package com.dora.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 提现相关DTO
 */
public class WithdrawDto {

    @Data
    @Schema(description = "提现申请请求")
    public static class WithdrawRequest {
        @NotNull(message = "提现金额不能为空")
        @DecimalMin(value = "100.00", message = "提现金额不能少于100元")
        @Schema(description = "提现金额", example = "500.00")
        private BigDecimal amount;

        @NotBlank(message = "收款账户类型不能为空")
        @Pattern(regexp = "^(alipay|wechat|bank)$", message = "收款账户类型只能是alipay、wechat或bank")
        @Schema(description = "收款账户类型", example = "alipay", allowableValues = {"alipay", "wechat", "bank"})
        private String accountType;

        @NotBlank(message = "收款账户不能为空")
        @Schema(description = "收款账户", example = "13800138000")
        private String account;

        @NotBlank(message = "收款人姓名不能为空")
        @Schema(description = "收款人姓名", example = "张三")
        private String accountName;

        @Schema(description = "开户行名称（银行卡提现时必填）", example = "中国工商银行")
        private String bankName;

        @Schema(description = "支行名称（银行卡提现时可选）", example = "北京分行")
        private String bankBranch;
    }

    @Data
    @Schema(description = "提现申请响应")
    public static class WithdrawResponse {
        @Schema(description = "提现申请ID")
        private Long id;

        @Schema(description = "提现金额")
        private BigDecimal amount;

        @Schema(description = "收款账户类型")
        private String accountType;

        @Schema(description = "收款账户")
        private String account;

        @Schema(description = "收款人姓名")
        private String accountName;

        @Schema(description = "开户行名称")
        private String bankName;

        @Schema(description = "支行名称")
        private String bankBranch;

        @Schema(description = "状态（0待审核/1通过/2拒绝）")
        private Integer status;

        @Schema(description = "拒绝原因")
        private String reason;

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

        @Schema(description = "手续费金额")
        private BigDecimal feeAmount;

        @Schema(description = "实际到账金额")
        private BigDecimal actualAmount;

        @Schema(description = "处理完成时间")
        private LocalDateTime processedAt;

        @Schema(description = "申请时间")
        private LocalDateTime createTime;

        @Schema(description = "审核时间")
        private LocalDateTime reviewedAt;
    }

    @Data
    @Schema(description = "提现记录列表响应")
    public static class WithdrawListResponse {
        @Schema(description = "提现记录列表")
        private List<WithdrawResponse> records;

        @Schema(description = "总记录数")
        private Long total;

        @Schema(description = "当前页码")
        private Integer page;

        @Schema(description = "每页大小")
        private Integer size;
    }

    @Data
    @Schema(description = "用户收益信息响应")
    public static class UserRevenueResponse {
        @Schema(description = "总收益金额")
        private BigDecimal totalRevenue;

        @Schema(description = "可提现金额")
        private BigDecimal availableAmount;

        @Schema(description = "已提现金额")
        private BigDecimal withdrawnAmount;

        @Schema(description = "待审核金额")
        private BigDecimal pendingAmount;

        @Schema(description = "推广收益")
        private BigDecimal promotionRevenue;

        @Schema(description = "当前推广等级")
        private Integer promotionLevel;

        @Schema(description = "推广等级名称")
        private String promotionLevelName;

        @Schema(description = "推广收益比例")
        private BigDecimal promotionRate;

        @Schema(description = "距离下一等级还需要的付费粉丝数")
        private Integer fansToNextLevel;

        @Schema(description = "工作流收益详情列表")
        private List<WorkflowRevenueDetail> workflowDetails;

        @Schema(description = "视频收益详情列表")
        private List<VideoRevenueDetail> videoDetails;
    }

    @Data
    @Schema(description = "工作流收益详情")
    public static class WorkflowRevenueDetail {
        @Schema(description = "工作流ID")
        private Long workflowId;

        @Schema(description = "工作流名称")
        private String workflowName;

        @Schema(description = "工作流描述")
        private String workflowDescription;

        @Schema(description = "工作流封面图")
        private String workflowCoverUrl;

        @Schema(description = "工作流总收益")
        private BigDecimal totalRevenue;

        @Schema(description = "当前复制次数")
        private Integer currentCopies;

        @Schema(description = "收益阶段列表")
        private List<RevenueStage> stages;
    }

    @Data
    @Schema(description = "视频收益详情")
    public static class VideoRevenueDetail {
        @Schema(description = "视频ID")
        private Long videoId;

