package storage

import (
	"encoding/json"
	"fmt"
	"log"
	"time"

	"mengyaping-backend/config"
)

const (
	kvKeyServer   = "cfg_server"
	kvKeyMonitor  = "cfg_monitor"
	kvKeyDataPath = "cfg_data_path"
	kvKeyDatabase = "cfg_database"
)

type monitorKVPayload struct {
	IntervalMinutes int `json:"interval_minutes"`
	TimeoutSeconds  int `json:"timeout_seconds"`
	RetryCount      int `json:"retry_count"`
	HistoryDays     int `json:"history_days"`
}

func (s *Storage) getKVRaw(key string) string {
	var row MonitorKV
	s.db.Where("cfg_key = ?", key).Limit(1).Find(&row)
	if row.CfgKey == "" {
		return ""
	}
	return row.CfgValue
}

func (s *Storage) setKVRaw(key, val string) error {
	var row MonitorKV
	s.db.Where("cfg_key = ?", key).Limit(1).Find(&row)
	if row.CfgKey == "" {
		return s.db.Create(&MonitorKV{CfgKey: key, CfgValue: val}).Error
	}
	row.CfgValue = val
	return s.db.Save(&row).Error
}

// loadAndSyncAppConfig 从 monitor_kv 覆盖内存配置，再写回全量（补全缺省键、统一格式）
func (s *Storage) loadAndSyncAppConfig() {
	cfg := config.GetConfig()

	if v := s.getKVRaw(kvKeyServer); v != "" {
		var sc config.ServerConfig
		if err := json.Unmarshal([]byte(v), &sc); err != nil {
			log.Printf("解析 %s: %v", kvKeyServer, err)
		} else {
			if sc.Port != "" {
				cfg.Server.Port = sc.Port
			}
			if sc.Host != "" {
				cfg.Server.Host = sc.Host
			}
		}
	}

	if v := s.getKVRaw(kvKeyMonitor); v != "" {
		var m monitorKVPayload
		if err := json.Unmarshal([]byte(v), &m); err != nil {
			log.Printf("解析 %s: %v", kvKeyMonitor, err)
		} else {
			if m.IntervalMinutes > 0 {
				snapped := config.SnapMonitorIntervalMinutes(m.IntervalMinutes)
				cfg.Monitor.Interval = time.Duration(snapped) * time.Minute
			}
			if m.TimeoutSeconds > 0 {
				cfg.Monitor.Timeout = time.Duration(m.TimeoutSeconds) * time.Second
			}
			if m.RetryCount > 0 {
				cfg.Monitor.RetryCount = m.RetryCount
			}
			if m.HistoryDays > 0 {
				cfg.Monitor.HistoryDays = m.HistoryDays
			}
		}
	}

	if v := s.getKVRaw(kvKeyDataPath); v != "" {
		cfg.DataPath = v
	}

	if v := s.getKVRaw(kvKeyDatabase); v != "" {
		var dc config.DatabaseConfig
		if err := json.Unmarshal([]byte(v), &dc); err != nil {
			log.Printf("解析 %s: %v", kvKeyDatabase, err)
		} else {
			if dc.Host != "" {
				cfg.Database.Host = dc.Host
			}
			if dc.Port != "" {
				cfg.Database.Port = dc.Port
			}
			if dc.User != "" {
				cfg.Database.User = dc.User
			}
			if dc.Password != "" {
				cfg.Database.Password = dc.Password
			}
			if dc.Database != "" {
				cfg.Database.Database = dc.Database
			}
		}
	}

	if err := s.PersistAppConfig(); err != nil {
		log.Printf("同步应用配置到 monitor_kv: %v", err)
	}
}

// PersistAppConfig 将当前内存中的 server/monitor/data_path/database 写入 monitor_kv
func (s *Storage) PersistAppConfig() error {
	cfg := config.GetConfig()

	b, err := json.Marshal(cfg.Server)
	if err != nil {
		return err
	}
	if err := s.setKVRaw(kvKeyServer, string(b)); err != nil {
		return err
	}

	m := monitorKVPayload{
		IntervalMinutes: config.SnapMonitorIntervalMinutes(int(cfg.Monitor.Interval / time.Minute)),
		TimeoutSeconds:  int(cfg.Monitor.Timeout.Seconds()),
		RetryCount:      cfg.Monitor.RetryCount,
		HistoryDays:     cfg.Monitor.HistoryDays,
	}
	b, err = json.Marshal(m)
	if err != nil {
		return err
	}
	if err := s.setKVRaw(kvKeyMonitor, string(b)); err != nil {
		return err
	}

	if err := s.setKVRaw(kvKeyDataPath, cfg.DataPath); err != nil {
		return err
	}

	b, err = json.Marshal(cfg.Database)
	if err != nil {
		return err
	}
	return s.setKVRaw(kvKeyDatabase, string(b))
}

// SetMonitorIntervalMinutes 更新检测周期并写入 monitor_kv
func (s *Storage) SetMonitorIntervalMinutes(minutes int) error {
	if !config.IsAllowedMonitorInterval(minutes) {
		return fmt.Errorf("interval_minutes 必须是预设值之一: %v", config.AllowedMonitorIntervalMinutes)
	}
	cfg := config.GetConfig()
	cfg.Monitor.Interval = time.Duration(minutes) * time.Minute
	return s.PersistAppConfig()
}
