package com.zc.business.domain;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zc.business.enums.TrafficDataPeriodTypeEnum;
import lombok.Data;
import org.apache.commons.codec.digest.DigestUtils;

import java.util.Date;
import java.util.Objects;

/**
 * 交通断面数据统计定义
 * @author xiepufeng
 */
@Data
public class DcTrafficSectionData {

    /**
     * 主键
     */
    @TableId
    private String id;

    /**
     * 车流量
     */
    private Integer trafficVolume;

    /**
     * 平均速度
     */
    private Integer averageSpeed;

    /**
     * 所属设备
     */
    private Long deviceId;

    /**
     * 统计时间
     */
    private Date statisticalDate;

    /**
     * 上报时间
     */
    @TableField(exist = false)
    private Date reportTime;

    /**
     * 道路方向
     */
    private Byte direction;

    /**
     * 时段类型
     * 1-年 2-月 3-季 4-日
     */
    private Byte periodType;


    /**
     * 所在桩号
     */
    private Integer stakeMark;


    /** 创建时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private Date createTime;


    /** 更新时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private Date updateTime;

    /**
     * 设置交通数据的统计周期类型。
     * @param periodType 统计周期类型的枚举值。
     */
    public void setPeriodType(TrafficDataPeriodTypeEnum periodType) {
        this.periodType = periodType.getCode(); // 将枚举类型转换为代码值存储
    }


    /**
     * 重写equals方法,用于比较两个对象是否相等。
     * @param o 要与当前对象比较的对象。
     * @return 如果两个对象相等,则返回true;否则返回false。
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true; // 同一对象比较,直接返回true
        if (o == null || getClass() != o.getClass()) return false; // 对象为空或类型不同,返回false
        DcTrafficSectionData that = (DcTrafficSectionData) o; // 类型转换
        return Objects.equals(deviceId, that.deviceId) &&
                Objects.equals(reportTime, that.reportTime) &&
                Objects.equals(direction, that.direction) &&
                Objects.equals(periodType, that.periodType) &&
                Objects.equals(stakeMark, that.stakeMark); // 比较各属性值
    }

    /**
     * 重写hashCode方法,基于对象的属性生成哈希码。
     * @return 对象的哈希码值。
     */
    @Override
    public int hashCode() {
        return Objects.hash(deviceId, reportTime, direction, periodType, stakeMark);
    }

    /**
     * 根据给定的统计周期类型和日期,设置统计日期为相应周期的起始日期。
     * @param statisticalDate 原始统计日期。
     * @param typeEnum 统计周期类型。
     */
    public void setStatisticalDate(Date statisticalDate, TrafficDataPeriodTypeEnum typeEnum) {
        switch (typeEnum) {
            case DAY:
                // 设置为当天的起始时间
                this.statisticalDate = DateUtil.beginOfDay(statisticalDate);
                break;
            case MONTH:
                // 设置为当月的起始日期
                this.statisticalDate = DateUtil.beginOfMonth(statisticalDate);
                break;
            case QUARTER:
                // 设置为当季度的起始日期
                this.statisticalDate = DateUtil.beginOfQuarter(statisticalDate);
                break;
            case YEAR:
                // 设置为当年的起始日期
                this.statisticalDate = DateUtil.beginOfYear(statisticalDate);
                break;
            default:
                // 如果不是预定义的周期类型,则不做任何处理
                this.statisticalDate = statisticalDate;
            }
    }

    /**
     * 根据设备ID、上报时间、方向、时段类型、桩号生成一个唯一ID
     */
    public void generateUniqueId() {
        String combinedAttributes = deviceId + "_" + DateUtil.format(reportTime, "yyyyMMdd_HHmmss") + "_" + direction + "_" + periodType + "_" + stakeMark;
        this.id = DigestUtils.md5Hex(combinedAttributes);
    }

}