package mail

import (
	"strings"

	"github.com/ultisuite/ulti-backend/internal/api/apivalidate"
)

const maxSettingsRequestBody = 4 << 10 // 4 KiB

var (
	allowedDensities = map[string]struct{}{
		"default": {},
		"normal":  {},
		"compact": {},
	}
	allowedThemeModes = map[string]struct{}{
		"light":  {},
		"dark":   {},
		"system": {},
	}
	allowedBackgroundIDs = map[string]struct{}{
		"none":              {},
		"gradient-aurora":   {},
		"gradient-sunset":   {},
		"gradient-ocean":    {},
		"gradient-blossom":  {},
		"photo-mountains":   {},
		"photo-ocean":       {},
		"photo-city":        {},
		"photo-nature":      {},
	}
	allowedInboxSorts = map[string]struct{}{
		"default":   {},
		"important": {},
		"unread":    {},
		"starred":   {},
	}
	allowedReadingPanes = map[string]struct{}{
		"none":  {},
		"right": {},
		"below": {},
	}
)

type MailNotificationSettings struct {
	DesktopNewMail  bool `json:"desktop_new_mail"`
	DesktopMentions bool `json:"desktop_mentions"`
	EmailDigest     bool `json:"email_digest"`
	SoundEnabled    bool `json:"sound_enabled"`
}

type MailSettings struct {
	Density          string                   `json:"density"`
	ThemeMode        string                   `json:"theme_mode"`
	BackgroundID     string                   `json:"background_id"`
	InboxSort        string                   `json:"inbox_sort"`
	ReadingPane      string                   `json:"reading_pane"`
	ConversationMode bool                     `json:"conversation_mode"`
	Notifications    MailNotificationSettings `json:"notifications"`
	UpdatedAt        any                      `json:"updated_at,omitempty"`
}

type patchMailNotificationSettings struct {
	DesktopNewMail  *bool `json:"desktop_new_mail"`
	DesktopMentions *bool `json:"desktop_mentions"`
	EmailDigest     *bool `json:"email_digest"`
	SoundEnabled    *bool `json:"sound_enabled"`
}

type patchMailSettingsRequest struct {
	Density          *string                        `json:"density"`
	ThemeMode        *string                        `json:"theme_mode"`
	BackgroundID     *string                        `json:"background_id"`
	InboxSort        *string                        `json:"inbox_sort"`
	ReadingPane      *string                        `json:"reading_pane"`
	ConversationMode *bool                          `json:"conversation_mode"`
	Notifications    *patchMailNotificationSettings `json:"notifications"`
}

func defaultMailNotificationSettings() MailNotificationSettings {
	return MailNotificationSettings{
		DesktopNewMail:  true,
		DesktopMentions: true,
		EmailDigest:     false,
		SoundEnabled:    false,
	}
}

func defaultMailSettings() MailSettings {
	return MailSettings{
		Density:          "default",
		ThemeMode:        "system",
		BackgroundID:     "none",
		InboxSort:        "default",
		ReadingPane:      "none",
		ConversationMode: true,
		Notifications:    defaultMailNotificationSettings(),
	}
}

func validateEnum(field, value string, allowed map[string]struct{}) *apivalidate.FieldDetail {
	value = strings.TrimSpace(strings.ToLower(value))
	if value == "" {
		return &apivalidate.FieldDetail{Field: field, Message: "required"}
	}
	if _, ok := allowed[value]; !ok {
		return &apivalidate.FieldDetail{Field: field, Message: "invalid"}
	}
	return nil
}

func validatePatchMailSettings(req *patchMailSettingsRequest) *apivalidate.ValidationError {
	if req == nil {
		return apivalidate.NewValidationError(apivalidate.FieldDetail{Field: "body", Message: "required"})
	}

	hasField := req.Density != nil ||
		req.ThemeMode != nil ||
		req.BackgroundID != nil ||
		req.InboxSort != nil ||
		req.ReadingPane != nil ||
		req.ConversationMode != nil ||
		req.Notifications != nil
	if !hasField {
		return apivalidate.NewValidationError(apivalidate.FieldDetail{Field: "body", Message: "at least one field required"})
	}

	var details []apivalidate.FieldDetail
	if req.Density != nil {
		if d := validateEnum("density", *req.Density, allowedDensities); d != nil {
			details = append(details, *d)
		}
	}
	if req.ThemeMode != nil {
		if d := validateEnum("theme_mode", *req.ThemeMode, allowedThemeModes); d != nil {
			details = append(details, *d)
		}
	}
	if req.BackgroundID != nil {
		if d := validateEnum("background_id", *req.BackgroundID, allowedBackgroundIDs); d != nil {
			details = append(details, *d)
		}
	}
	if req.InboxSort != nil {
		if d := validateEnum("inbox_sort", *req.InboxSort, allowedInboxSorts); d != nil {
			details = append(details, *d)
		}
	}
	if req.ReadingPane != nil {
		if d := validateEnum("reading_pane", *req.ReadingPane, allowedReadingPanes); d != nil {
			details = append(details, *d)
		}
	}
	if len(details) == 0 {
		return nil
	}
	return apivalidate.NewValidationError(details...)
}
