package email

import (
	"context"
	"fmt"
	"log/slog"
	"net/smtp"

	"github.com/tim/cairnquire/apps/server/internal/config"
)

type Sender interface {
	Send(ctx context.Context, to []string, subject, body string) error
}

type SMTPConfig struct {
	Host string
	Port int
	From string
}

type SMTPSender struct {
	cfg    SMTPConfig
	logger *slog.Logger
}

func NewSMTPSender(cfg config.EmailConfig, logger *slog.Logger) *SMTPSender {
	return &SMTPSender{
		cfg: SMTPConfig{
			Host: cfg.SMTPHost,
			Port: cfg.SMTPPort,
			From: cfg.From,
		},
		logger: logger,
	}
}

func (s *SMTPSender) Send(ctx context.Context, to []string, subject, body string) error {
	if s.cfg.Host == "" {
		return fmt.Errorf("email host not configured")
	}
	addr := fmt.Sprintf("%s:%d", s.cfg.Host, s.cfg.Port)
	msg := []byte(fmt.Sprintf("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s\r\n", s.cfg.From, to[0], subject, body))

	s.logger.Info("sending email", "to", to, "subject", subject, "addr", addr)

	// Use SMTP without auth for local testing (Mailpit/MailHog)
	var auth smtp.Auth
	err := smtp.SendMail(addr, auth, s.cfg.From, to, msg)
	if err != nil {
		return fmt.Errorf("send email: %w", err)
	}
	return nil
}

type NoOpSender struct {
	logger *slog.Logger
}

func NewNoOpSender(logger *slog.Logger) *NoOpSender {
	return &NoOpSender{logger: logger}
}

func (n *NoOpSender) Send(ctx context.Context, to []string, subject, body string) error {
	n.logger.Info("email noop", "to", to, "subject", subject, "body_len", len(body))
	return nil
}
