package cn.stylefeng.team.project.api.enums;

import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.rule.base.ReadableEnum;
import cn.stylefeng.team.project.api.pojo.dto.CycleLimitItem;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Getter
public enum FilingCycleEnum implements ReadableEnum<FilingCycleEnum> {

    ITEM_1(1, "不限定"),

    ITEM_2(2, "天"),

    ITEM_3(3, "周"),

    ITEM_4(4, "月"),

    ITEM_5(5, "季度"),

    ITEM_6(6, "年");

    @EnumValue
    @JsonValue
    private final Integer code;

    private final String message;

    FilingCycleEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    public static FilingCycleEnum codeToEnum(String code) {
        if (null != code) {
            for (FilingCycleEnum enumItem : FilingCycleEnum.values()) {
                if (enumItem.getCode().toString().equals(code)) {
                    return enumItem;
                }
            }
        }
        return null;
    }

    public static String codeToMessage(String code) {
        if (null != code) {
            for (FilingCycleEnum enumItem : FilingCycleEnum.values()) {
                if (enumItem.getCode().toString().equals(code)) {
                    return enumItem.getMessage();
                }
            }
        }
        return "未知";
    }

    @Override
    public Object getKey() {
        return this.code;
    }

    @Override
    public Object getName() {
        return this.message;
    }

    @Override
    public FilingCycleEnum parseToEnum(String originValue) {
        if (ObjectUtil.isEmpty(originValue)) {
            return null;
        }
        for (FilingCycleEnum value : FilingCycleEnum.values()) {
            if (value.code.toString().equals(originValue)) {
                return value;
            }
        }
        return null;
    }

    public static boolean getCyclicFlag(int code) {
        return code != ITEM_1.getCode();
    }

    public static List<CycleLimitItem> getAllPeriods(int cycle, Date startTime, Date endTime) {
        List<CycleLimitItem> periods = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(startTime);

        while (!calendar.getTime().after(endTime)) {

            Date cycleStartTime = calendar.getTime();

            Calendar endCalendar = (Calendar) calendar.clone();

            switch (cycle) {
                case 2: // 天
                    endCalendar.add(Calendar.DAY_OF_MONTH, 1);
                    endCalendar.add(Calendar.SECOND, -1); // 减去 1 秒，表示当天的最后一秒
                    break;
                case 3: // 周
                    endCalendar.add(Calendar.WEEK_OF_YEAR, 1);
                    endCalendar.add(Calendar.SECOND, -1); // 减去 1 秒，表示该周的最后一秒
                    break;
                case 4: // 月
                    endCalendar.add(Calendar.MONTH, 1);
                    endCalendar.add(Calendar.SECOND, -1); // 减去 1 秒，表示该月的最后一秒
                    break;
                case 5: // 季度
                    endCalendar.add(Calendar.MONTH, 3);
                    endCalendar.add(Calendar.SECOND, -1); // 减去 1 秒，表示该季度的最后一秒
                    break;
                case 6: // 年
                    endCalendar.add(Calendar.YEAR, 1);
                    endCalendar.add(Calendar.SECOND, -1); // 减去 1 秒，表示该年的最后一秒
                    break;
                default:
                    throw new IllegalArgumentException("Invalid cycle type: " + cycle);
            }

            Date cycleEndTime = endCalendar.getTime();

            if (cycleEndTime.after(endTime)) {

                cycleEndTime = endTime;
            }

            CycleLimitItem cycleItem = new CycleLimitItem();
            cycleItem.setCycleStartTime(cycleStartTime);
            cycleItem.setCycleEndTime(cycleEndTime);
            periods.add(cycleItem);

            switch (cycle) {
                case 2: // 天
                    calendar.add(Calendar.DAY_OF_MONTH, 1);
                    break;
                case 3: // 周
                    calendar.add(Calendar.WEEK_OF_YEAR, 1);
                    break;
                case 4: // 月
                    calendar.add(Calendar.MONTH, 1);
                    break;
                case 5: // 季度
                    calendar.add(Calendar.MONTH, 3);
                    break;
                case 6: // 年
                    calendar.add(Calendar.YEAR, 1);
                    break;
            }
        }

        return periods;
    }

}