package com.dora.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;

import jakarta.validation.constraints.*;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 管理端礼品码管理相关DTO
 */
public class AdminGiftCodeDto {

    private AdminGiftCodeDto() {
        // 工具类，禁止实例化
    }

    /**
     * 礼品码列表查询请求
     */
    @Data
    @Schema(description = "礼品码列表查询请求")
    public static class GiftCodeListRequest {
        @Schema(description = "页码", example = "1")
        @Min(value = 1, message = "页码必须大于0")
        private Integer page = 1;

        @Schema(description = "每页大小", example = "20")
        @Min(value = 1, message = "每页大小必须大于0")
        @Max(value = 100, message = "每页大小不能超过100")
        private Integer size = 20;

        @Schema(description = "搜索关键词（礼品码、名称）")
        private String keyword;

        @Schema(description = "礼品码类型筛选（1-积分卡/2-会员卡）")
        private Integer type;

        @Schema(description = "启用状态筛选（0-禁用/1-启用）")
        private Integer isActive;

        @Schema(description = "创建时间开始")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTimeStart;

        @Schema(description = "创建时间结束")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTimeEnd;

        @Schema(description = "排序字段", example = "createTime")
        private String sortField = "createTime";

        @Schema(description = "排序方向", example = "desc")
        private String sortOrder = "desc";
    }

    /**
     * 礼品码列表响应
     */
    @Data
    @Schema(description = "礼品码列表响应")
    public static class GiftCodeListResponse {
        @Schema(description = "礼品码列表")
        private List<GiftCodeListItem> list;

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

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

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

    /**
     * 礼品码列表项
     */
    @Data
    @Schema(description = "礼品码列表项")
    public static class GiftCodeListItem {
        @Schema(description = "ID")
        private Long id;

        @Schema(description = "礼品码")
        private String code;

        @Schema(description = "礼品码名称")
        private String name;

        @Schema(description = "礼品码类型（1-积分卡/2-会员卡）")
        private Integer type;

        @Schema(description = "类型名称")
        private String typeName;

        @Schema(description = "积分数量")
        private Integer points;

        @Schema(description = "目标角色")
        private Integer targetRole;

        @Schema(description = "总可用次数")
        private Integer totalCount;

        @Schema(description = "已使用次数")
        private Integer usedCount;

        @Schema(description = "剩余次数")
        private Integer remainingCount;

        @Schema(description = "是否启用")
        private Integer isActive;

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

