package admin_agent

import (
	"context"
	"database/sql"
	"strconv"
	"bdqr-server/common/xerr"

	"github.com/pkg/errors"

	"bdqr-server/app/main/api/internal/svc"
	"bdqr-server/app/main/api/internal/types"
	"bdqr-server/app/main/model"

	"github.com/zeromicro/go-zero/core/logx"
)

type AdminUpdateAgentConfigLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewAdminUpdateAgentConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminUpdateAgentConfigLogic {
	return &AdminUpdateAgentConfigLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *AdminUpdateAgentConfigLogic) AdminUpdateAgentConfig(req *types.AdminUpdateAgentConfigReq) (resp *types.AdminUpdateAgentConfigResp, err error) {
	configTypeForKey := func(key string) string {
		switch key {
		case "level_1_bonus", "level_2_bonus", "level_3_bonus":
			return "bonus"
		case "upgrade_to_gold_fee", "upgrade_to_diamond_fee", "upgrade_to_gold_rebate", "upgrade_to_diamond_rebate":
			return "upgrade"
		case "direct_parent_amount_diamond", "direct_parent_amount_gold", "direct_parent_amount_normal", "max_gold_rebate_amount":
			return "rebate"
		case "commission_freeze_ratio", "commission_freeze_threshold", "commission_freeze_days":
			return "rebate"
		case "tax_rate", "tax_exemption_amount":
			return "tax"
		case "gold_max_uplift_amount", "diamond_max_uplift_amount":
			return "price"
		default:
			return "rebate"
		}
	}

	updateConfig := func(key string, value *float64) error {
		if value == nil {
			return nil
		}
		valStr := strconv.FormatFloat(*value, 'f', -1, 64)
		config, err := l.svcCtx.AgentConfigModel.FindOneByConfigKey(l.ctx, key)
		if err != nil {
			if errors.Is(err, model.ErrNotFound) {
				cfg := &model.AgentConfig{
					ConfigKey:   key,
					ConfigValue: valStr,
					ConfigType:  configTypeForKey(key),
					Description: sql.NullString{},
					DeleteTime:  sql.NullTime{},
					Version:     0,
				}
				_, insErr := l.svcCtx.AgentConfigModel.Insert(l.ctx, nil, cfg)
				if insErr != nil {
					return errors.Wrapf(insErr, "创建配置失败, key: %s", key)
				}
				return nil
			}
			return errors.Wrapf(err, "查询配置失败, key: %s", key)
		}
		config.ConfigValue = valStr
		if uErr := l.svcCtx.AgentConfigModel.UpdateWithVersion(l.ctx, nil, config); uErr != nil {
			if errors.Is(uErr, model.ErrNoRowsUpdate) {
				latestByKey, reErr := l.svcCtx.AgentConfigModel.FindOneByConfigKey(l.ctx, key)
				if reErr != nil {
					if errors.Is(reErr, model.ErrNotFound) {
						cfg := &model.AgentConfig{
							ConfigKey:   key,
							ConfigValue: valStr,
							ConfigType:  configTypeForKey(key),
							Description: sql.NullString{},
							DeleteTime:  sql.NullTime{},
							Version:     0,
						}
						_, insErr := l.svcCtx.AgentConfigModel.Insert(l.ctx, nil, cfg)
						if insErr != nil {
							return errors.Wrapf(insErr, "创建配置失败, key: %s", key)
						}
						return nil
					}
					return errors.Wrapf(reErr, "查询最新配置失败, key: %s", key)
				}
				latestByKey.ConfigValue = valStr
				return l.svcCtx.AgentConfigModel.UpdateWithVersion(l.ctx, nil, latestByKey)
			}
			return uErr
		}
		return nil
	}

	// 更新等级加成配置
	if req.LevelBonus != nil {
		if err := updateConfig("level_1_bonus", func() *float64 { v := float64(req.LevelBonus.Normal); return &v }()); err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新白银代理等级加成失败, %v", err)
		}
		if err := updateConfig("level_2_bonus", func() *float64 { v := float64(req.LevelBonus.Gold); return &v }()); err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新黄金代理等级加成失败, %v", err)
		}
		if err := updateConfig("level_3_bonus", func() *float64 { v := float64(req.LevelBonus.Diamond); return &v }()); err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钻石代理等级加成失败, %v", err)
		}
	}

	// 更新升级费用配置
	if req.UpgradeFee != nil {
		if err := updateConfig("upgrade_to_gold_fee", &req.UpgradeFee.NormalToGold); err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新普通→黄金升级费用失败, %v", err)
		}
		if err := updateConfig("upgrade_to_diamond_fee", &req.UpgradeFee.NormalToDiamond); err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新普通→钻石升级费用失败, %v", err)
		}
		// gold_to_diamond 是计算得出的，不需要更新
	}

	// 更新升级返佣配置
	if req.UpgradeRebate != nil {
		if err := updateConfig("upgrade_to_gold_rebate", &req.UpgradeRebate.NormalToGoldRebate); err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新普通→黄金返佣失败, %v", err)
		}
		if err := updateConfig("upgrade_to_diamond_rebate", &req.UpgradeRebate.ToDiamondRebate); err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新升级为钻石返佣失败, %v", err)
		}
	}

	// 更新直接上级返佣配置
	if req.DirectParentRebate != nil {
		if err := updateConfig("direct_parent_amount_diamond", &req.DirectParentRebate.Diamond); err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新直接上级是钻石的返佣金额失败, %v", err)
		}
		if err := updateConfig("direct_parent_amount_gold", &req.DirectParentRebate.Gold); err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新直接上级是黄金的返佣金额失败, %v", err)
		}
		if err := updateConfig("direct_parent_amount_normal", &req.DirectParentRebate.Normal); err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新直接上级是普通的返佣金额失败, %v", err)
		}
	}

	// 更新黄金代理最大返佣金额
	if err := updateConfig("max_gold_rebate_amount", req.MaxGoldRebateAmount); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新黄金代理最大返佣金额失败, %v", err)
	}

	// 更新佣金冻结配置
	if req.CommissionFreeze != nil {
		if err := updateConfig("commission_freeze_ratio", &req.CommissionFreeze.Ratio); err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新佣金冻结比例失败, %v", err)
		}
		if err := updateConfig("commission_freeze_threshold", &req.CommissionFreeze.Threshold); err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新佣金冻结阈值失败, %v", err)
		}
		// 更新解冻天数（整数类型）
		if req.CommissionFreeze.Days > 0 {
			daysFloat := float64(req.CommissionFreeze.Days)
			if err := updateConfig("commission_freeze_days", &daysFloat); err != nil {
				return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新佣金冻结解冻天数失败, %v", err)
			}
		}
	}

	// 更新税费配置
	if err := updateConfig("tax_rate", req.TaxRate); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新税率失败, %v", err)
	}
	if err := updateConfig("tax_exemption_amount", req.TaxExemptionAmount); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新免税额度失败, %v", err)
	}

	if err := updateConfig("gold_max_uplift_amount", req.GoldMaxUpliftAmount); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新黄金代理最高价上调金额失败, %v", err)
	}
	if err := updateConfig("diamond_max_uplift_amount", req.DiamondMaxUpliftAmount); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钻石代理最高价上调金额失败, %v", err)
	}

	return &types.AdminUpdateAgentConfigResp{
		Success: true,
	}, nil
}
