package email_sender

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

type sender struct {
	smtpHost     string
	smtpPort     string
	smtpUser     string
	smtpPassword string
}

func NewSender(
	smtpHost string,
	smtpPort string,
	smtpUser string,
	smtpPassword string,
) IEmailSender {
	return &sender{
		smtpHost:     smtpHost,
		smtpPort:     smtpPort,
		smtpUser:     smtpUser,
		smtpPassword: smtpPassword,
	}
}

func (s *sender) Send(_ context.Context, message Message) error {
	emailMessage := []byte(fmt.Sprintf(
		"To: %s\r\n"+
			"Subject: %s\r\n"+
			"MIME-Version: 1.0\r\n"+
			"Content-Type: text/plain; charset=utf-8\r\n"+
			"\r\n"+
			"%s\r\n",
		message.To,
		message.Subject,
		message.Body,
	))

	// Настраиваем TLS
	tlsConfig := &tls.Config{
		ServerName: s.smtpHost,
	}

	// Подключаемся к серверу
	conn, err := tls.Dial("tcp", s.smtpHost+":"+s.smtpPort, tlsConfig)
	if err != nil {
		return err
	}
	defer conn.Close()

	// Создаем SMTP клиент
	client, err := smtp.NewClient(conn, s.smtpHost)
	if err != nil {
		return err
	}
	defer client.Quit()

	// Аутентификация
	auth := smtp.PlainAuth("", s.smtpUser, s.smtpPassword, s.smtpHost)
	if err = client.Auth(auth); err != nil {
		return err
	}

	// Указываем отправителя
	if err = client.Mail(s.smtpUser); err != nil {
		return err
	}

	// Указываем получателя
	if err = client.Rcpt(message.To); err != nil {
		return err
	}

	// Отправляем данные письма
	w, err := client.Data()
	if err != nil {
		return err
	}
	_, err = w.Write(emailMessage)
	if err != nil {
		return err
	}
	err = w.Close()
	if err != nil {
		return err
	}

	return nil
}
