package account

import (
	"fmt"
	"html/template"
	"strings"
	tmpltext "text/template"
	"time"
)

// emailBrandColor is the single accent used in the confirmation email — a calm
// tile green, matching the "no riot of colours" brief.
const emailBrandColor = "#2f7d4f"

// confirmEmailView is the fully-localised data the confirmation email templates
// render. Every string is resolved before rendering, so the templates carry no
// localisation logic.
type confirmEmailView struct {
	Brand        string
	Heading      string
	Intro        string
	Code         string
	Expiry       string
	CTALabel     string
	DeeplinkURL  string
	FooterIgnore string
	LandingURL   string
	LandingLabel string
	Preheader    string
	Locale       string
	Accent       string
}

// emailCopy is the purpose- and locale-specific wording of a confirmation email.
type emailCopy struct {
	Subject      string
	Preheader    string
	Heading      string
	Intro        string
	CTALabel     string
	FooterIgnore string
}

// confirmEmailCopy holds the wording per (purpose, locale). Unknown purposes fall
// back to the neutral link wording and unknown locales fall back to English.
var confirmEmailCopy = map[string]map[string]emailCopy{
	purposeLogin: {
		"en": {
			Subject:      "Your Erudit sign-in code",
			Preheader:    "Your sign-in code",
			Heading:      "Sign in to Erudit",
			Intro:        "Enter this code to sign in:",
			CTALabel:     "Sign in with one tap",
			FooterIgnore: "If you didn't request this email, you can safely ignore it.",
		},
		"ru": {
			Subject:      "Код для входа в Эрудит",
			Preheader:    "Ваш код для входа",
			Heading:      "Вход в Эрудит",
			Intro:        "Введите этот код, чтобы войти в игру:",
			CTALabel:     "Войти одним нажатием",
			FooterIgnore: "Если вы не запрашивали это письмо, просто проигнорируйте его.",
		},
	},
	purposeLink: {
		"en": {
			Subject:      "Your Erudit confirmation code",
			Preheader:    "Your confirmation code",
			Heading:      "Confirm your e-mail",
			Intro:        "Enter this code to confirm your address:",
			CTALabel:     "Confirm with one tap",
			FooterIgnore: "If you didn't request this email, you can safely ignore it.",
		},
		"ru": {
			Subject:      "Код подтверждения Эрудит",
			Preheader:    "Ваш код подтверждения",
			Heading:      "Подтверждение e-mail",
			Intro:        "Введите этот код, чтобы подтвердить адрес:",
			CTALabel:     "Подтвердить одним нажатием",
			FooterIgnore: "Если вы не запрашивали это письмо, просто проигнорируйте его.",
		},
	},
	purposeChange: {
		"en": {
			Subject:      "Confirm your new Erudit e-mail",
			Preheader:    "Confirm your new address",
			Heading:      "Confirm your new e-mail",
			Intro:        "Enter this code to switch your account to this address:",
			CTALabel:     "Confirm with one tap",
			FooterIgnore: "If you didn't request this change, you can safely ignore it — your address stays the same.",
		},
		"ru": {
			Subject:      "Подтвердите новый e-mail в Эрудит",
			Preheader:    "Подтвердите новый адрес",
			Heading:      "Смена e-mail",
			Intro:        "Введите этот код, чтобы привязать аккаунт к новому адресу:",
			CTALabel:     "Подтвердить одним нажатием",
			FooterIgnore: "Если вы не запрашивали смену, просто проигнорируйте письмо — адрес останется прежним.",
		},
	},
	purposeDelete: {
		"en": {
			Subject:      "Confirm your Erudit account deletion",
			Preheader:    "Confirm account deletion",
			Heading:      "Delete your account",
			Intro:        "Enter this code in the app to permanently delete your account:",
			CTALabel:     "",
			FooterIgnore: "If you didn't request this, ignore it — your account stays as it is.",
		},
		"ru": {
			Subject:      "Подтвердите удаление аккаунта Эрудит",
			Preheader:    "Подтверждение удаления аккаунта",
			Heading:      "Удаление аккаунта",
			Intro:        "Введите этот код в приложении, чтобы удалить аккаунт без восстановления:",
			CTALabel:     "",
			FooterIgnore: "Если вы не запрашивали удаление, проигнорируйте письмо — аккаунт останется.",
		},
	},
}

// emailBrand is the brand wordmark per locale.
var emailBrand = map[string]string{"en": "Erudit", "ru": "Эрудит"}

// emailExpiry formats the code-lifetime line per locale (abbreviated minutes to
// avoid plural agreement).
func emailExpiry(locale string, d time.Duration) string {
	min := int(d / time.Minute)
	if locale == "ru" {
		return fmt.Sprintf("Код действует %d мин.", min)
	}
	return fmt.Sprintf("The code is valid for %d minutes.", min)
}

// normalizeLocale maps an account language to a supported email locale, defaulting
// to English.
func normalizeLocale(locale string) string {
	if locale == "ru" {
		return "ru"
	}
	return "en"
}

