package services

import (
	"context"

	"github.com/nexuscrm/kernel/pkg/ports"
	"github.com/nexuscrm/shared/pkg/contract"
)

type notificationContract struct {
	sender      ports.EmailSender
	frontendURL string
}

func NewNotificationContract(sender ports.EmailSender, frontendURL string) contract.Notifications {
	return &notificationContract{sender: sender, frontendURL: frontendURL}
}

func (c *notificationContract) SendEmail(ctx context.Context, msg *contract.OutboundEmailMessage) (*contract.OutboundEmailResult, error) {
	if c == nil || c.sender == nil {
		return &contract.OutboundEmailResult{}, nil
	}
	result, err := c.sender.Send(ctx, outboundEmailMessageToPort(msg))
	if err != nil {
		return nil, err
	}
	return outboundEmailResultFromPort(result), nil
}

func (c *notificationContract) FrontendBaseURL(context.Context) string {
	if c == nil {
		return ""
	}
	return c.frontendURL
}

func outboundEmailMessageToPort(msg *contract.OutboundEmailMessage) *ports.EmailMessage {
	if msg == nil {
		return nil
	}
	return &ports.EmailMessage{
		To:      append([]string(nil), msg.To...),
		Cc:      append([]string(nil), msg.Cc...),
		Bcc:     append([]string(nil), msg.Bcc...),
		From:    msg.From,
		Subject: msg.Subject,
		Body:    msg.Body,
		HTML:    msg.HTML,
	}
}

func outboundEmailResultFromPort(result *ports.EmailSendResult) *contract.OutboundEmailResult {
	if result == nil {
		return nil
	}
	out := &contract.OutboundEmailResult{
		SentCount:        result.SentCount,
		MessageID:        result.MessageID,
		RecipientResults: make([]contract.OutboundEmailRecipientResult, 0, len(result.RecipientResults)),
	}
	for _, recipient := range result.RecipientResults {
		out.RecipientResults = append(out.RecipientResults, contract.OutboundEmailRecipientResult{
			Address: recipient.Address,
			Role:    recipient.Role,
			Status:  recipient.Status,
			Error:   recipient.Error,
		})
	}
	return out
}
