package cn.com.victorysoft.business.sys.entity;

import cn.com.victorysoft.business.constant.DataType;
import cn.com.victorysoft.business.util.DateUtils;
import lombok.Data;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期范围
 */
@Data
public class DateRange {

    private Date start;
    private Date end;
    private String name;
    private DataType dataType;
    /**
     * 下级数据类型
     */
    private DataType dataTypeLower;

    public DateRange(Date startDate, Date endDate, String name, DataType dataType) {
        this.start = startDate;
        this.end = endDate;
        this.name = name;
        this.dataType = dataType;
    }

    public DateRange(Date date, DataType dataType) {
        this.dataType = dataType;

        Calendar calendar = Calendar.getInstance();
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        int year, month;
        switch (dataType) {
            case daily:
                startCalendar.setTime(date);
                setMinTime(startCalendar);
                this.start = startCalendar.getTime();

                endCalendar.setTime(date);
                setMaxTime(endCalendar);
                this.end = endCalendar.getTime();

                this.name = DateUtils.formatDate(date);
                break;
            case month:
                startCalendar.setTime(date);
                startCalendar.set(Calendar.DAY_OF_MONTH, 1);
                setMinTime(startCalendar);
                this.start = startCalendar.getTime();

                endCalendar.setTime(date);
                endCalendar.set(Calendar.DAY_OF_MONTH, endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                setMaxTime(endCalendar);
                this.end = endCalendar.getTime();

                this.dataTypeLower = DataType.daily;
                this.name = DateUtils.format(date, "yyyyMM");
                break;
            case quarter:
                startCalendar.setTime(date);
                startCalendar.set(Calendar.MONTH, (startCalendar.get(Calendar.MONTH) / 3) * 3);
                startCalendar.set(Calendar.DAY_OF_MONTH, 1);
                setMinTime(startCalendar);
                this.start = startCalendar.getTime();

                endCalendar.setTime(date);
                endCalendar.set(Calendar.MONTH, (startCalendar.get(Calendar.MONTH) / 3) * 3 + 2);
                endCalendar.set(Calendar.DAY_OF_MONTH, endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                setMaxTime(endCalendar);
                this.end = endCalendar.getTime();

                this.dataTypeLower = DataType.month;
                calendar.setTime(start);
                month = calendar.get(Calendar.MONTH);
                year = calendar.get(Calendar.YEAR);
                switch (month) {
                    case 0:
                        this.name = year + "-第一季度";
                        break;
                    case 3:
                        this.name = year + "-第二季度";
                        break;
                    case 6:
                        this.name = year + "-第三季度";
                        break;
                    case 9:
                        this.name = year + "-第四季度";
                        break;
                }
                break;
            case half_year:
                startCalendar.setTime(date);
                startCalendar.set(Calendar.MONTH, (startCalendar.get(Calendar.MONTH) / 6) * 6);
                startCalendar.set(Calendar.DAY_OF_MONTH, 1);
                setMinTime(startCalendar);
                this.start = startCalendar.getTime();

                endCalendar.setTime(date);
                endCalendar.set(Calendar.MONTH, (startCalendar.get(Calendar.MONTH) / 6) * 6 + 5);
                endCalendar.set(Calendar.DAY_OF_MONTH, endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                setMaxTime(endCalendar);
                this.end = endCalendar.getTime();

                this.dataTypeLower = DataType.quarter;
                calendar.setTime(start);
                month = calendar.get(Calendar.MONTH);
                year = calendar.get(Calendar.YEAR);
                switch (month) {
                    case 0:
                        this.name = year + "-上半年";
                        break;
                    case 6:
                        this.name = year + "-下半年";
                        break;
                }
                break;
            case year:
                startCalendar.setTime(date);
                startCalendar.set(Calendar.MONTH, 0);
                startCalendar.set(Calendar.DAY_OF_MONTH, 1);
                setMinTime(startCalendar);
                this.start = startCalendar.getTime();

                endCalendar.setTime(date);
                endCalendar.set(Calendar.MONTH, 11);
                endCalendar.set(Calendar.DAY_OF_MONTH, endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                setMaxTime(endCalendar);
                this.end = endCalendar.getTime();

                this.dataTypeLower = DataType.half_year;
                this.name = DateUtils.format(date, "yyyy");
                break;
        }
    }

    private static void setMinTime(Calendar calendar){
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
    }

    private static void setMaxTime(Calendar calendar){
        calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
        calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
        calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND));
    }

    @Override
    public String toString() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return "DateRange(start=" + sdf.format(start) + ", end=" + sdf.format(end) + ", name=" + name +
                ", dataType=" + dataType.name() + ", dataTypeLower=" + (dataTypeLower == null ? "null" : dataTypeLower.name()) + ")";
    }

}
