package com.aps.entity.basic;

import com.aps.entity.Algorithm.GAScheduleResult;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;

/**
 * 机器设备类
 * 用于表示生产系统中的机器设备，包含基本信息、工作时间、维护窗口等
 */
@Data
public class Machine {

    private long id;

    /**
     * 设备名称
     */
    private String name;

    /**
     * 最早可用时间，默认值：0
     */
    private int earliestTime=0;

    /**
     * 最后的任务，默认值：0
     */
    private GAScheduleResult lastGene=null;

    /**
     * 总任务时间
     */
    private double totalTaskTime=0;

    /**
     * 班次列表
     */
    private List<Shift> shifts;

    /**
     * 维护窗口列表
     */
    private List<MaintenanceWindow> maintenanceWindows;

    /**
     * 可用时间段列表（线程安全）
     */
    private CopyOnWriteArrayList<TimeSegment> availability;

    /**
     * 设备编码
     */
    private String code;
    /**
     * 设备类型
     *
     */
    private String capacityTypeName;

    /**
     * 节假日列表
     */
    private List<Holiday> holidays;

    /**
     * 实际工作时间
     */
    private double actualWorkTime;

    /**
     * 工作效率
     */
    private double rate;

    /**
     * 所属部门
     */
    private String department;

    /**
     * 班次变更事件回调
     */
    private Consumer<Void> shiftsChanged;

    /**
     * 维护窗口变更事件回调
     */
    private Consumer<Void> maintenanceWindowsChanged;


    public Machine() {
        this.shifts = new ArrayList<>();
        this.maintenanceWindows = new ArrayList<>();
        this.availability = new CopyOnWriteArrayList<>();
    }


    public Machine(int id, String name) {
        this();
        this.id = id;
        this.name = name;
    }


    public void addMaintenanceWindow(MaintenanceWindow window) {
        maintenanceWindows.add(window);
        if (maintenanceWindowsChanged != null) {
            maintenanceWindowsChanged.accept(null);
        }
    }


    public void addShift(Shift shift) {
        shifts.add(shift);
        if (shiftsChanged != null) {
            shiftsChanged.accept(null);
        }
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Machine machine = (Machine) o;
        return id == machine.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}