        @Schema(description = "视频标题")
        private String videoTitle;

        @Schema(description = "视频描述")
        private String videoDescription;

        @Schema(description = "视频封面图")
        private String videoCoverUrl;

        @Schema(description = "视频总收益")
        private BigDecimal totalRevenue;

        @Schema(description = "当前观看次数")
        private Integer currentViews;

        @Schema(description = "收益阶段列表")
        private List<RevenueStage> stages;
    }

    @Data
    @Schema(description = "收益阶段")
    public static class RevenueStage {
        @Schema(description = "阶段ID")
        private Long stageId;

        @Schema(description = "阶段等级")
        private Integer stageLevel;

        @Schema(description = "阶段名称")
        private String stageName;

        @Schema(description = "目标数量")
        private Integer targetCount;

        @Schema(description = "奖励金额")
        private BigDecimal rewardAmount;

        @Schema(description = "当前数量")
        private Integer currentCount;

        @Schema(description = "是否已达到")
        private Boolean isAchieved;

        @Schema(description = "达到时间")
        private LocalDateTime achievedAt;

        @Schema(description = "是否已提现")
        private Boolean isWithdrawn;

        @Schema(description = "提现时间")
        private LocalDateTime withdrawnAt;

        @Schema(description = "距离目标还差多少")
        private Integer remainingCount;
    }

    @Data
    @Schema(description = "基础收益信息响应")
    public static class BasicRevenueResponse {
        @Schema(description = "总收益金额")
        private BigDecimal totalRevenue;

        @Schema(description = "可提现金额")
        private BigDecimal availableAmount;

        @Schema(description = "已提现金额")
        private BigDecimal withdrawnAmount;

        @Schema(description = "待审核金额")
        private BigDecimal pendingAmount;

        @Schema(description = "推广收益")
        private BigDecimal promotionRevenue;

        @Schema(description = "当前推广等级")
        private Integer promotionLevel;

        @Schema(description = "推广等级名称")
        private String promotionLevelName;

        @Schema(description = "推广收益比例")
        private BigDecimal promotionRate;

        @Schema(description = "距离下一等级还需要的付费粉丝数")
        private Integer fansToNextLevel;
    }

    @Data
    @Schema(description = "工作流收益列表响应")
    public static class WorkflowRevenueListResponse {
        @Schema(description = "工作流收益详情列表")
        private List<WorkflowRevenueDetail> records;

        @Schema(description = "总记录数")
        private Long total;

        @Schema(description = "当前页码")
        private Integer page;

        @Schema(description = "每页大小")
        private Integer size;
    }

    @Data
    @Schema(description = "视频收益列表响应")
    public static class VideoRevenueListResponse {
        @Schema(description = "视频收益详情列表")
        private List<VideoRevenueDetail> records;

        @Schema(description = "总记录数")
        private Long total;

        @Schema(description = "当前页码")
        private Integer page;

        @Schema(description = "每页大小")
        private Integer size;
    }

    @Data
    @Schema(description = "推广收益响应")
    public static class PromotionRevenueResponse {
        @Schema(description = "推广收益")
        private BigDecimal promotionRevenue;

        @Schema(description = "当前推广等级")
        private Integer promotionLevel;

        @Schema(description = "推广等级名称")
        private String promotionLevelName;

        @Schema(description = "推广收益比例")
        private BigDecimal promotionRate;

        @Schema(description = "距离下一等级还需要的付费粉丝数")
        private Integer fansToNextLevel;

        @Schema(description = "当前付费粉丝数")
        private Integer currentPaidFans;
    }

    @Data
    @Schema(description = "管理员审核提现申请请求")
    public static class AdminReviewRequest {
        @NotNull(message = "提现申请ID不能为空")
        @Schema(description = "提现申请ID", example = "1")
        private Long withdrawId;

        @NotNull(message = "审核状态不能为空")
        @Schema(description = "审核状态（1通过/2拒绝）", example = "1", allowableValues = {"1", "2"})
        private Integer status;

        @Schema(description = "拒绝原因（状态为拒绝时必填）", example = "银行卡信息不正确")
        private String reason;

        @Schema(description = "第三方交易流水号（审核通过时填写）", example = "TX202501011234567890")
        private String transactionNo;

        @DecimalMin(value = "0.00", message = "手续费金额不能为负数")
        @Schema(description = "手续费金额（审核通过时填写）", example = "5.00")
        private BigDecimal feeAmount;

