package infra

import (
	"crypto/tls"
	"fmt"
	"net"
	"net/smtp"
	"strconv"
)

// SMTPConnect establishes an authenticated SMTP connection using the given config.
// TLSMode controls encryption:
//   - "tls"      → direct TLS (typical port 465)
//   - "starttls" → plain connection upgraded with STARTTLS (typical port 587)
//   - ""         → no encryption (typical port 25)
//
// Returns an *smtp.Client ready to use with SMTPSend.
// The caller is responsible for calling client.Quit() when done.
func SMTPConnect(cfg SMTPConfig) (*smtp.Client, error) {
	addr := net.JoinHostPort(cfg.Host, strconv.Itoa(cfg.Port))

	switch cfg.TLSMode {
	case "tls":
		tlsCfg := &tls.Config{ServerName: cfg.Host}
		conn, err := tls.Dial("tcp", addr, tlsCfg)
		if err != nil {
			return nil, fmt.Errorf("smtp_connect: tls dial %s: %w", addr, err)
		}
		client, err := smtp.NewClient(conn, cfg.Host)
		if err != nil {
			conn.Close()
			return nil, fmt.Errorf("smtp_connect: new client: %w", err)
		}
		if cfg.Username != "" {
			auth := smtp.PlainAuth("", cfg.Username, cfg.Password, cfg.Host)
			if err := client.Auth(auth); err != nil {
				client.Close()
				return nil, fmt.Errorf("smtp_connect: auth: %w", err)
			}
		}
		return client, nil

	case "starttls":
		conn, err := net.Dial("tcp", addr)
		if err != nil {
			return nil, fmt.Errorf("smtp_connect: dial %s: %w", addr, err)
		}
		client, err := smtp.NewClient(conn, cfg.Host)
		if err != nil {
			conn.Close()
			return nil, fmt.Errorf("smtp_connect: new client: %w", err)
		}
		tlsCfg := &tls.Config{ServerName: cfg.Host}
		if err := client.StartTLS(tlsCfg); err != nil {
			client.Close()
			return nil, fmt.Errorf("smtp_connect: starttls: %w", err)
		}
		if cfg.Username != "" {
			auth := smtp.PlainAuth("", cfg.Username, cfg.Password, cfg.Host)
			if err := client.Auth(auth); err != nil {
				client.Close()
				return nil, fmt.Errorf("smtp_connect: auth: %w", err)
			}
		}
		return client, nil

	default:
		// no encryption
		client, err := smtp.Dial(addr)
		if err != nil {
			return nil, fmt.Errorf("smtp_connect: dial %s: %w", addr, err)
		}
		if cfg.Username != "" {
			auth := smtp.PlainAuth("", cfg.Username, cfg.Password, cfg.Host)
			if err := client.Auth(auth); err != nil {
				client.Close()
				return nil, fmt.Errorf("smtp_connect: auth: %w", err)
			}
		}
		return client, nil
	}
}
