package com.gxwebsoft.payment.dto;

import com.gxwebsoft.payment.enums.PaymentType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import javax.validation.Valid;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.List;

/**
 * 支付与订单创建请求DTO
 * 用于统一支付模块中的订单创建和支付
 *
 * @author 科技小王子
 * @since 2025-01-26
 */
@Data
@Schema(name = "PaymentWithOrderRequest", description = "支付与订单创建请求")
public class PaymentWithOrderRequest {

    // ========== 支付相关字段 ==========
    
    @Schema(description = "支付类型", required = true)
    @NotNull(message = "支付类型不能为空")
    private PaymentType paymentType;

    @Schema(description = "支付金额", required = true)
    @NotNull(message = "支付金额不能为空")
    @DecimalMin(value = "0.01", message = "支付金额必须大于0")
    @Digits(integer = 10, fraction = 2, message = "支付金额格式不正确")
    private BigDecimal amount;

    @Schema(description = "订单标题", required = true)
    @NotBlank(message = "订单标题不能为空")
    @Size(max = 60, message = "订单标题长度不能超过60个字符")
    private String subject;

    @Schema(description = "订单描述")
    @Size(max = 500, message = "订单描述长度不能超过500个字符")
    private String description;

    @Schema(description = "租户ID", required = true)
    @NotNull(message = "租户ID不能为空")
    @Positive(message = "租户ID必须为正数")
    private Integer tenantId;

    // ========== 订单相关字段 ==========
    
    @Schema(description = "订单信息", required = true)
    @Valid
    @NotNull(message = "订单信息不能为空")
    private OrderInfo orderInfo;

    /**
     * 订单信息
     */
    @Data
    @Schema(name = "OrderInfo", description = "订单信息")
    public static class OrderInfo {
        
        @Schema(description = "订单类型，0商城订单 1预定订单/外卖 2会员卡")
        @NotNull(message = "订单类型不能为空")
        @Min(value = 0, message = "订单类型值无效")
        @Max(value = 2, message = "订单类型值无效")
        private Integer type;

        @Schema(description = "收货人姓名")
        @Size(max = 50, message = "收货人姓名长度不能超过50个字符")
        private String realName;

        @Schema(description = "收货地址")
        @Size(max = 200, message = "收货地址长度不能超过200个字符")
        private String address;

        @Schema(description = "关联收货地址ID")
        private Integer addressId;

        @Schema(description = "快递/自提，0快递 1自提")
        private Integer deliveryType;

        @Schema(description = "下单渠道，0小程序预定 1俱乐部训练场 3活动订场")
        private Integer channel;

        @Schema(description = "商户ID")
        private Long merchantId;

        @Schema(description = "商户名称")
        private String merchantName;

        @Schema(description = "使用的优惠券ID")
        private Integer couponId;

        @Schema(description = "备注")
        @Size(max = 500, message = "备注长度不能超过500字符")
        private String comments;

        @Schema(description = "订单商品列表", required = true)
        @Valid
        @NotEmpty(message = "订单商品列表不能为空")
        private List<OrderGoodsItem> goodsItems;
    }

    /**
     * 订单商品项
     */
    @Data
    @Schema(name = "OrderGoodsItem", description = "订单商品项")
    public static class OrderGoodsItem {
        
        @Schema(description = "商品ID", required = true)
        @NotNull(message = "商品ID不能为空")
        @Positive(message = "商品ID必须为正数")
        private Integer goodsId;

        @Schema(description = "商品SKU ID")
        private Integer skuId;

        @Schema(description = "商品数量", required = true)
        @NotNull(message = "商品数量不能为空")
        @Min(value = 1, message = "商品数量必须大于0")
        private Integer quantity;

        @Schema(description = "规格信息，如：颜色:红色|尺寸:L")
        private String specInfo;
    }

    /**
     * 获取格式化的金额字符串
     */
    public String getFormattedAmount() {
        if (amount == null) {
            return "0.00";
        }
        return String.format("%.2f", amount);
    }

    /**
     * 验证订单商品总金额是否与支付金额一致
     */
    public boolean isAmountConsistent() {
        if (amount == null || orderInfo == null || orderInfo.getGoodsItems() == null) {
            return false;
        }
        
        // 这里可以添加商品金额计算逻辑
        // 实际实现时需要查询数据库获取商品价格
        return true;
    }

    @Override
    public String toString() {
        return String.format("PaymentWithOrderRequest{paymentType=%s, amount=%s, subject='%s', tenantId=%d, goodsCount=%d}", 
            paymentType, getFormattedAmount(), subject, tenantId, 
            orderInfo != null && orderInfo.getGoodsItems() != null ? orderInfo.getGoodsItems().size() : 0);
    }
}
