package handlers

import (
	"context"
	"net/http"
	"time"

	"go.mongodb.org/mongo-driver/v2/bson"
	"go.mongodb.org/mongo-driver/v2/mongo"
	"go.mongodb.org/mongo-driver/v2/mongo/options"

	"yh_web/server/config"
	"yh_web/server/models"

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

const smsConfigDocID = "sms_platform"

// GetSMSConfig 获取短信平台配置（仅超级用户 role_id=0, role=admin）
func GetSMSConfig(c *gin.Context) {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	coll := config.GetDB(config.DBName).Collection("system_config")
	var cfg models.SMSConfig
	err := coll.FindOne(ctx, bson.M{"_id": smsConfigDocID}).Decode(&cfg)
	if err != nil {
		if err == mongo.ErrNoDocuments {
			c.JSON(http.StatusOK, models.SMSConfig{})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, cfg)
}

// SMSConfigUpdateInput 短信配置更新
type SMSConfigUpdateInput struct {
	Provider   string `json:"provider"`
	AccessKey  string `json:"access_key"`
	SecretKey  string `json:"secret_key"`
	SignName   string `json:"sign_name"`
	TemplateID string `json:"template_id"`
	Enabled    *bool  `json:"enabled"`
}

// UpdateSMSConfig 更新短信平台配置（仅超级用户）
func UpdateSMSConfig(c *gin.Context) {
	var input SMSConfigUpdateInput
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	coll := config.GetDB(config.DBName).Collection("system_config")
	update := bson.M{}
	if input.Provider != "" {
		update["provider"] = input.Provider
	}
	if input.AccessKey != "" {
		update["access_key"] = input.AccessKey
	}
	if input.SecretKey != "" {
		update["secret_key"] = input.SecretKey
	}
	if input.SignName != "" {
		update["sign_name"] = input.SignName
	}
	if input.TemplateID != "" {
		update["template_id"] = input.TemplateID
	}
	if input.Enabled != nil {
		update["enabled"] = *input.Enabled
	}

	if len(update) == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无有效更新字段"})
		return
	}

	opts := options.UpdateOne().SetUpsert(true)
	_, err := coll.UpdateOne(ctx, bson.M{"_id": smsConfigDocID}, bson.M{"$set": update}, opts)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "配置已保存"})
}