        @DecimalMin(value = "0.01", message = "实际到账金额必须大于0")
        @Schema(description = "实际到账金额（审核通过时必填）", example = "495.00")
        private BigDecimal actualAmount;
    }

    @Data
    @Schema(description = "管理员获取提现申请列表请求")
    public static class AdminWithdrawListRequest {
        @Schema(description = "页码", example = "1")
        private int page = 1;

        @Schema(description = "每页大小", example = "10")
        private int size = 10;

        @Schema(description = "审核状态筛选（0待审核/1通过/2拒绝）", example = "0")
        private Integer status;

        @Schema(description = "用户ID筛选", example = "123")
        private Long userId;

        @Schema(description = "提现账户类型筛选", example = "alipay")
        private String accountType;
    }

    @Data
    @Schema(description = "管理员提现申请列表响应")
    public static class AdminWithdrawListResponse {
        @Schema(description = "提现申请列表")
        private List<AdminWithdrawItem> records;

        @Schema(description = "总记录数")
        private Long total;

        @Schema(description = "当前页码")
        private int page;

        @Schema(description = "每页大小")
        private int size;
    }

    @Data
    @Schema(description = "管理员提现申请项")
    public static class AdminWithdrawItem {
        @Schema(description = "提现申请ID")
        private Long id;

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

        @Schema(description = "用户昵称")
        private String username;

        @Schema(description = "用户手机号")
        private String phone;

        @Schema(description = "用户身份证号")
        private String idNumber;

        @Schema(description = "提现金额")
        private BigDecimal amount;

        @Schema(description = "提现类型")
        private String withdrawType;

        @Schema(description = "收款账户类型")
        private String accountType;

        @Schema(description = "收款账户类型名称")
        private String accountTypeName;

        @Schema(description = "收款账户")
        private String account;

        @Schema(description = "收款人姓名")
        private String accountName;

        @Schema(description = "开户行名称")
        private String bankName;

        @Schema(description = "支行名称")
        private String bankBranch;

        @Schema(description = "申请状态")
        private Integer status;

        @Schema(description = "申请状态名称")
        private String statusName;

        @Schema(description = "拒绝原因")
        private String reason;

        @Schema(description = "审核人ID")
        private Long reviewerId;

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

        @Schema(description = "手续费金额")
        private BigDecimal feeAmount;

        @Schema(description = "实际到账金额")
        private BigDecimal actualAmount;

        @Schema(description = "处理完成时间")
        private LocalDateTime processedAt;

        @Schema(description = "申请时间")
        private LocalDateTime createTime;

        @Schema(description = "审核时间")
        private LocalDateTime reviewedAt;

        @Schema(description = "用户当前余额")
        private BigDecimal userBalance;

        @Schema(description = "用户累计收入")
        private BigDecimal userTotalIncome;
    }

    @Data
    @Schema(description = "审核状态统计")
    public static class WithdrawStatusStats {
        @Schema(description = "待审核数量")
        private Long pendingCount;

        @Schema(description = "待审核金额")
        private BigDecimal pendingAmount;

        @Schema(description = "已通过数量")
        private Long approvedCount;

        @Schema(description = "已通过金额")
        private BigDecimal approvedAmount;

        @Schema(description = "已拒绝数量")
        private Long rejectedCount;

        @Schema(description = "已拒绝金额")
        private BigDecimal rejectedAmount;
    }

    // 账户类型枚举
    public enum AccountType {
        ALIPAY("alipay", "支付宝"),
        WECHAT("wechat", "微信"),
        BANK("bank", "银行卡");

        private final String code;
        private final String name;

        AccountType(String code, String name) {
            this.code = code;
            this.name = name;
        }

        public static String getAccountTypeName(String code) {
            for (AccountType type : AccountType.values()) {
                if (type.code.equals(code)) {
                    return type.name;
                }
            }
            return code;
        }
    }

    // 提现状态枚举
    public enum WithdrawStatus {
        PENDING(0, "待审核"),
        APPROVED(1, "已通过"),
        REJECTED(2, "已拒绝");

        private final Integer code;
        private final String name;

        WithdrawStatus(Integer code, String name) {
            this.code = code;
            this.name = name;
        }

        public static String getStatusName(Integer code) {
            for (WithdrawStatus status : WithdrawStatus.values()) {
                if (status.code.equals(code)) {
                    return status.name;
                }
            }
            return "未知状态";
        }
    }
} 