package com.aps.entity.Algorithm;

import com.aps.common.util.FileHelper;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam;
import com.aps.entity.basic.Machine;
import com.aps.entity.basic.Material;
import com.aps.entity.basic.Order;
import lombok.Data;



import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * 作者：佟礼
 * 时间：2025-11-21
 */
@Data
public class Chromosome {

    private String ID = UUID.randomUUID().toString();

    private String generateType;

    private Integer version=0;

    /// <summary>
    /// 机器选择部分（可选机器集中的顺序号）
    /// </summary>
    private CopyOnWriteArrayList<Integer> machineSelection;

    // 缓存标记
    private transient boolean machineStrDirty = true;
    private transient boolean operationStrDirty = true;
    private transient boolean geneStrDirty = true;

    /// <summary>
    /// 工序排序部分（工件/订单ID）
    /// </summary>
    private String machineStr;

    /// <summary>
    /// 机器选择部分 + 工序排序部分
    /// </summary>
    private String geneStr;

    public String  getGeneStr() {
        if (geneStrDirty || machineStrDirty || operationStrDirty) {
            geneStr = getMachineStr() + "_" + getOperationStr();
            geneStrDirty = false;
        }
        return geneStr;
    }

    private Integer gsOrls=0;


    public String  getMachineStr() {
        if (machineStrDirty) {
            machineStr = Optional.ofNullable(machineSelection)
                    .orElse(new CopyOnWriteArrayList<>(Collections.emptyList()))
                    .stream()
                    .map(String::valueOf)
                    .collect(Collectors.joining(","));
            machineStrDirty = false;
            geneStrDirty = true;
        }
        return machineStr;
    }

    public String  getOperationStr() {
        if (operationStrDirty) {
            operationStr = Optional.ofNullable(operationSequencing)
                    .orElse(new CopyOnWriteArrayList<>(Collections.emptyList()))
                    .stream()
                    .map(String::valueOf)
                    .collect(Collectors.joining(","));
            operationStrDirty = false;
            geneStrDirty = true;
        }
        return operationStr;
    }

    // 重写 setter 方法，在设置时标记为脏
    public void setMachineSelection(CopyOnWriteArrayList<Integer> machineSelection) {
        this.machineSelection = machineSelection;
        this.machineStrDirty = true;
        this.geneStrDirty = true;
    }

    public void setOperationSequencing(CopyOnWriteArrayList<Integer> operationSequencing) {
        this.operationSequencing = operationSequencing;
        this.operationStrDirty = true;
        this.geneStrDirty = true;
    }




    /// <summary>
    /// 工序排序部分（工件/订单ID）
    /// </summary>
    private CopyOnWriteArrayList<Integer> operationSequencing;



    /// <summary>
    /// 工序排序部分（工件/订单ID）
    /// </summary>
    private String operationStr;





    private  CopyOnWriteArrayList<GlobalOperationInfo> globalOpList = new CopyOnWriteArrayList<>();
    private  CopyOnWriteArrayList<Entry> allOperations = new CopyOnWriteArrayList<>();
    private  CopyOnWriteArrayList<Order> orders = new CopyOnWriteArrayList<>();
    private  List<Machine> InitMachines = new ArrayList<>();

    private List<OrderMaterialRequirement> orderMaterials = new ArrayList<>();

    private CopyOnWriteArrayList<GroupResult> OperatRel = new CopyOnWriteArrayList<>();

    private ObjectiveWeights objectiveWeights;

    private GlobalParam globalParamSnapshot;

    private TreeMap<String, Material> materials = new TreeMap<>();

    // private List<Material> materials = new ArrayList<>();

    private  List<String> materialIds = new ArrayList<>();
    /*
     * 最早完工时间（最小化） 最小化总加工时间 最小总换型时间
     */
    private double[] Objectives = new double[0]; // 多目标值：[Makespan, TotalFlowTime, TotalChangeover, LoadStd, Delay]
    private double[] MaxObjectives = new double[0]; //
    private double[] MinObjectives = new double[0]; //
    private double[] weights = new double[0];
    /**
     * 各目标维度的理论下界（用于计算 Gap = (current - lowerBound) / lowerBound）。
     * 由 KpiLowerBoundCalculator 在 decode 后计算并填入。
     */
    private double[] LowerBoundObjectives = new double[0];
    private int Rank; // 非支配排序等级（1最优）
    private double CrowdingDistance =0; // 拥挤距离 越小越优
    /*
     *(Objectives - min) / (max - min);
     */
    private double[] WeightedObjectives = new double[0];//越靠近1越优
    private double WeightedObjective =0; // 加权目标值（用于自定义权重）

    /// <summary>
    /// 适应度值
    /// </summary>
    private double[] fitnessLevel = new double[0];

    /// <summary>
    /// 适应度值
    /// </summary>
    private double Fitness = 0.0;

    /// <summary>
    /// 机器
    /// </summary>
    private List<Machine> Machines = new ArrayList<>();

    /// <summary>
    /// 解码后的调度结果
    /// </summary>
    private CopyOnWriteArrayList<GAScheduleResult> Result = new CopyOnWriteArrayList<>();

    /// <summary>
    /// 解码后的调度结果
    /// </summary>
    private List<GAScheduleResult> ResultOld=new CopyOnWriteArrayList<>();

