package cn.ibizlab.core.extensions.dto;

import cn.ibizlab.core.analysis.domain.DAMetric;
import cn.ibizlab.util.dict.Catalog;
import cn.ibizlab.util.dict.CodeItem;
import cn.ibizlab.util.dict.Option;
import cn.ibizlab.util.helper.DataObject;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
public class FetchParam {

    @JsonIgnore
    @JSONField(serialize = false)
    private String id;

    @JsonIgnore
    @JSONField(serialize = false)
    public String getId() {
        if(StringUtils.isEmpty(id))
        {
            String str = "FetchParam{" +
                    "reportId='" + reportId + '\'' +
                    ", chartId='" + chartId + '\'' +
                    ", buildId='" + buildId + '\'' +
                    ", displayType='" + displayType + '\'' +
                    ", dimDict='" + dimDict + '\'' +
                    ", dimValues=" + dimValues +
                    ", dimItems=" +  JSONObject.toJSONString(dimItems)+
                    ", domains=" +  JSONObject.toJSONString(getDomains())+
                    ", dimValue='" + dimValue + '\'' +
                    ", includeChild=" + includeChild +
                    ", metricIds=" + metricIds +
                    ", metricId='" + metricId + '\'' +
                    ", startTime=" + startTime +
                    ", endTime=" + endTime +
                    ", page=" + page +
                    ", size=" + size +
                    ", total=" + total +
                    ", group='" + group + '\'' +
                    '}';
            id = DigestUtils.md5DigestAsHex(str.getBytes());
        }
        return id;
    }

    private String reportId;
    private String chartId;
    private String buildId;

    private String title;

    // 表格展示类型：1.  default（维度数据以行的形式展示），2.  LIST_BOX（维度数据以列的形式展示）
    private String displayType = "default";


    private String dimDict;
    private List<String> dimValues;
    private String dimValue;
    private boolean includeChild = true;

    private List<String> metricIds;
    private String metricId;

    private List<String> domains;

    private String domain;

    public List<String> getDomains() {
        if(ObjectUtils.isEmpty(domains) && domain!=null) {
            domains = new ArrayList<>();
            domains.add(domain);
        }
        return domains;
    }

    public String getDomain() {
        if(domain==null && !ObjectUtils.isEmpty(domains)) {
            domain = domains.get(0);
        }
        return domain;
    }

    @JsonFormat(pattern = "yyyy-MM-dd", locale = "zh", timezone = "GMT+8")
    @JSONField(name = "startTime", format = "yyyy-MM-dd")
    private Timestamp startTime;
    @JsonFormat(pattern = "yyyy-MM-dd", locale = "zh", timezone = "GMT+8")
    @JSONField(name = "endTime", format = "yyyy-MM-dd")
    private Timestamp endTime;

    private int page = 0;
    private int size = 1000;
    private int total = 0;

    private boolean filled = false;

    public List<String> getDimValues()
    {
        if(dimValues == null&&(!includeChild)&&(!StringUtils.isEmpty(dimValue)))
        {
            dimValues = new ArrayList<>();
            dimValues.add(dimValue);
        }
        return dimValues;
    }

    public List<String> getMetricIds()
    {
        if(metricIds == null)
        {
            metricIds = new ArrayList<>();
            if(!StringUtils.isEmpty(metricId))
                metricIds.add(metricId);
        }
        return metricIds;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    private Catalog dict;

    private List<Option> dimItems;

    @JsonIgnore
    @JSONField(serialize = false)
    private Option dimItem;
    @JsonIgnore
    @JSONField(serialize = false)
    public Option getDimItem()
    {
        return dimItem;
    }
    @JsonIgnore
    @JSONField(serialize = false)
    public FetchParam setDimItem(Option dimItem)
    {
        this.dimItem = dimItem;
        return this;
    }


    @JsonIgnore
    @JSONField(serialize = false)
    private Map<String,Set<String>> dimTables;
    @JsonIgnore
    @JSONField(serialize = false)
    public Map<String,Set<String>> getDimTables()
    {
        if(dimTables==null)
            dimTables = new LinkedHashMap<>();
        return dimTables;
    }
    @JsonIgnore
    @JSONField(serialize = false)
    public FetchParam setDimTables(Map<String, Set<String>> dimTables)
    {
        this.dimTables = dimTables;
        return this;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    private Map<String, DAMetric> metrics;
    @JsonIgnore
    @JSONField(serialize = false)
    public Map<String,DAMetric> getMetrics()
    {
        if(metrics==null)
            metrics = new LinkedHashMap<>();
        return metrics;
    }
    @JsonIgnore
    @JSONField(serialize = false)
    public FetchParam setMetrics(Map<String,DAMetric> metrics)
    {
        this.metrics = metrics;
        return this;
    }

    public Timestamp getStartTime() {
        if(startTime!=null)
        {
            try {
                return new Timestamp(DataObject.dayFormat.parse(DataObject.dayFormat.format(startTime)).getTime());
            } catch (Exception exception) {
            }
        }
        return getDefaultStartTimestamp();
    }

    public Timestamp getEndTime() {
        if(endTime!=null)
        {
            try {
                return new Timestamp(DataObject.datetimeFormat.parse(DataObject.dayFormat.format(endTime)+" 23:59:59").getTime());
            } catch (Exception exception) {
            }
        }
        return getDefaultEndTimestamp();
    }


    @JsonIgnore
    @JSONField(serialize = false)
    private List<VMConfig> vmConfigs;


    @JsonIgnore
    @JSONField(serialize = false)
    private String group;


    public static Timestamp getDefaultStartTimestamp() {
        Calendar c = Calendar.getInstance();
        Date d=new Date();
        try {
            d = DataObject.dayFormat.parse(DataObject.dayFormat.format(d));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        c.setTime(d);
        c.add(Calendar.MONTH, -1);

        c.set(Calendar.DAY_OF_MONTH, 1);

        return new Timestamp(c.getTime().getTime());
    }

    public static Timestamp getDefaultEndTimestamp() {
        Calendar c = Calendar.getInstance();
        Date d=new Date();
        try {
            d = DataObject.dayFormat.parse(DataObject.dayFormat.format(d)+" 23:59:59");
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        c.setTime(d);
        int month=c.get(Calendar.MONTH);
        c.set(Calendar.MONTH, month-1);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        return new Timestamp(c.getTime().getTime());
    }

    public static Timestamp getLastYear(Timestamp time)
    {
        Date date=new Date(time.getTime());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 设置为当前时间
        calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 1);
        // 设置为上一年
        date = calendar.getTime();

        Timestamp rt=new Timestamp(date.getTime());
        return rt;
    }

    public static Timestamp getLastMonth(Timestamp time)
    {

        Date date=new Date(time.getTime());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 设置为当前时间
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
        // 设置为上一个月
        date = calendar.getTime();

        Timestamp rt=new Timestamp(date.getTime());
        return rt;
    }


}
