package relay

import (
	"mailgoserver/internal/db"
	"mailgoserver/internal/toolbox"

	"gopkg.in/ini.v1"
)

// LogEmail mirrors EmailRelay.log_email: computes the overall status from per-recipient
// results (relayed/partial/failed) and persists the EmailLog + EmailRecipientLog rows.
func (r *Relay) LogEmail(cfg *ini.File, peerIP, mailFrom, toAddress, ccAddresses, bccAddresses, subject, emailHeaders, messageBody, messageID, username string, dkimSigned bool, results []Result) (int64, error) {
	overall := overallStatus(results)

	logID, err := r.DB.InsertEmailLog(db.EmailLog{
		MessageID:    messageID,
		Timestamp:    toolbox.GetCurrentTime(cfg),
		PeerIP:       peerIP,
		MailFrom:     mailFrom,
		ToAddress:    toAddress,
		CcAddresses:  ccAddresses,
		BccAddresses: bccAddresses,
		Subject:      subject,
		EmailHeaders: emailHeaders,
		MessageBody:  messageBody,
		Status:       overall,
		DKIMSigned:   dkimSigned,
		Username:     username,
	})
	if err != nil {
		return 0, err
	}

	for _, res := range results {
		recipientType := res.RecipientType
		if recipientType == "" {
			recipientType = "to"
		}
		if err := r.DB.InsertEmailRecipientLog(db.EmailRecipientLog{
			EmailLogID:     logID,
			Recipient:      res.Recipient,
			RecipientType:  recipientType,
			Status:         res.Status,
			ErrorCode:      res.ErrorCode,
			ErrorMessage:   res.ErrorMessage,
			ServerResponse: res.ServerResponse,
		}); err != nil {
			r.Logger.Error("Failed to log recipient %s: %v", res.Recipient, err)
		}
	}

	return logID, nil
}

func overallStatus(results []Result) string {
	if len(results) == 0 {
		return "failed"
	}
	success, failed := 0, 0
	for _, res := range results {
		if res.Status == "success" {
			success++
		} else {
			failed++
		}
	}
	switch {
	case success > 0 && failed > 0:
		return "partial"
	case success > 0:
		return "relayed"
	default:
		return "failed"
	}
}