    /// <summary>
    /// 最早完工时间
    /// </summary>
    private double Makespan = 0.0;

    /// <summary>
    /// 总流程时间
    /// </summary>
    private double TotalFlowTime = 0.0;

    /// <summary>
    /// 总换型时间
    /// </summary>
    private double TotalChangeoverTime = 0.0;

    /// <summary>
    /// 机器负载标准差（越小越均衡）
    /// </summary>
    private double MachineLoadStd = 0.0;

    /// <summary>
    /// 交付期延迟时间
    /// </summary>
    private double DelayTime = 0.0;
    private double SemiJitSlack;

    private String ScenarioID = "";

    private String ScenarioName = "";
    private LocalDateTime BaseTime; // 当前基准时间

    private List<Integer> reOrderids=new ArrayList<>();

//
//    //最大设备利用率
//    private  double machineMaxRate;
//    //最小设备利用率
//    private  double machineMinRate;
////设备等待时长
//    private  double machineWaitTime;
//
//
////订单及时完成率
//    private  double orderOnTime;
//
//    //最大延迟
//    private  double orderMaxDelay;
//
//    //最小延迟
//    private  double orderMinDelay;
//
//    //平均延迟
//    private  double orderAvgDelay;
//
//    //最长生产周期
//    private  double orderMaxProductTime;
//
//    //最短生产周期
//    private  double orderMinProductTime;
//
//    //平均生产周期
//    private  double orderAvgProductTime;
//
//    //最大流量
//    private  double orderMaxFlow;
//
//    //最小流量
//    private  double orderMinFlow;
//
//    //平均流量
//    private  double orderAvgFlow;


    private  List<KpiMetrics> kpiMetrics;

    /**
     * 获取 Result 中工序ID不在 allOperations 里的调度结果列表
     *
     * @return 不在 allOperations 中的 GAScheduleResult 列表；若均存在则返回空列表
     */
    public List<GAScheduleResult> checkResultsNotInAllOperations1() {
        if (Result == null || Result.isEmpty()) {
            return Collections.emptyList();
        }
        if (allOperations == null || allOperations.isEmpty()) {
            return new ArrayList<>(Result);
        }
        Set<Integer> allOpIds = allOperations.stream()
                .map(com.aps.entity.basic.Entry::getId)
                .collect(Collectors.toSet());
        List<GAScheduleResult>  NotInAllOperations=  Result.stream()
                .filter(r -> !allOpIds.contains(r.getOperationId()))
                .collect(Collectors.toList());

        if(NotInAllOperations.size()>0)
        {
            FileHelper.writeLogFile("Result 中有工序ID不在 allOperations");
        }
        return  NotInAllOperations;
    }

    /**
     * 判断 Result 中是否存在工序ID不在 allOperations 里的调度结果
     *
     * @return 存在则返回 true，否则返回 false
     */
//    public boolean hasResultNotInAllOperations1() {
//      /  return !getResultsNotInAllOperations1().isEmpty();
//    }

    /**
     * LNS 需要：创建染色体的深拷贝（machineSelection 和 operationSequencing 独立副本）
     * 大对象（globalOpList / allOperations / orders / materials）共享引用
     */
    public Chromosome deepCopy() {
        Chromosome copy = new Chromosome();
        if (machineSelection != null) {
            copy.machineSelection = new CopyOnWriteArrayList<>(machineSelection);
            copy.machineStrDirty = true;
        }
        if (operationSequencing != null) {
            copy.operationSequencing = new CopyOnWriteArrayList<>(operationSequencing);
            copy.operationStrDirty = true;
        }
        copy.geneStrDirty = true;
        if (Objectives != null) copy.Objectives = Arrays.copyOf(Objectives, Objectives.length);
        if (WeightedObjectives != null) copy.WeightedObjectives = Arrays.copyOf(WeightedObjectives, WeightedObjectives.length);
        if (fitnessLevel != null) copy.fitnessLevel = Arrays.copyOf(fitnessLevel, fitnessLevel.length);
        if (LowerBoundObjectives != null) copy.LowerBoundObjectives = Arrays.copyOf(LowerBoundObjectives, LowerBoundObjectives.length);
        copy.WeightedObjective = WeightedObjective;
        copy.Makespan = Makespan;
        copy.TotalFlowTime = TotalFlowTime;
        copy.TotalChangeoverTime = TotalChangeoverTime;
        copy.MachineLoadStd = MachineLoadStd;
        copy.Fitness = Fitness;
        copy.Rank = Rank;
        copy.CrowdingDistance = CrowdingDistance;
        copy.gsOrls = gsOrls;
        copy.generateType = generateType + "_copy";
        copy.globalParamSnapshot = globalParamSnapshot;
        copy.objectiveWeights = objectiveWeights;
        copy.globalOpList = globalOpList;
        copy.allOperations = allOperations;
        copy.orders = orders;
        copy.InitMachines = InitMachines;
        copy.materials = materials;
        copy.materialIds = materialIds;
        copy.OperatRel = OperatRel;
        copy.orderMaterials = orderMaterials;
        copy.Machines = Machines;
        if (Result != null) copy.Result = new CopyOnWriteArrayList<>(Result);
        return copy;
    }

}