        @Schema(description = "过期时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime expireTime;

        @Schema(description = "创建时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTime;
    }

    /**
     * 创建礼品码请求
     */
    @Data
    @Schema(description = "创建礼品码请求")
    public static class CreateGiftCodeRequest {
        @NotBlank(message = "礼品码不能为空")
        @Size(max = 32, message = "礼品码长度不能超过32位")
        @Pattern(regexp = "^[A-Za-z0-9_-]+$", message = "礼品码只能包含字母、数字、下划线和连接符")
        @Schema(description = "礼品码", example = "VIP2024")
        private String code;

        @NotBlank(message = "礼品码名称不能为空")
        @Size(max = 128, message = "礼品码名称长度不能超过128位")
        @Schema(description = "礼品码名称", example = "VIP会员卡")
        private String name;

        @Schema(description = "礼品码描述")
        private String description;

        @NotNull(message = "礼品码类型不能为空")
        @Min(value = 1, message = "礼品码类型必须为1或2")
        @Max(value = 2, message = "礼品码类型必须为1或2")
        @Schema(description = "礼品码类型（1-积分卡/2-会员卡）", example = "2")
        private Integer type;

        @Schema(description = "积分数量（积分卡类型必填）", example = "1000")
        private Integer points;

        @Schema(description = "积分有效期天数（积分卡类型必填）", example = "365")
        private Integer pointsExpireDays;

        @Schema(description = "目标角色等级（会员卡类型必填）", example = "2")
        private Integer targetRole;

        @Schema(description = "会员有效期天数（会员卡类型必填）", example = "30")
        private Integer durationDays;

        @NotNull(message = "总可用次数不能为空")
        @Min(value = 1, message = "总可用次数至少为1")
        @Schema(description = "总可用次数", example = "1")
        private Integer totalCount;

        @Schema(description = "过期时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime expireTime;
    }

    /**
     * 更新礼品码请求
     */
    @Data
    @Schema(description = "更新礼品码请求")
    public static class UpdateGiftCodeRequest {
        @NotNull(message = "礼品码ID不能为空")
        @Schema(description = "礼品码ID")
        private Long id;

        @NotBlank(message = "礼品码名称不能为空")
        @Size(max = 128, message = "礼品码名称长度不能超过128位")
        @Schema(description = "礼品码名称", example = "VIP会员卡")
        private String name;

        @Schema(description = "礼品码描述")
        private String description;

        @Schema(description = "积分数量（积分卡类型）", example = "1000")
        private Integer points;

        @Schema(description = "积分有效期天数（积分卡类型）", example = "365")
        private Integer pointsExpireDays;

        @Schema(description = "目标角色等级（会员卡类型）", example = "2")
        private Integer targetRole;

        @Schema(description = "会员有效期天数（会员卡类型）", example = "30")
        private Integer durationDays;

        @Min(value = 1, message = "总可用次数至少为1")
        @Schema(description = "总可用次数", example = "1")
        private Integer totalCount;

        @Schema(description = "过期时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime expireTime;
    }

    /**
     * 礼品码详情响应
     */
    @Data
    @Schema(description = "礼品码详情响应")
    public static class GiftCodeDetailResponse {
        @Schema(description = "ID")
        private Long id;

        @Schema(description = "礼品码")
        private String code;

        @Schema(description = "礼品码名称")
        private String name;

        @Schema(description = "礼品码描述")
        private String description;

        @Schema(description = "礼品码类型（1-积分卡/2-会员卡）")
        private Integer type;

        @Schema(description = "类型名称")
        private String typeName;

        @Schema(description = "积分数量")
        private Integer points;

        @Schema(description = "积分有效期天数")
        private Integer pointsExpireDays;

        @Schema(description = "目标角色等级")
        private Integer targetRole;

        @Schema(description = "角色名称")
        private String targetRoleName;

        @Schema(description = "会员有效期天数")
        private Integer durationDays;

        @Schema(description = "总可用次数")
        private Integer totalCount;

        @Schema(description = "已使用次数")
        private Integer usedCount;

        @Schema(description = "剩余次数")
        private Integer remainingCount;

        @Schema(description = "使用率（百分比）")
        private Double usageRate;

        @Schema(description = "是否启用")
        private Integer isActive;

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

        @Schema(description = "过期时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime expireTime;

        @Schema(description = "创建时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTime;

        @Schema(description = "更新时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime updateTime;
    }

    /**
     * 礼品码状态更新请求
     */
    @Data
    @Schema(description = "礼品码状态更新请求")
    public static class UpdateGiftCodeStatusRequest {
        @NotNull(message = "礼品码ID不能为空")
        @Schema(description = "礼品码ID")
        private Long id;

        @NotNull(message = "状态不能为空")
        @Min(value = 0, message = "状态值必须为0或1")
        @Max(value = 1, message = "状态值必须为0或1")
        @Schema(description = "启用状态（0-禁用/1-启用）")
        private Integer isActive;
    }

    /**
     * 批量操作请求
     */
    @Data
    @Schema(description = "批量操作请求")
    public static class BatchOperationRequest {
        @NotNull(message = "礼品码ID列表不能为空")
        @NotEmpty(message = "礼品码ID列表不能为空")
        @Schema(description = "礼品码ID列表")
        private List<Long> ids;

        @NotBlank(message = "操作类型不能为空")
        @Schema(description = "操作类型（enable-启用/disable-禁用/delete-删除）")
        private String operation;
    }

    /**
     * 使用记录列表请求
     */
    @Data
    @Schema(description = "使用记录列表请求")
    public static class UsageListRequest {
        @Schema(description = "页码", example = "1")
        @Min(value = 1, message = "页码必须大于0")
        private Integer page = 1;

        @Schema(description = "每页大小", example = "20")
        @Min(value = 1, message = "每页大小必须大于0")
        @Max(value = 100, message = "每页大小不能超过100")
        private Integer size = 20;

        @Schema(description = "礼品码ID")
        private Long giftCodeId;

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

        @Schema(description = "礼品码")
        private String code;

        @Schema(description = "礼品码类型（1-积分卡/2-会员卡）")
        private Integer type;

        @Schema(description = "使用状态（0-失败/1-成功）")
        private Integer status;

        @Schema(description = "使用时间开始")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTimeStart;

        @Schema(description = "使用时间结束")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTimeEnd;

        @Schema(description = "排序字段", example = "createTime")
        private String sortField = "createTime";

        @Schema(description = "排序方向", example = "desc")
        private String sortOrder = "desc";
    }

    /**
     * 使用记录列表响应
     */
    @Data
    @Schema(description = "使用记录列表响应")
    public static class UsageListResponse {
        @Schema(description = "使用记录列表")
        private List<UsageListItem> list;

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

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

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

    /**
     * 使用记录列表项
     */
    @Data
    @Schema(description = "使用记录列表项")
    public static class UsageListItem {
        @Schema(description = "ID")
        private Long id;

        @Schema(description = "礼品码ID")
        private Long giftCodeId;

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

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

        @Schema(description = "礼品码")
        private String code;

        @Schema(description = "礼品码名称")
        private String giftCodeName;

        @Schema(description = "礼品码类型（1-积分卡/2-会员卡）")
        private Integer type;

        @Schema(description = "类型名称")
        private String typeName;

        @Schema(description = "积分数量")
        private Integer points;

        @Schema(description = "目标角色")
        private Integer targetRole;

        @Schema(description = "用户原角色")
        private Integer oldRole;

        @Schema(description = "用户新角色")
        private Integer newRole;

        @Schema(description = "用户原积分")
        private Integer oldPoints;

        @Schema(description = "用户新积分")
        private Integer newPoints;

        @Schema(description = "使用状态（0-失败/1-成功）")
        private Integer status;

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

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

        @Schema(description = "使用时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTime;
    }

    /**
     * 礼品码统计响应
     */
    @Data
    @Schema(description = "礼品码统计响应")
    public static class GiftCodeStatisticsResponse {
        @Schema(description = "总礼品码数量")
        private Long totalCount;

        @Schema(description = "启用的礼品码数量")
        private Long activeCount;

        @Schema(description = "禁用的礼品码数量")
        private Long inactiveCount;

        @Schema(description = "积分卡数量")
        private Long pointsCardCount;

        @Schema(description = "会员卡数量")
        private Long membershipCardCount;

        @Schema(description = "已过期数量")
        private Long expiredCount;

        @Schema(description = "总使用次数")
        private Long totalUsageCount;

        @Schema(description = "成功使用次数")
        private Long successUsageCount;

        @Schema(description = "失败使用次数")
        private Long failedUsageCount;

        @Schema(description = "本月新增礼品码数量")
        private Long thisMonthNewCount;

        @Schema(description = "本月使用次数")
        private Long thisMonthUsageCount;
    }
}