// renderConfirmationEmail builds the branded confirmation email for purpose in
// locale: a large readable code plus a one-tap deeplink button, with an
// ignore-notice footer and a landing link. Both a plain-text body and an HTML
// alternative are produced. deeplinkURL is the absolute /confirm link and
// landingURL the public landing origin.
func renderConfirmationEmail(purpose, code, deeplinkURL, landingURL, locale string) (Message, error) {
	loc := normalizeLocale(locale)
	byLocale, ok := confirmEmailCopy[purpose]
	if !ok {
		byLocale = confirmEmailCopy[purposeLink]
	}
	cp := byLocale[loc]
	view := confirmEmailView{
		Brand:        emailBrand[loc],
		Heading:      cp.Heading,
		Intro:        cp.Intro,
		Code:         code,
		Expiry:       emailExpiry(loc, emailCodeTTL),
		CTALabel:     cp.CTALabel,
		DeeplinkURL:  deeplinkURL,
		FooterIgnore: cp.FooterIgnore,
		LandingURL:   landingURL,
		LandingLabel: emailBrand[loc],
		Preheader:    cp.Preheader,
		Locale:       loc,
		Accent:       emailBrandColor,
	}
	var html strings.Builder
	if err := confirmEmailHTML.Execute(&html, view); err != nil {
		return Message{}, fmt.Errorf("account: render confirmation email (html): %w", err)
	}
	var text strings.Builder
	if err := confirmEmailText.Execute(&text, view); err != nil {
		return Message{}, fmt.Errorf("account: render confirmation email (text): %w", err)
	}
	return Message{Subject: cp.Subject, Text: text.String(), HTML: html.String()}, nil
}

// confirmEmailHTML is a compact, image-free, mobile-friendly HTML email. Layout is
// table-based for broad mail-client compatibility and all styling is inlined
// because clients strip <style> blocks.
var confirmEmailHTML = template.Must(template.New("confirmEmailHTML").Parse(`<!DOCTYPE html>
<html lang="{{.Locale}}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{.Brand}}</title>
</head>
<body style="margin:0;padding:0;background:#f4f5f7;">
<span style="display:none;max-height:0;overflow:hidden;opacity:0;">{{.Preheader}}</span>
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background:#f4f5f7;padding:24px 12px;">
<tr><td align="center">
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="max-width:460px;background:#ffffff;border:1px solid #e5e7eb;border-radius:14px;overflow:hidden;font-family:-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;">
<tr><td style="padding:28px 32px 4px;">
<div style="font-size:15px;font-weight:700;letter-spacing:.04em;color:{{.Accent}};">{{.Brand}}</div>
</td></tr>
<tr><td style="padding:8px 32px 0;">
<h1 style="margin:0;font-size:20px;line-height:1.3;color:#111827;font-weight:600;">{{.Heading}}</h1>
<p style="margin:12px 0 0;font-size:15px;line-height:1.5;color:#374151;">{{.Intro}}</p>
</td></tr>
<tr><td style="padding:18px 32px 0;">
<div style="font-size:34px;font-weight:700;letter-spacing:8px;text-align:center;color:#111827;background:#f3f4f6;border-radius:10px;padding:18px 0;font-family:'SFMono-Regular',Consolas,Menlo,monospace;">{{.Code}}</div>
<p style="margin:10px 0 0;font-size:13px;line-height:1.5;color:#6b7280;text-align:center;">{{.Expiry}}</p>
</td></tr>
{{if .DeeplinkURL}}<tr><td style="padding:22px 32px 0;" align="center">
<a href="{{.DeeplinkURL}}" style="display:inline-block;background:{{.Accent}};color:#ffffff;text-decoration:none;font-size:15px;font-weight:600;padding:12px 26px;border-radius:9px;">{{.CTALabel}}</a>
</td></tr>
{{end}}<tr><td style="padding:26px 32px 28px;">
<hr style="border:none;border-top:1px solid #eceef1;margin:0 0 16px;">
<p style="margin:0;font-size:12px;line-height:1.6;color:#9ca3af;">{{.FooterIgnore}}</p>
<p style="margin:10px 0 0;font-size:12px;color:#9ca3af;"><a href="{{.LandingURL}}" style="color:#6b7280;text-decoration:none;">{{.LandingLabel}}</a></p>
</td></tr>
</table>
</td></tr>
</table>
</body>
</html>
`))

// confirmEmailText is the plain-text alternative (and multipart fallback).
var confirmEmailText = tmpltext.Must(tmpltext.New("confirmEmailText").Parse(`{{.Brand}}

{{.Heading}}

{{.Intro}}

    {{.Code}}

{{.Expiry}}

{{if .DeeplinkURL}}{{.CTALabel}}:
{{.DeeplinkURL}}

{{end}}—
{{.FooterIgnore}}
{{.LandingLabel}} — {{.LandingURL}}
`))
