package handler

import (
	"errors"
	"kra/internal/biz/system"
	"kra/internal/service/dto"
	systemservice "kra/internal/service/system"
	"log/slog"

	"github.com/gin-gonic/gin"
)

type SystemConfig struct {
	system   *systemservice.SystemConfigService
	settings *systemservice.SecurityService
}

func NewSystemConfig(system *systemservice.SystemConfigService, settings *systemservice.SecurityService) *SystemConfig {
	return &SystemConfig{system: system, settings: settings}
}

func (h *SystemConfig) GetSecurity(c *gin.Context) {
	value, err := h.settings.Security(c.Request.Context())
	if err != nil {
		Fail(c, "获取安全配置失败")
		return
	}
	Write(c, CodeSuccess, value, "获取成功")
}

func (h *SystemConfig) SetSecurity(c *gin.Context) {
	var req dto.SecurityConfigRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	result, err := h.settings.SaveSecurityRequest(c.Request.Context(), &req)
	if err != nil {
		Fail(c, "设置安全配置失败")
		return
	}
	Write(c, CodeSuccess, result, "设置成功")
}

func (h *SystemConfig) Get(c *gin.Context) {
	value, err := h.system.SystemConfig()
	if err != nil {
		Fail(c, "获取失败")
		return
	}
	Write(c, CodeSuccess, value, "获取成功")
}

func (h *SystemConfig) Set(c *gin.Context) {
	var req dto.SetSystemConfigRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if err := h.system.SaveSystemConfig(c.Request.Context(), &req); err != nil {
		Fail(c, "设置失败")
		return
	}
	Write(c, CodeSuccess, gin.H{}, "设置成功")
}

func (h *SystemConfig) Reload(c *gin.Context) {
	if err := h.system.ReloadConfig(c.Request.Context()); err != nil {
		// Reloading the data/configuration is committed before task schedules are
		// rebuilt. Match GVA's successful HTTP contract for this partial-success
		// case while leaving the typed error available to internal callers.
		if errors.Is(err, system.ErrTaskRuntimeReload) {
			slog.ErrorContext(c.Request.Context(), "系统配置重载完成，但定时任务恢复失败", "mod", "timedTask", "error", err)
			Write(c, CodeSuccess, gin.H{}, "重载系统成功")
			return
		}
		Fail(c, "重载系统失败:"+err.Error())
		return
	}
	Write(c, CodeSuccess, gin.H{}, "重载系统成功")
}

func (h *SystemConfig) ServerInfo(c *gin.Context) {
	server, err := h.system.ServerInfo(c.Request.Context())
	if err != nil {
		Fail(c, "获取失败")
		return
	}
	Write(c, CodeSuccess, gin.H{"server": server}, "获取成功")
}
