package com.ximai.mes.pro.schedule.strategy;

import com.ximai.mes.pro.domain.proWorkOrder.ProWorkorder;
import com.ximai.mes.pro.schedule.IOperationTimeCalculator;
import com.ximai.mes.pro.schedule.JobExtent;
import com.ximai.mes.pro.schedule.Task;
import com.ximai.mes.pro.schedule.TaskSchedulingContext;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 产能评估-换型规则
 * 根据排产换型规则表的顺序号
 * 当前设备任务规则（工序+类别）
 * 不存在返回：0
 * 存在换型规则
 *	当前设备任务工单规则值 匹配 当前设备上个任务工单规则值
 *	匹配上的优先级越高、属性越多、打分越高
 */
@Component
public class EvaluateEquipmentChangeOver implements EvaluateEquipment{

    @Override
    public double evaluate(TaskSchedulingContext context, IOperationTimeCalculator.OperationTimePlan operationTimePlan
            , List<TaskSchedulingContext.TaskSchedulingResultContext> scheduleResult) {
        //获取交期最晚工单
        List<ProWorkorder> workorderList = context.getJob().getJobExtend().getWorkorderList()
                .stream().sorted(Comparator.comparing(ProWorkorder::getRequestDate)).collect(Collectors.toList());
        ProWorkorder workorder = workorderList.get(workorderList.size()-1);
        JobExtent jobExtent = context.getJob().getJobExtend();
        String processName = context.getTask().getProcessName();
        //根据当前任务工序、产品类别查找换型规则
        //当前任务换型规则
        Map<String, Integer> setupRuleMap = jobExtent.getSetupRuleMap().get(workorder.getWorkorderId()+processName);
        if(setupRuleMap==null){
            return 0;
        }
        //当前任务工单换型属性值
        Map<String, Object> setupRuleValsCur = jobExtent.getSetupRuleValsCur().get(workorder.getWorkorderId()+processName);
        //设备上个任务工单换型属性值
        List<Task> taskList = context.getEquipment().getScheduleTask().stream()
                .sorted(Comparator.comparing(Task::getScheduledEndedTime)).collect(Collectors.toList());
        if(taskList.isEmpty()){
            return 0;
        }
        Task newestTask = taskList.get(taskList.size()-1);
        List<ProWorkorder> preWorkorderList = newestTask.getJob().getJobExtend().getWorkorderList()
                .stream().sorted(Comparator.comparing(ProWorkorder::getRequestDate)).collect(Collectors.toList());
        ProWorkorder preWorkorder = preWorkorderList.get(preWorkorderList.size()-1);
        Map<String, Object> setupRuleValsPre = newestTask.getJob().getJobExtend().getSetupRuleValsCur().get(preWorkorder.getWorkorderId()+newestTask.getProcessName());
        if(setupRuleValsPre==null||setupRuleValsCur==null){
            return 0.0;
        }
        return calculateScore(setupRuleMap, setupRuleValsCur, setupRuleValsPre);
    }

    /*
    计算得分
     */
    private double calculateScore(Map<String, Integer> setupRuleMap, Map<String, Object> setupRuleValsCur,
                             Map<String, Object> setupRuleValsPre){
        AtomicReference<Integer> totalScore = new AtomicReference<>(0);//总优先数值
        //公式=(5-L1)+(5-L2).../5N*10
        //L1\L2...
        //计算总分
        setupRuleMap.forEach((k,v)->{
            totalScore.updateAndGet(v1 -> v1 + 5);
        });
        //总评分
        AtomicReference<Integer> score = new AtomicReference<>(0);//总优先数值
        setupRuleMap.forEach((k,v)->{
            if(setupRuleValsCur.get(k)==null&&setupRuleValsPre.get(k)==null){
                score.updateAndGet(v1 -> v1 + (5-v));
            }
            if(setupRuleValsCur.get(k)!=null&&setupRuleValsPre.get(k)!=null &&
                    setupRuleValsCur.get(k).equals(setupRuleValsPre.get(k))){
                score.updateAndGet(v1 -> v1 + (5-v));
            }
        });
        //转换得分范围1-5，最终得分=总得分/总分*10
        return Double.valueOf(score.get()) / totalScore.get() * 10;
    }

    @Override
    public int weight() {
        return 1;
    }


}
