package com.dora.dto;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

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

/**
 * 管理端支付用户统计相关DTO
 */
public class AdminPaymentUserDto {

    // 私有构造函数
    private AdminPaymentUserDto() {
    }

    /**
     * 支付用户统计请求
     */
    @Data
    @Schema(description = "支付用户统计请求")
    public static class PaymentUserStatisticsRequest {
        @Schema(description = "开始日期（格式：yyyy-MM-dd）", example = "2024-01-01")
        @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "日期格式错误，应为yyyy-MM-dd")
        private String startDate;

        @Schema(description = "结束日期（格式：yyyy-MM-dd）", example = "2024-01-31")
        @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "日期格式错误，应为yyyy-MM-dd")
        private String endDate;
    }

    /**
     * 支付用户统计响应
     */
    @Data
    @Schema(description = "支付用户统计响应")
    public static class PaymentUserStatisticsResponse {
        @Schema(description = "统计概览")
        private PaymentOverview overview;

        @Schema(description = "支付用户列表")
        private List<PaymentUserInfo> paymentUsers;

        @Schema(description = "支付金额分布统计")
        private AmountDistributionStats amountDistribution;

        @Schema(description = "每日支付统计")
        private List<DailyPaymentStats> dailyStats;
    }

    /**
     * 支付概览统计
     */
    @Data
    @Schema(description = "支付概览统计")
    public static class PaymentOverview {
        @Schema(description = "支付用户总数")
        private Long totalPaymentUsers;

        @Schema(description = "支付订单总数")
        private Long totalPaymentOrders;

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

        @Schema(description = "平均客单价")
        private BigDecimal avgOrderAmount;

        @Schema(description = "新增VIP用户数")
        private Long newVipUsers;

        @Schema(description = "新增SVIP用户数")
        private Long newSvipUsers;

        @Schema(description = "复购用户数（有多次支付的用户）")
        private Long repeatPurchaseUsers;

        @Schema(description = "首次购买用户数")
        private Long firstTimeUsers;
    }

    /**
     * 支付用户信息
     */
    @Data
    @Schema(description = "支付用户信息")
    public static class PaymentUserInfo {
        @Schema(description = "用户ID")
        @JsonSerialize(using = ToStringSerializer.class)
        private Long userId;

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

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

        @Schema(description = "用户角色（1普通/2VIP/3SVIP）")
        private Integer role;

        @Schema(description = "支付订单数量")
        private Long orderCount;

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

        @Schema(description = "最近支付时间")
        private LocalDateTime lastPaidAt;

        @Schema(description = "首次支付时间")
        private LocalDateTime firstPaidAt;

        @Schema(description = "支付方式（1支付宝/2微信支付）")
        private Integer paymentMethod;

        @Schema(description = "是否为复购用户")
        private Boolean isRepeatUser;
    }

    /**
     * 支付金额分布统计
     */
    @Data
    @Schema(description = "支付金额分布统计")
    public static class AmountDistributionStats {
        @Schema(description = "0-50元支付用户数")
        private Long users0To50;

        @Schema(description = "50-100元支付用户数")
        private Long users50To100;

        @Schema(description = "100-200元支付用户数")
        private Long users100To200;

        @Schema(description = "200-500元支付用户数")
        private Long users200To500;

        @Schema(description = "500元以上支付用户数")
        private Long usersAbove500;
    }

    /**
     * 每日支付统计
     */
    @Data
    @Schema(description = "每日支付统计")
    public static class DailyPaymentStats {
        @Schema(description = "日期")
        private String date;

        @Schema(description = "支付用户数")
        private Long paymentUsers;

        @Schema(description = "支付订单数")
        private Long paymentOrders;

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

        @Schema(description = "新增VIP用户数")
        private Long newVipUsers;

        @Schema(description = "新增SVIP用户数")
        private Long newSvipUsers;
    }

    /**
     * 支付用户详情列表请求
     */
    @Data
    @Schema(description = "支付用户详情列表请求")
    public static class PaymentUserListRequest {
        @Schema(description = "开始日期（格式：yyyy-MM-dd）", example = "2024-01-01")
        @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "日期格式错误，应为yyyy-MM-dd")
        private String startDate;

        @Schema(description = "结束日期（格式：yyyy-MM-dd）", example = "2024-01-31")
        @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "日期格式错误，应为yyyy-MM-dd")
        private String endDate;

        @Schema(description = "用户角色筛选（1普通/2VIP/3SVIP）")
        private Integer role;

        @Schema(description = "是否只显示复购用户")
        private Boolean onlyRepeatUsers;

        @Schema(description = "最小支付金额")
        private BigDecimal minAmount;

        @Schema(description = "最大支付金额")
        private BigDecimal maxAmount;

        @Schema(description = "排序字段（totalAmount/orderCount/lastPaidAt/firstPaidAt）")
        private String sortField = "lastPaidAt";

        @Schema(description = "排序方向（ASC/DESC）")
        private String sortOrder = "DESC";

        @Schema(description = "页码", example = "1")
        private Integer page = 1;

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

    /**
     * 支付用户详情列表响应
     */
    @Data
    @Schema(description = "支付用户详情列表响应")
    public static class PaymentUserListResponse {
        @Schema(description = "支付用户列表")
        private List<PaymentUserInfo> users;

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

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

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

        @Schema(description = "总页数")
        private Integer totalPages;
    }
}
