package emailService

import (
	"bytes"
	"context"
	"fmt"
	"net/smtp"
	"strings"

	"git.ma-al.com/goc_daniel/b2b/app/config"
	"git.ma-al.com/goc_daniel/b2b/app/service/langsService"
	"git.ma-al.com/goc_daniel/b2b/app/templ/emails"
	"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
	"git.ma-al.com/goc_daniel/b2b/app/view"
)

// EmailService handles sending emails
type EmailService struct {
	config *config.EmailConfig
}

// NewEmailService creates a new EmailService instance
func NewEmailService() *EmailService {
	return &EmailService{
		config: &config.Get().Email,
	}
}

// getLangID returns the language ID from the ISO code using the language service
func getLangID(isoCode string) uint {
	if isoCode == "" {
		isoCode = "en"
	}

	lang, err := langsService.LangSrv.GetLanguageByISOCode(isoCode)
	if err != nil || lang == nil {
		return 1 // Default to English (ID 1)
	}

	return uint(lang.ID)
}

// SendEmail sends an email to the specified recipient
func (s *EmailService) SendEmail(to, subject, body string) error {
	if !s.config.Enabled {
		return fmt.Errorf("email service is disabled")
	}

	// Set up authentication
	auth := smtp.PlainAuth("", s.config.SMTPUser, s.config.SMTPPassword, s.config.SMTPHost)

	// Create email headers
	headers := make(map[string]string)
	headers["From"] = fmt.Sprintf("%s <%s>", s.config.FromName, s.config.FromEmail)
	headers["To"] = to
	headers["Subject"] = subject
	headers["MIME-Version"] = "1.0"
	headers["Content-Type"] = "text/html; charset=utf-8"

	// Build email message
	var msg strings.Builder
	for k, v := range headers {
		msg.WriteString(fmt.Sprintf("%s: %s\r\n", k, v))
	}
	msg.WriteString("\r\n")
	msg.WriteString(body)

	// Send email
	addr := fmt.Sprintf("%s:%d", s.config.SMTPHost, s.config.SMTPPort)
	if err := smtp.SendMail(addr, auth, s.config.FromEmail, []string{to}, []byte(msg.String())); err != nil {
		return fmt.Errorf("failed to send email: %w", err)
	}

	return nil
}

// SendVerificationEmail sends an email verification email
func (s *EmailService) SendVerificationEmail(to, token, baseURL, lang string) error {
	// Use default language if not provided
	if lang == "" {
		lang = "en"
	}
	verificationURL := fmt.Sprintf("%s/%s/verify-email?token=%s", baseURL, lang, token)

	langID := getLangID(lang)
	subject := i18n.T___(langID, "email.email_verification_subject")
	body := s.verificationEmailTemplate(to, verificationURL, langID)

	return s.SendEmail(to, subject, body)
}

// SendPasswordResetEmail sends a password reset email
func (s *EmailService) SendPasswordResetEmail(to, token, baseURL, lang string) error {
	// Use default language if not provided
	if lang == "" {
		lang = "en"
	}
	resetURL := fmt.Sprintf("%s/%s/reset-password?token=%s", baseURL, lang, token)

	langID := getLangID(lang)
	subject := i18n.T___(langID, "email.email_password_reset_subject")
	body := s.passwordResetEmailTemplate(to, resetURL, langID)

	return s.SendEmail(to, subject, body)
}

// SendNewUserAdminNotification sends an email to admin when a new user completes registration
func (s *EmailService) SendNewUserAdminNotification(userEmail, userName, baseURL string) error {
	if s.config.AdminEmail == "" {
		return nil // No admin email configured
	}

	subject := "New User Registration - Repository Assignment Required"
	body := s.newUserAdminNotificationTemplate(userEmail, userName, baseURL)

	return s.SendEmail(s.config.AdminEmail, subject, body)
}

// verificationEmailTemplate returns the HTML template for email verification
func (s *EmailService) verificationEmailTemplate(name, verificationURL string, langID uint) string {
	buf := bytes.Buffer{}
	emails.EmailVerificationWrapper(view.EmailLayout[view.EmailVerificationData]{LangID: langID, Data: view.EmailVerificationData{VerificationURL: verificationURL}}).Render(context.Background(), &buf)
	return buf.String()
}

// passwordResetEmailTemplate returns the HTML template for password reset
func (s *EmailService) passwordResetEmailTemplate(name, resetURL string, langID uint) string {
	buf := bytes.Buffer{}
	emails.EmailPasswordResetWrapper(view.EmailLayout[view.EmailPasswordResetData]{LangID: langID, Data: view.EmailPasswordResetData{ResetURL: resetURL}}).Render(context.Background(), &buf)
	return buf.String()
}

// newUserAdminNotificationTemplate returns the HTML template for admin notification
func (s *EmailService) newUserAdminNotificationTemplate(userEmail, userName, baseURL string) string {
	buf := bytes.Buffer{}
	emails.EmailAdminNotificationWrapper(view.EmailLayout[view.EmailAdminNotificationData]{LangID: 2, Data: view.EmailAdminNotificationData{UserEmail: userEmail, UserName: userName, BaseURL: baseURL}}).Render(context.Background(), &buf)
	return buf.String()
}
