package handler

import (
	"context"
	"encoding/json"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/sundynix/sundynix-gateway/internal/payment"
	"github.com/sundynix/sundynix-shared/secrets"
)

// 微信支付配置控制面：配置进 DB（sundynix_setting）、改完热生效不重启；
// APIv3 密钥入库前 AES-GCM 加密（与模型 API Key 同一把 SUNDYNIX_SECRET_KEY），
// 私钥文件留在服务器磁盘，库里只存路径。env 仍作兜底（DB 优先 → env → 隐藏）。

// SettingWechatPay 是 settings KV 里的键，值为 payment.Config 的 JSON（apiv3_key 为密文）。
const SettingWechatPay = "payment_wechat"

// loadWechatConfig 读支付配置：DB 优先（解密 apiv3），空则回退 env。
func (h *Handler) loadWechatConfig(ctx context.Context) payment.Config {
	raw := h.db.GetSetting(ctx, SettingWechatPay)
	if raw == "" {
		return payment.ConfigFromEnv()
	}
	var c payment.Config
	if err := json.Unmarshal([]byte(raw), &c); err != nil {
		return payment.ConfigFromEnv()
	}
	if c.APIv3Key != "" {
		if plain, err := secrets.Decrypt(c.APIv3Key); err == nil {
			c.APIv3Key = plain
		}
	}
	return c
}

// InitWechat 启动时装配微信渠道（DB 优先 → env）。失败只降级隐藏，不阻断启动。
func (h *Handler) InitWechat(ctx context.Context) {
	_ = h.pay.Reload(ctx, h.loadWechatConfig(ctx))
}

// AdminGetWechatPay: GET /api/v1/admin/payment/wechat —— 当前配置（密钥不回显）+ 渠道状态。
func (h *Handler) AdminGetWechatPay(c *gin.Context) {
	cfg := h.loadWechatConfig(c.Request.Context())
	enabled, reason := h.pay.Status()
	c.JSON(http.StatusOK, gin.H{
		"config": gin.H{
			"mchid":            cfg.MchID,
			"cert_serial":      cfg.CertSerial,
			"private_key_path": cfg.PrivateKeyPath,
			"public_key_path":  cfg.PublicKeyPath,
			"public_key_id":    cfg.PublicKeyID,
			"appid":            cfg.AppID,
			"notify_url":       cfg.NotifyURL,
			"has_apiv3_key":    cfg.APIv3Key != "", // 密钥只报有无，明文永不回显
		},
		"enabled": enabled,
		"reason":  reason,
	})
}

// AdminSaveWechatPay: PUT /api/v1/admin/payment/wechat —— 保存配置并热重载渠道。
// apiv3_key 留空 = 沿用已存的（只写不回显的编辑语义，同模型 Key）。
func (h *Handler) AdminSaveWechatPay(c *gin.Context) {
	var b struct {
		MchID          string `json:"mchid"`
		CertSerial     string `json:"cert_serial"`
		PrivateKeyPath string `json:"private_key_path"`
		APIv3Key       string `json:"apiv3_key"`
		AppID          string `json:"appid"`
		NotifyURL      string `json:"notify_url"`
		PublicKeyPath  string `json:"public_key_path"`
		PublicKeyID    string `json:"public_key_id"`
	}
	if err := c.ShouldBindJSON(&b); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
		return
	}
	ctx := c.Request.Context()
	apiv3 := strings.TrimSpace(b.APIv3Key)
	if apiv3 == "" {
		apiv3 = h.loadWechatConfig(ctx).APIv3Key // 留空沿用旧密钥（此处为明文，稍后统一加密入库）
	}
	cfg := payment.Config{
		MchID:          strings.TrimSpace(b.MchID),
		CertSerial:     strings.TrimSpace(b.CertSerial),
		PrivateKeyPath: strings.TrimSpace(b.PrivateKeyPath),
		APIv3Key:       apiv3,
		AppID:          strings.TrimSpace(b.AppID),
		NotifyURL:      strings.TrimSpace(b.NotifyURL),
		PublicKeyPath:  strings.TrimSpace(b.PublicKeyPath),
		PublicKeyID:    strings.TrimSpace(b.PublicKeyID),
	}
	stored := cfg
	if stored.APIv3Key != "" {
		enc, err := secrets.Encrypt(stored.APIv3Key)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "密钥加密失败: " + err.Error()})
			return
		}
		stored.APIv3Key = enc
	}
	raw, _ := json.Marshal(stored)
	if err := h.db.SetSetting(ctx, SettingWechatPay, string(raw)); err != nil {
		c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
		return
	}
	// 热重载：配置有毛病只会让渠道隐藏并给出原因，不影响其它功能。
	_ = h.pay.Reload(ctx, cfg)
	enabled, reason := h.pay.Status()
	c.JSON(http.StatusOK, gin.H{"status": "ok", "enabled": enabled, "reason": reason})
}
