package agent

import (
	"context"
	"fmt"

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

	"github.com/google/uuid"
	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

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

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

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

	// 1. 获取代理信息并验证（任意等级代理均可操作白名单）
	_, 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. 验证参数
	if req.IdCard == "" {
		return nil, errors.Wrapf(xerr.NewErrMsg("身份证号不能为空"), "")
	}
	if len(req.FeatureIds) == 0 {
		return nil, errors.Wrapf(xerr.NewErrMsg("请至少选择一个模块"), "")
	}

	// 3. 查询feature信息并计算总金额
	var totalAmount float64
	var orderItems []struct {
		FeatureId    string
		FeatureApiId string
		FeatureName  string
		Price        float64
	}

	for _, featureId := range req.FeatureIds {
		feature, err := l.svcCtx.FeatureModel.FindOne(l.ctx, featureId)
		if err != nil {
			if errors.Is(err, model.ErrNotFound) {
				return nil, errors.Wrapf(xerr.NewErrMsg(fmt.Sprintf("模块不存在: %s", featureId)), "")
			}
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询模块信息失败, %v", err)
		}

		// 直接使用feature的WhitelistPrice字段
		whitelistPrice := feature.WhitelistPrice

		if whitelistPrice <= 0 {
			return nil, errors.Wrapf(xerr.NewErrMsg(fmt.Sprintf("模块 %s 不支持白名单屏蔽", feature.Name)), "")
		}

		// 检查该身份证号+feature是否已经存在白名单记录
		whitelistBuilder := l.svcCtx.UserFeatureWhitelistModel.SelectBuilder().
			Where("id_card = ? AND feature_id = ?", req.IdCard, featureId)
		existing, err := l.svcCtx.UserFeatureWhitelistModel.FindAll(l.ctx, whitelistBuilder, "")
		if err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询白名单记录失败, %v", err)
		}
		// 检查是否有生效的记录（status=1）
		for _, item := range existing {
			if item.Status == 1 {
				return nil, errors.Wrapf(xerr.NewErrMsg(fmt.Sprintf("身份证号 %s 的模块 %s 已经加入白名单", req.IdCard, feature.Name)), "")
			}
		}

		totalAmount += whitelistPrice
		orderItems = append(orderItems, struct {
			FeatureId    string
			FeatureApiId string
			FeatureName  string
			Price        float64
		}{
			FeatureId:    feature.Id,
			FeatureApiId: feature.ApiId,
			FeatureName:  feature.Name,
			Price:        whitelistPrice,
		})
	}

	// 4. 生成订单号（白名单订单前缀 W_，限制长度不超过32）
	base := l.svcCtx.AlipayService.GenerateOutTradeNo()
	orderNo := "W_" + base
	if len(orderNo) > 32 {
		orderNo = orderNo[:32]
	}

	// 5. 使用事务创建订单和订单明细
	var orderId string
	err = l.svcCtx.WhitelistOrderModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
		// 创建订单
		order := &model.WhitelistOrder{
			Id:          uuid.NewString(),
			OrderNo:     orderNo,
			UserId:      userID,
			IdCard:      req.IdCard,
			TotalAmount: totalAmount,
			Status:      1, // 待支付
		}
		_, err := l.svcCtx.WhitelistOrderModel.Insert(ctx, session, order)
		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建订单失败, %v", err)
		}
		orderId = order.Id

		// 创建订单明细
		for _, item := range orderItems {
			orderItem := &model.WhitelistOrderItem{
				Id:           uuid.NewString(),
				OrderId:      orderId,
				FeatureId:    item.FeatureId,
				FeatureApiId: item.FeatureApiId,
				FeatureName:  item.FeatureName,
				Price:        item.Price,
			}
			_, err := l.svcCtx.WhitelistOrderItemModel.Insert(ctx, session, orderItem)
			if err != nil {
				return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建订单明细失败, %v", err)
			}
		}

		return nil
	})

	if err != nil {
		return nil, err
	}

	return &types.CreateWhitelistOrderResp{
		OrderId:     orderId,
		OrderNo:     orderNo,
		TotalAmount: totalAmount,
	}, nil
}
