package com.ylx.point.enums;

import lombok.Getter;

import java.util.Arrays;
import java.util.Optional;

/**
 * 任务次数限制枚举
 * 包含：无限制、总次数限制、每日次数限制
 * 自带策略模式校验逻辑
 */
@Getter
public enum TaskLimitTimesEnum {

    // ====================== 枚举实例 ======================
    /**
     * 无限制
     */
    UNLIMITED("0", null, "无限制", null, (current, max) -> true),

    /**
     * 总次数限制 - 仅限一次
     */
    LIMIT_ONCE("1", 1, "仅限一次", LimitCategory.TOTAL, (current, max) -> current < max),
    /**
     * 总次数限制 - 仅限二次
     */
    LIMIT_TWICE("3", 2, "仅限二次", LimitCategory.TOTAL, (current, max) -> current < max),
    /**
     * 总次数限制 - 仅限三次
     */
    LIMIT_THRICE("5", 3, "仅限三次", LimitCategory.TOTAL, (current, max) -> current < max),

    /**
     * 每日限制 - 每日一次
     */
    DAILY_ONCE("2", 1, "每日一次", LimitCategory.DAILY, (current, max) -> current < max),
    /**
     * 每日限制 - 每日二次
     */
    DAILY_TWICE("4", 2, "每日二次", LimitCategory.DAILY, (current, max) -> current < max),
    /**
     * 每日限制 - 每日三次
     */
    DAILY_THRICE("6", 3, "每日三次", LimitCategory.DAILY, (current, max) -> current < max);

    // ====================== 内部枚举：限制类型 ======================
    public enum LimitCategory {
        /**
         * 总次数限制（累计次数）
         */
        TOTAL,
        /**
         * 每日次数限制
         */
        DAILY
    }

    // ====================== 函数式接口：限制策略 ======================
    @FunctionalInterface
    public interface LimitStrategy {
        /**
         * 校验次数是否超限
         * @param currentCount 当前已使用次数
         * @param maxLimit 最大允许次数
         * @return true=未超限 / false=已超限
         */
        boolean checkLimit(int currentCount, int maxLimit);
    }

    // ====================== 字段 ======================
    /**
     * 枚举值（数据库/前端传值）
     */
    private final String value;
    /**
     * 限制次数
     */
    private final Integer time;
    /**
     * 中文描述
     */
    private final String label;
    /**
     * 限制分类：总次数/每日
     */
    private final LimitCategory category;
    /**
     * 校验策略
     */
    private final LimitStrategy strategy;

    // ====================== 构造器 ======================
    TaskLimitTimesEnum(String value, Integer time, String label, LimitCategory category, LimitStrategy strategy) {
        this.value = value;
        this.time = time;
        this.label = label;
        this.category = category;
        this.strategy = strategy;
    }

    // ====================== 核心方法 ======================
    /**
     * 执行次数限制校验
     * @param currentCount 当前已使用次数
     * @return true=可以继续执行 / false=已超限
     */
    public boolean executeCheck(int currentCount) {
        // 无限制直接放行
        if (this == UNLIMITED) {
            return true;
        }
        // 执行策略校验
        return strategy.checkLimit(currentCount, this.time);
    }

    // ====================== 工具方法 ======================
    /**
     * 根据 value 获取枚举
     */
    public static TaskLimitTimesEnum getByValue(String value) {
        if (value == null) {
            return null;
        }
        return Arrays.stream(values())
                .filter(e -> value.equals(e.value))
                .findFirst()
                .orElse(null);
    }

    /**
     * 根据 value 安全获取枚举（避免空指针）
     */
    public static Optional<TaskLimitTimesEnum> getOptionalByValue(String value) {
        return Arrays.stream(values())
                .filter(e -> e.value.equals(value))
                .findFirst();
    }

}