package storage

import (
	"strconv"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"

	"mengyastore-backend/internal/database"
)

type SiteStore struct {
	db *gorm.DB
}

func NewSiteStore(db *gorm.DB) (*SiteStore, error) {
	return &SiteStore{db: db}, nil
}

func (s *SiteStore) get(key string) (string, error) {
	var row database.SiteSettingRow
	// `key` 是 MySQL 保留字，需用反引号转义以避免 SQL 语法错误。
	// 使用 Find+Limit 而非 First：缺键时不产生 ErrRecordNotFound，避免 GORM 默认 logger 刷「record not found」。
	if err := s.db.Where("`key` = ?", key).Limit(1).Find(&row).Error; err != nil {
		return "", err
	}
	if row.Key == "" {
		return "", nil
	}
	return row.Value, nil
}

func (s *SiteStore) set(key, value string) error {
	return s.db.Clauses(clause.OnConflict{
		Columns:   []clause.Column{{Name: "key"}},
		DoUpdates: clause.AssignmentColumns([]string{"value"}),
	}).Create(&database.SiteSettingRow{Key: key, Value: value}).Error
}

func (s *SiteStore) GetTotalVisits() (int, error) {
	v, err := s.get("totalVisits")
	if err != nil || v == "" {
		return 0, err
	}
	n, _ := strconv.Atoi(v)
	return n, nil
}

func (s *SiteStore) IncrementVisits() (int, error) {
	current, err := s.GetTotalVisits()
	if err != nil {
		return 0, err
	}
	current++
	if err := s.set("totalVisits", strconv.Itoa(current)); err != nil {
		return 0, err
	}
	return current, nil
}

func (s *SiteStore) GetMaintenance() (enabled bool, reason string, err error) {
	v, err := s.get("maintenance")
	if err != nil {
		return false, "", err
	}
	enabled = v == "true"
	reason, err = s.get("maintenanceReason")
	return enabled, reason, err
}

func (s *SiteStore) SetMaintenance(enabled bool, reason string) error {
	v := "false"
	if enabled {
		v = "true"
	}
	if err := s.set("maintenance", v); err != nil {
		return err
	}
	return s.set("maintenanceReason", reason)
}

// RecordVisit 递增访问计数，返回 (总访问量, 是否计入, 错误)。
// 去重逻辑由上层 handler 的内存指纹完成，此处无条件累加。
func (s *SiteStore) RecordVisit(_ string) (int, bool, error) {
	total, err := s.IncrementVisits()
	return total, true, err
}

// SMTPConfig 存储数据库中的发件 SMTP 配置。
type SMTPConfig struct {
	Enabled  bool   `json:"enabled"`
	Email    string `json:"email"`
	Password string `json:"password"`
	FromName string `json:"fromName"`
	Host     string `json:"host"`
	Port     string `json:"port"`
}

// IsConfiguredEmail 判断邮件通知是否已启用且 SMTP 配置完整。
func (c SMTPConfig) IsConfiguredEmail() bool {
	return c.Enabled && c.Email != "" && c.Password != "" && c.Host != ""
}

func (s *SiteStore) GetSMTPConfig() (SMTPConfig, error) {
	cfg := SMTPConfig{
		Enabled: true, // 默认启用
		Host:    "smtp.qq.com",
		Port:    "465",
	}
	if v, _ := s.get("smtpEnabled"); v == "false" {
		cfg.Enabled = false
	}
	if v, _ := s.get("smtpEmail"); v != "" {
		cfg.Email = v
	}
	if v, _ := s.get("smtpPassword"); v != "" {
		cfg.Password = v
	}
	if v, _ := s.get("smtpFromName"); v != "" {
		cfg.FromName = v
	}
	if v, _ := s.get("smtpHost"); v != "" {
		cfg.Host = v
	}
	if v, _ := s.get("smtpPort"); v != "" {
		cfg.Port = v
	}
	return cfg, nil
}

func (s *SiteStore) SetSMTPConfig(cfg SMTPConfig) error {
	enabledVal := "true"
	if !cfg.Enabled {
		enabledVal = "false"
	}
	pairs := [][2]string{
		{"smtpEnabled", enabledVal},
		{"smtpEmail", cfg.Email},
		{"smtpPassword", cfg.Password},
		{"smtpFromName", cfg.FromName},
		{"smtpHost", cfg.Host},
		{"smtpPort", cfg.Port},
	}
	for _, p := range pairs {
		if err := s.set(p[0], p[1]); err != nil {
			return err
		}
	}
	return nil
}
