package com.purui.prims.common.pojo;

import com.purui.prims.common.pojo.enums.TimeDimensionEnum;
import com.purui.prims.common.util.DateUtils;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

import static java.time.LocalDate.now;

@Data
public class DateConf {

    private static final long serialVersionUID = 3074129990945004340L;


    @ApiModelProperty(value = "日期模式")
    private DateMode dateMode = DateMode.RECENT;

    /**
     * like 2021-10-22, dateMode=1
     */
    @ApiModelProperty(value = "开始日期")
    private String startDate = now().plusDays(-1).toString();

    @ApiModelProperty(value = "结束日期")
    private String endDate = now().toString();

    /**
     * [2021-10-22, 2022-01-22], dateMode=2
     */
    @ApiModelProperty(value = "日期列表")
    private List<String> dateList = new ArrayList<>();

    /**
     * the last unit time unit,
     * such as the last 7 days, unit = 7
     */
    @ApiModelProperty(value = "单位")
    private Integer unit = 1;

    /**
     * DAY,WEEK,MONTH
     */
    @ApiModelProperty(value = "统计周期")
    private String period = Constants.DAY;

    /**
     * the text parse from , example "last 7 days" , "last mouth"
     */
    @ApiModelProperty(value = "检测文本")
    private String detectWord;

    @ApiModelProperty(value = "是否继承")
    private boolean isInherited;

    @ApiModelProperty(value = "是否按日期分组")
    private boolean groupByDate;

    public List<String> getDateList() {
        if (!CollectionUtils.isEmpty(dateList)) {
            return dateList;
        }
        String startDateStr = getStartDate();
        String endDateStr = getEndDate();
        return DateUtils.getDateList(startDateStr, endDateStr, getPeriod());
    }

    /**
     * 区分group by的维度和查询维度，存在按月份进行汇总，但查询条件为近N年的情况
     */
    public String getGroupByTimeDimension() {
        switch (period.toUpperCase(Locale.ROOT)) {
            case Constants.WEEK:
                return TimeDimensionEnum.WEEK.getName();
            case Constants.MONTH:
                return TimeDimensionEnum.MONTH.getName();
            case Constants.YEAR:
                return TimeDimensionEnum.YEAR.getName();
            default:
                return TimeDimensionEnum.DAY.getName();
        }

    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        DateConf dateConf = (DateConf) o;
        return dateMode == dateConf.dateMode
               && Objects.equals(startDate, dateConf.startDate)
               && Objects.equals(endDate, dateConf.endDate)
               && Objects.equals(unit, dateConf.unit)
               && Objects.equals(period, dateConf.period);
    }

    @Override
    public int hashCode() {
        return Objects.hash(dateMode, startDate, endDate, unit, period);
    }

    public enum DateMode {
        /**
         * date mode
         * 1 - BETWEEN, continuous static value, [startDate, endDate]
         * 2 - LIST, discrete static value, [dateList]
         * 3 - RECENT, dynamic time related to the actual available time of the element, [unit, period]
         * 4 - AVAILABLE, dynamic time which guaranteed to query some data, [startDate, endDate]
         * 5 - IGNORE , ignore the date
         */
        BETWEEN, LIST, RECENT, AVAILABLE, IGNORE
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("{");
        sb.append("\"dateMode\":")
          .append(dateMode);
        sb.append(",\"startDate\":\"")
          .append(startDate).append('\"');
        sb.append(",\"endDate\":\"")
          .append(endDate).append('\"');
        sb.append(",\"dateList\":")
          .append(dateList);
        sb.append(",\"unit\":")
          .append(unit);
        sb.append(",\"period\":\"")
          .append(period).append('\"');
        sb.append(",\"text\":\"")
          .append(detectWord).append('\"');
        sb.append('}');
        return sb.toString();
    }
}
