package com.gxwebsoft.payment.dto;

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

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 统一支付响应DTO
 * 支持所有支付方式的统一响应格式
 *
 * @author 科技小王子
 * @since 2025-01-26
 */
@Data
@Schema(name = "统一支付响应", description = "支持所有支付方式的统一支付响应")
public class PaymentResponse {

    @Schema(description = "是否成功")
    private Boolean success;

    @Schema(description = "错误代码")
    private String errorCode;

    @Schema(description = "错误信息")
    private String errorMessage;

    @Schema(description = "订单号")
    private String orderNo;

    @Schema(description = "第三方交易号")
    private String transactionId;

    @Schema(description = "支付类型")
    private PaymentType paymentType;

    @Schema(description = "支付渠道")
    private PaymentChannel paymentChannel;

    @Schema(description = "支付状态")
    private PaymentStatus paymentStatus;

    @Schema(description = "支付金额")
    private BigDecimal amount;

    @Schema(description = "实际支付金额")
    private BigDecimal paidAmount;

    @Schema(description = "货币类型")
    private String currency;

    @Schema(description = "租户ID")
    private Integer tenantId;

    @Schema(description = "用户ID")
    private Integer userId;

    @Schema(description = "创建时间")
    private LocalDateTime createTime;

    @Schema(description = "支付时间")
    private LocalDateTime payTime;

    @Schema(description = "过期时间")
    private LocalDateTime expireTime;

    // 微信支付特有字段
    @Schema(description = "微信支付二维码URL（Native支付）")
    private String codeUrl;

    @Schema(description = "微信支付参数（JSAPI支付）")
    private WechatPayParams wechatPayParams;

    @Schema(description = "微信H5支付URL")
    private String h5Url;

    // 支付宝特有字段
    @Schema(description = "支付宝支付表单（网页支付）")
    private String alipayForm;

    @Schema(description = "支付宝支付URL（手机网站支付）")
    private String alipayUrl;

    @Schema(description = "支付宝支付参数（APP支付）")
    private String alipayParams;

    // 银联支付特有字段
    @Schema(description = "银联支付表单")
    private String unionPayForm;

    @Schema(description = "银联支付URL")
    private String unionPayUrl;

    @Schema(description = "扩展参数")
    private Map<String, Object> extraParams;

    /**
     * 微信支付参数
     */
    @Data
    @Schema(name = "微信支付参数", description = "微信JSAPI支付所需参数")
    public static class WechatPayParams {
        @Schema(description = "应用ID")
        private String appId;

        @Schema(description = "时间戳")
        private String timeStamp;

        @Schema(description = "随机字符串")
        private String nonceStr;

        @Schema(description = "订单详情扩展字符串")
        private String packageValue;

        @Schema(description = "签名方式")
        private String signType;

        @Schema(description = "签名")
        private String paySign;
    }

    /**
     * 创建成功响应
     */
    public static PaymentResponse success(String orderNo, PaymentType paymentType) {
        PaymentResponse response = new PaymentResponse();
        response.setSuccess(true);
        response.setOrderNo(orderNo);
        response.setPaymentType(paymentType);
        response.setPaymentStatus(PaymentStatus.PENDING);
        response.setCreateTime(LocalDateTime.now());
        return response;
    }

    /**
     * 创建失败响应
     */
    public static PaymentResponse failure(String errorCode, String errorMessage) {
        PaymentResponse response = new PaymentResponse();
        response.setSuccess(false);
        response.setErrorCode(errorCode);
        response.setErrorMessage(errorMessage);
        return response;
    }

    /**
     * 创建微信Native支付响应
     */
    public static PaymentResponse wechatNative(String orderNo, String codeUrl, BigDecimal amount, Integer tenantId) {
        PaymentResponse response = success(orderNo, PaymentType.WECHAT_NATIVE);
        response.setCodeUrl(codeUrl);
        response.setPaymentChannel(PaymentChannel.WECHAT_NATIVE);
        response.setAmount(amount);
        response.setTenantId(tenantId);
        response.setCurrency("CNY");
        return response;
    }

