// cmd/dashboard/controller/domain.go
package controller

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

	"github.com/gin-gonic/gin"
	"github.com/nezhahq/nezha/model"
	"github.com/nezhahq/nezha/service/singleton"
)

// DomainAPIResponse 是用于API返回的结构体，可以包含一些后端计算好的字段
type DomainAPIResponse struct {
	model.Domain
	ExpiresInDays *int `json:"expires_in_days"` // 剩余天数，使用指针以区分0和null
}

// UpdateDomain 更新域名
func UpdateDomain(c *gin.Context) (any, error) {
	domainID, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		return nil, newGormError("无效的域名ID")
	}
	var req model.DomainUpdateRequest // 使用新的请求体
	if err := c.ShouldBindJSON(&req); err != nil {
		return nil, newGormError("无效的请求: %s", err.Error())
	}

	return singleton.UpdateDomain(domainID, req)
}

func GetDomainList(c *gin.Context) (any, error) {
	scope := c.DefaultQuery("scope", "admin")
	domains, err := singleton.GetDomains(scope)
	if err != nil {
		return nil, err
	}

	var response []DomainAPIResponse
	for _, d := range domains {
		apiDomain := DomainAPIResponse{
			Domain: d,
		}
		if d.BillingData != nil {
			var billing model.BillingDataMod
			if json.Unmarshal(d.BillingData, &billing) == nil && billing.EndDate != "" {
				if endDate, err := time.Parse(time.RFC3339, billing.EndDate); err == nil {
					daysLeft := int(time.Until(endDate).Hours() / 24)
					apiDomain.ExpiresInDays = &daysLeft
				}
			}
		}
		response = append(response, apiDomain)
	}

	return response, nil
}

func AddDomain(c *gin.Context) (any, error) {
	var req model.DomainAPIRequest // 使用 model/domain.go 中定义的请求体
	if err := c.ShouldBindJSON(&req); err != nil {
		return nil, newGormError("无效的请求: %s", err.Error())
	}
	return singleton.AddDomain(req.Domain)
}

func VerifyDomain(c *gin.Context) (any, error) {
	domainID, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		return nil, newGormError("无效的域名ID")
	}

	success, err := singleton.VerifyDomain(domainID)
	if err != nil {
		return nil, newGormError("验证过程中发生错误: %s", err.Error())
	}

	var message string
	if success {
		message = "验证成功，域名状态已更新"
	} else {
		message = "验证失败，未找到匹配的 TXT 记录"
	}

	// 对于这种包含非数据字段（如message）的特殊成功响应，
	// 我们可以直接返回一个 map，commonHandler 会将其包装
	return gin.H{
		"success": success,
		"message": message,
	}, nil
}

func DeleteDomain(c *gin.Context) (any, error) {
	domainID, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		return nil, nil // ID无效，直接返回成功，不做任何事
	}

	if err := singleton.DeleteDomain(domainID); err != nil {
		return nil, err
	}
	// 对于DELETE成功，通常不返回data，返回nil即可
	return nil, nil
}

func UpdateDomainInfo(c *gin.Context) (any, error) {
	domainID, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		return nil, newGormError("无效的域名ID")
	}

	var req model.DomainUpdateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		return nil, newGormError("无效的请求: %s", err.Error())
	}

	return singleton.UpdateDomain(domainID, req)
}

func SyncDomainWHOIS(c *gin.Context) (any, error) {
	domainID, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		return nil, newGormError("无效的域名ID")
	}

	domain, err := singleton.GetDomainByID(domainID)
	if err != nil {
		return nil, newGormError("未找到域名: %s", err.Error())
	}

	if err := singleton.SyncDomainWHOIS(domain); err != nil {
		return nil, fmt.Errorf("Whois 同步失败: %v", err)
	}

	return domain, nil
}

func SyncAllDomains(c *gin.Context) (any, error) {
	singleton.SyncAllDomains()
	// 手动触发到期检查，方便调试
	singleton.CronJobForDomainStatus()
	singleton.CronJobForServerStatus()
	return nil, nil
}
