package h5

import (
	"strconv"

	"github.com/gofiber/fiber/v2"

	"github.com/break/junhong_cmp_fiber/internal/model/dto"
	rechargeService "github.com/break/junhong_cmp_fiber/internal/service/recharge"
	"github.com/break/junhong_cmp_fiber/pkg/errors"
	"github.com/break/junhong_cmp_fiber/pkg/middleware"
	"github.com/break/junhong_cmp_fiber/pkg/response"
)

// RechargeHandler 充值订单处理器
// 提供充值订单的创建、预检、查询等接口
type RechargeHandler struct {
	service *rechargeService.Service
}

// NewRechargeHandler 创建充值订单处理器实例
// 参数:
//   - service: 充值服务
//
// 返回:
//   - *RechargeHandler: 充值订单处理器实例
func NewRechargeHandler(service *rechargeService.Service) *RechargeHandler {
	return &RechargeHandler{service: service}
}

// Create 创建充值订单
// POST /api/h5/wallets/recharge
// 请求参数:
//   - resource_type: 资源类型（iot_card/device）
//   - resource_id: 资源ID（卡ID或设备ID）
//   - amount: 充值金额（分）
//   - payment_method: 支付方式（wechat/alipay）
//
// 响应:
//   - 成功: 返回充值订单信息（订单ID、订单号、金额、状态等）
//   - 失败: 返回错误信息
func (h *RechargeHandler) Create(c *fiber.Ctx) error {
	var req dto.CreateRechargeRequest
	if err := c.BodyParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
	}

	ctx := c.UserContext()
	// 获取个人客户ID作为用户ID
	userID := middleware.GetCustomerIDFromContext(ctx)
	if userID == 0 {
		return errors.New(errors.CodeUnauthorized, "用户未登录")
	}

	result, err := h.service.Create(ctx, &req, userID)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

// RechargeCheck 充值预检
// GET /api/h5/wallets/recharge-check
// 请求参数:
//   - resource_type: 资源类型（iot_card/device）
//   - resource_id: 资源ID（卡ID或设备ID）
//
// 响应:
//   - 成功: 返回预检信息（是否需要强充、强充金额、最小/最大充值金额等）
//   - 失败: 返回错误信息
func (h *RechargeHandler) RechargeCheck(c *fiber.Ctx) error {
	var req dto.RechargeCheckRequest
	if err := c.QueryParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
	}

	// 验证必填参数
	if req.ResourceType == "" {
		return errors.New(errors.CodeInvalidParam, "资源类型不能为空")
	}
	if req.ResourceID == 0 {
		return errors.New(errors.CodeInvalidParam, "资源ID不能为空")
	}

	ctx := c.UserContext()
	result, err := h.service.GetRechargeCheck(ctx, req.ResourceType, req.ResourceID)
	if err != nil {
		return err
	}

	// 转换为 DTO 响应
	resp := &dto.RechargeCheckResponse{
		NeedForceRecharge:   result.NeedForceRecharge,
		ForceRechargeAmount: result.ForceRechargeAmount,
		TriggerType:         result.TriggerType,
		MinAmount:           result.MinAmount,
		MaxAmount:           result.MaxAmount,
		CurrentAccumulated:  result.CurrentAccumulated,
		Threshold:           result.Threshold,
		Message:             result.Message,
		FirstCommissionPaid: result.FirstCommissionPaid,
	}

	return response.Success(c, resp)
}

// List 查询充值订单列表
// GET /api/h5/wallets/recharges
// 请求参数:
//   - page: 页码（从1开始，默认1）
//   - page_size: 每页数量（默认20，最大100）
//   - wallet_id: 钱包ID筛选（可选）
//   - status: 状态筛选（可选，1-待支付 2-已支付 3-已完成 4-已关闭 5-已退款）
//   - start_time: 开始时间筛选（可选）
//   - end_time: 结束时间筛选（可选）
//
// 响应:
//   - 成功: 返回充值订单列表（分页数据、总记录数、总页数）
//   - 失败: 返回错误信息
func (h *RechargeHandler) List(c *fiber.Ctx) error {
	var req dto.RechargeListRequest
	if err := c.QueryParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
	}

	ctx := c.UserContext()
	// 获取个人客户ID作为用户ID
	userID := middleware.GetCustomerIDFromContext(ctx)
	if userID == 0 {
		return errors.New(errors.CodeUnauthorized, "用户未登录")
	}

	result, err := h.service.List(ctx, &req, userID)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

// Get 查询充值订单详情
// GET /api/h5/wallets/recharges/:id
// 路径参数:
//   - id: 充值订单ID
//
// 响应:
//   - 成功: 返回充值订单详情（订单ID、订单号、金额、状态、支付信息等）
//   - 失败: 返回错误信息
func (h *RechargeHandler) Get(c *fiber.Ctx) error {
	id, err := strconv.ParseUint(c.Params("id"), 10, 64)
	if err != nil {
		return errors.New(errors.CodeInvalidParam, "无效的充值订单ID")
	}

	ctx := c.UserContext()
	// 获取个人客户ID作为用户ID
	userID := middleware.GetCustomerIDFromContext(ctx)
	if userID == 0 {
		return errors.New(errors.CodeUnauthorized, "用户未登录")
	}

	result, err := h.service.GetByID(ctx, uint(id), userID)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}
