package agent

import (
	"context"
	"strconv"
	"qnc-server/app/main/model"
	"qnc-server/common/ctxdata"
	"qnc-server/common/xerr"

	"github.com/pkg/errors"

	"qnc-server/app/main/api/internal/svc"
	"qnc-server/app/main/api/internal/types"

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

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

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

func (l *GetAgentProductConfigLogic) GetAgentProductConfig() (resp *types.AgentProductConfigResp, err error) {
	userID, err := ctxdata.GetUidFromCtx(l.ctx)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败, %v", err)
	}

	// 1. 获取代理信息
	agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
	if err != nil {
		if errors.Is(err, model.ErrNotFound) {
			return nil, errors.Wrapf(xerr.NewErrMsg("您不是代理"), "")
		}
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败, %v", err)
	}

	// 2. 获取等级加成配置（从系统配置表读取）
	levelBonus, err := l.getLevelBonus(agentModel.Level)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取等级加成配置失败, %v", err)
	}

	// 3. 查询所有产品配置
	builder := l.svcCtx.AgentProductConfigModel.SelectBuilder()
	productConfigs, err := l.svcCtx.AgentProductConfigModel.FindAll(l.ctx, builder, "")
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询产品配置失败, %v", err)
	}

	// 4. 组装响应数据（通过 product_id 查询产品名称和英文标识）
	var respList []types.ProductConfigItem
	for _, productConfig := range productConfigs {
		// 通过 product_id 查询产品信息获取产品名称和英文标识
		product, err := l.svcCtx.ProductModel.FindOne(l.ctx, productConfig.ProductId)
		productName := ""
		productEn := ""
		if err == nil {
			productName = product.ProductName
			productEn = product.ProductEn
		} else {
			// 如果产品不存在，记录日志但不影响主流程
			l.Infof("查询产品信息失败, productId: %d, err: %v", productConfig.ProductId, err)
		}

		// 使用产品配置的基础底价（必须配置）
		productBasePrice := productConfig.BasePrice

		// 计算该产品的实际底价
		productActualBasePrice := productBasePrice + float64(levelBonus)

        priceRangeMin := productActualBasePrice
        upliftAmount, _ := l.getLevelMaxUpliftAmount(agentModel.Level)
        priceRangeMax := productConfig.SystemMaxPrice + upliftAmount

		// 使用产品配置的提价阈值和手续费比例，如果为NULL则使用0
		productPriceThreshold := 0.0
		if productConfig.PriceThreshold.Valid {
			productPriceThreshold = productConfig.PriceThreshold.Float64
		}
		productPriceFeeRate := 0.0
		if productConfig.PriceFeeRate.Valid {
			productPriceFeeRate = productConfig.PriceFeeRate.Float64
		}

		respList = append(respList, types.ProductConfigItem{
			ProductId:       productConfig.ProductId,
			ProductName:     productName,
			ProductEn:       productEn,
			ActualBasePrice: productActualBasePrice,
			PriceRangeMin:   priceRangeMin,
			PriceRangeMax:   priceRangeMax,
			PriceThreshold:  productPriceThreshold,
			PriceFeeRate:    productPriceFeeRate,
		})
	}

	return &types.AgentProductConfigResp{
		List: respList,
	}, nil
}

// getLevelBonus 获取等级加成（从配置表读取）
func (l *GetAgentProductConfigLogic) getLevelBonus(level int64) (int64, error) {
	var configKey string
	switch level {
	case 1: // 普通
		configKey = "level_1_bonus"
	case 2: // 黄金
		configKey = "level_2_bonus"
	case 3: // 钻石
		configKey = "level_3_bonus"
	default:
		return 0, nil
	}

	config, err := l.svcCtx.AgentConfigModel.FindOneByConfigKey(l.ctx, configKey)
	if err != nil {
		// 配置不存在时返回默认值
		l.Errorf("获取等级加成配置失败, level: %d, key: %s, err: %v，使用默认值", level, configKey, err)
		switch level {
		case 1:
			return 6, nil
		case 2:
			return 3, nil
		case 3:
			return 0, nil
		}
		return 0, nil
	}

	value, err := strconv.ParseFloat(config.ConfigValue, 64)
	if err != nil {
		return 0, errors.Wrapf(err, "解析配置值失败, key: %s, value: %s", configKey, config.ConfigValue)
	}
	return int64(value), nil
}

func (l *GetAgentProductConfigLogic) getLevelMaxUpliftAmount(level int64) (float64, error) {
    var key string
    switch level {
    case 2:
        key = "gold_max_uplift_amount"
    case 3:
        key = "diamond_max_uplift_amount"
    default:
        return 0, nil
    }
    config, err := l.svcCtx.AgentConfigModel.FindOneByConfigKey(l.ctx, key)
    if err != nil {
        return 0, nil
    }
    v, err := strconv.ParseFloat(config.ConfigValue, 64)
    if err != nil {
        return 0, nil
    }
    if v < 0 {
        return 0, nil
    }
    return v, nil
}