    /**
     * 创建微信JSAPI支付响应
     */
    public static PaymentResponse wechatJsapi(String orderNo, WechatPayParams payParams, BigDecimal amount, Integer tenantId) {
        PaymentResponse response = success(orderNo, PaymentType.WECHAT);
        response.setWechatPayParams(payParams);
        response.setPaymentChannel(PaymentChannel.WECHAT_JSAPI);
        response.setAmount(amount);
        response.setTenantId(tenantId);
        response.setCurrency("CNY");
        return response;
    }

    /**
     * 创建微信H5支付响应
     */
    public static PaymentResponse wechatH5(String orderNo, String h5Url, BigDecimal amount, Integer tenantId) {
        PaymentResponse response = success(orderNo, PaymentType.WECHAT);
        response.setH5Url(h5Url);
        response.setPaymentChannel(PaymentChannel.WECHAT_H5);
        response.setAmount(amount);
        response.setTenantId(tenantId);
        response.setCurrency("CNY");
        return response;
    }

    /**
     * 创建支付宝网页支付响应
     */
    public static PaymentResponse alipayWeb(String orderNo, String alipayForm, BigDecimal amount, Integer tenantId) {
        PaymentResponse response = success(orderNo, PaymentType.ALIPAY);
        response.setAlipayForm(alipayForm);
        response.setPaymentChannel(PaymentChannel.ALIPAY_WEB);
        response.setAmount(amount);
        response.setTenantId(tenantId);
        response.setCurrency("CNY");
        return response;
    }

    /**
     * 创建支付宝手机网站支付响应
     */
    public static PaymentResponse alipayWap(String orderNo, String alipayUrl, BigDecimal amount, Integer tenantId) {
        PaymentResponse response = success(orderNo, PaymentType.ALIPAY);
        response.setAlipayUrl(alipayUrl);
        response.setPaymentChannel(PaymentChannel.ALIPAY_WAP);
        response.setAmount(amount);
        response.setTenantId(tenantId);
        response.setCurrency("CNY");
        return response;
    }

    /**
     * 创建支付宝APP支付响应
     */
    public static PaymentResponse alipayApp(String orderNo, String alipayParams, BigDecimal amount, Integer tenantId) {
        PaymentResponse response = success(orderNo, PaymentType.ALIPAY);
        response.setAlipayParams(alipayParams);
        response.setPaymentChannel(PaymentChannel.ALIPAY_APP);
        response.setAmount(amount);
        response.setTenantId(tenantId);
        response.setCurrency("CNY");
        return response;
    }

    /**
     * 创建余额支付响应
     */
    public static PaymentResponse balance(String orderNo, BigDecimal amount, Integer tenantId, Integer userId) {
        PaymentResponse response = success(orderNo, PaymentType.BALANCE);
        response.setPaymentChannel(PaymentChannel.BALANCE);
        response.setPaymentStatus(PaymentStatus.SUCCESS);
        response.setAmount(amount);
        response.setPaidAmount(amount);
        response.setTenantId(tenantId);
        response.setUserId(userId);
        response.setCurrency("CNY");
        response.setPayTime(LocalDateTime.now());
        return response;
    }

    /**
     * 判断是否为成功响应
     */
    public boolean isSuccess() {
        return Boolean.TRUE.equals(success);
    }

    /**
     * 判断是否需要用户进一步操作
     */
    public boolean needUserAction() {
        return isSuccess() && paymentStatus == PaymentStatus.PENDING;
    }

    /**
     * 获取支付结果描述
     */
    public String getResultDescription() {
        if (!isSuccess()) {
            return errorMessage != null ? errorMessage : "支付失败";
        }
        
        if (paymentStatus == null) {
            return "支付状态未知";
        }
        
        switch (paymentStatus) {
            case SUCCESS:
                return "支付成功";
            case PENDING:
                return "等待支付";
            case PROCESSING:
                return "支付处理中";
            case FAILED:
                return "支付失败";
            case CANCELLED:
                return "支付已取消";
            case TIMEOUT:
                return "支付超时";
            default:
                return paymentStatus.getName();
        }
    }

    @Override
    public String toString() {
        return String.format("PaymentResponse{success=%s, orderNo='%s', paymentType=%s, paymentStatus=%s, amount=%s}", 
            success, orderNo, paymentType, paymentStatus, amount);
    }
}
