package org.wcs.business.etag;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.wcs.business.redis.EtagRedis;
import org.wcs.constant.enums.database.EtagBusinessTypeEnum;
import org.wcs.constant.enums.database.EtagTaskLightModelEnum;
import org.wcs.constant.enums.database.EtagTaskStatusEnum;
import org.wcs.constant.enums.etag.LedBlinkingEnum;
import org.wcs.constant.enums.etag.LedColorEnum;
import org.wcs.mapper.intf.AppEtagTagInfoService;
import org.wcs.mapper.intf.AppEtagTaskService;
import org.wcs.model.bo.etag.EtagLightParams;
import org.wcs.model.po.app.AppEtagTagInfo;
import org.wcs.model.po.app.AppEtagTagLocation;
import org.wcs.model.po.app.AppEtagTask;
import org.wcs.utils.AppStringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 电子标签任务执行类
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class EtagTaskExecute {


    // 电子标签操作类
    private final EtagAtopOperation etagAtopOperation;
    // 电子标签任务服务
    private final AppEtagTaskService etagTaskService;
    // 电子标签小标签数据库服务
    private final AppEtagTagInfoService etagTagInfoService;
    // 电子标签Redis操作类
    private final EtagRedis etagRedis;

    /**
     * 点亮小标签
     */
    public void lightSmallTag() {
        lightImmediatelyTask(); // 点亮立即点亮的任务
        lightNeedFireTask(); // 点亮需要触发的任务
    }

    /**
     * 点亮立即点亮的任务
     */
    private void lightImmediatelyTask() {
        // 点亮立即点亮的任务
        AppEtagTask queryImmediatelyTask = new AppEtagTask();
        queryImmediatelyTask.setTaskStatus(EtagTaskStatusEnum.NOT_ACTIVATED.getCode());
        queryImmediatelyTask.setLightModel(EtagTaskLightModelEnum.IMMEDIATELY.getCode());
        List<AppEtagTask> immediatelyTaskList = etagTaskService.queryIgnoreNull(queryImmediatelyTask);
        if(immediatelyTaskList == null) {
            return;
        }
        if (immediatelyTaskList.isEmpty()) {
            return;
        }
        lightEtagTasks(immediatelyTaskList);
    }

    /**
     * 点亮需要触发的任务
     */
    private void lightNeedFireTask() {
        // 查找区域绑定好的载具信息
        Map<String, String> areaVehicleAll = etagRedis.getEtagAreaVehicleAll();
        for (Map.Entry<String, String> entry : areaVehicleAll.entrySet()) {
            String areaId = entry.getKey(); // 区域编号
            String vehicleNo = entry.getValue(); // 载具编号
            if(AppStringUtils.isEmpty(areaId) || AppStringUtils.isEmpty(vehicleNo)) {
                continue;
            }
            List<Integer> taskStatus = List.of(EtagTaskStatusEnum.NOT_ACTIVATED.getCode());
            List<AppEtagTask> appEtagTaskList = etagTaskService.queryByTagAreaIdAndVehicleAndStatus(areaId, vehicleNo, taskStatus);
            if(appEtagTaskList == null || appEtagTaskList.isEmpty()) {
                continue; // 查找任务失败或者没找到任务就继续下拨循环
            }
            lightEtagTasks(appEtagTaskList);
        }
    }

    /**
     * 点亮任务列表
     * @param appEtagTaskList 电子标签任务列表
     */
    private void lightEtagTasks(List<AppEtagTask> appEtagTaskList) {
        for (AppEtagTask etagTask : appEtagTaskList) {
            // 查找这个任务货位对应的标签信息
            AppEtagTagLocation appEtagTagLocation = etagRedis.getEtagLocation(etagTask.getLocation());
            if(appEtagTagLocation == null) {
                log.info("点亮标签任务：{}，时未找到货位：{} 的信息", etagTask.getTaskId(), etagTask.getLocation());
                AppEtagTask updateEtagTask = new AppEtagTask();
                updateEtagTask.setTaskId(etagTask.getTaskId());
                updateEtagTask.setTaskStatus(EtagTaskStatusEnum.ERROR.getCode());
                updateEtagTask.setCompletedTime(LocalDateTime.now());
                updateEtagTask.setRemark("未找到货位：" + etagTask.getLocation() + " 的信息");
                Integer result = etagTaskService.updateIgnoreNull(updateEtagTask).result();
                log.info("更新电子标签任务：{}，结果：{}，更新项：{}", updateEtagTask.getTaskId(), result, updateEtagTask);
                continue;
            }
            // 查找这个标签绑定的任务
            AppEtagTask etagTagTask = etagRedis.getEtagTagTask(appEtagTagLocation.getTagName());
            if(etagTagTask != null) {
                // 绑定了任务，说明标签还在亮着，得等按下完成
                continue;
            }
            // 查找这个标签名称对应的数据
            AppEtagTagInfo appEtagTagInfo = etagRedis.getEtagTag(appEtagTagLocation.getTagName());
            if(appEtagTagInfo == null) {
                log.info("点亮标签任务：{}，时未找到标签：{} 的信息", etagTask.getTaskId(), appEtagTagLocation.getTagName());
                AppEtagTask updateEtagTask = new AppEtagTask();
                updateEtagTask.setTaskId(etagTask.getTaskId());
                updateEtagTask.setTaskStatus(EtagTaskStatusEnum.ERROR.getCode());
                updateEtagTask.setCompletedTime(LocalDateTime.now());
                updateEtagTask.setRemark("未找到标签：" + appEtagTagLocation.getTagName() + " 的信息");
                Integer result = etagTaskService.updateIgnoreNull(updateEtagTask).result();
                log.info("更新电子标签任务：{}，结果：{}，更新项：{}", updateEtagTask.getTaskId(), result, updateEtagTask);
                continue;
            }
            // 点亮标签
            EtagLightParams lightParams = EtagLightParams.builder()
                    .tagName(appEtagTagInfo.getTagName())
                    .tagId(appEtagTagInfo.getTagId().byteValue())
                    .tagValue(String.valueOf(etagTask.getLightNum()))
                    .tagString(etagTask.getGoodsName() + "[" + etagTask.getGoodsId() + "]")
                    .ledBlinking(LedBlinkingEnum.BLINKING_0_25)
                    .ledColor(LedColorEnum.ORANGE)
                    .build();
            String lightTagResult = etagAtopOperation.lightTag(lightParams);
            log.info("点亮电子标签: {}，点亮参数：{}，点亮结果：{}", appEtagTagLocation.getTagName(), lightParams, lightTagResult);
            if(AppStringUtils.isEmpty(lightTagResult)) {
                etagRedis.setEtagTagTask(appEtagTagLocation.getTagName(), etagTask); // 点亮成功，将任务绑定到标签
                // 更新任务状态
                AppEtagTask updateEtagTask = new AppEtagTask();
                updateEtagTask.setTaskId(etagTask.getTaskId());
                updateEtagTask.setTaskStatus(EtagTaskStatusEnum.LIGHTING.getCode());
                updateEtagTask.setLightTime(LocalDateTime.now());
                Integer result = etagTaskService.updateIgnoreNull(updateEtagTask).result();
                log.info("更新电子标签任务：{}，结果：{}，更新项：{}", updateEtagTask.getTaskId(), result, updateEtagTask);
            }
        }
    }

    /**
     * 点亮和熄灭通道灯
     */
    public void lightTunnelLight() {
        AppEtagTagInfo queryLightTag = new AppEtagTagInfo();
        queryLightTag.setBusinessType(EtagBusinessTypeEnum.TUNNEL_LIGHT.getCode());
        List<AppEtagTagInfo> etagTagInfoList = etagTagInfoService.queryIgnoreNull(queryLightTag); // 所有的通道灯数据
        if(etagTagInfoList == null || etagTagInfoList.isEmpty()) {
            return;
        }
        List<EtagLightParams> lightParamsList = new ArrayList<>(); // 各个通道灯的点亮参数
        // 遍历所有通道灯，获取各个通道灯的标签名称，检查其是否有绑定的任务
        for (AppEtagTagInfo etagTagInfo : etagTagInfoList) {
            AppEtagTagInfo queryTunnelEtag = new AppEtagTagInfo();
            queryTunnelEtag.setTunnelNo(etagTagInfo.getTunnelNo());
            List<AppEtagTagInfo> tunnelEtagTagInfoList = etagTagInfoService.queryIgnoreNull(queryTunnelEtag);
            if(tunnelEtagTagInfoList == null) {
                continue;
            }
            boolean existTask = false; // 是否存在任务
            for (AppEtagTagInfo tunnelEtagTagInfo : tunnelEtagTagInfoList) {
                existTask = etagRedis.existsEtagTagTask(tunnelEtagTagInfo.getTagName());
                if(existTask) {
                    break; // 存在一个任务即视为存在，直接跳出
                }
            }
            EtagLightParams lightParams; // 点亮参数
            if(existTask) {
                lightParams = EtagLightParams.builder()
                        .tagName(etagTagInfo.getTagName())
                        .tagId(etagTagInfo.getTagId().byteValue())
                        .ledBlinking(LedBlinkingEnum.LED_ON)
                        .ledColor(LedColorEnum.GREEN)
                        .build();
            } else {
                lightParams = EtagLightParams.builder()
                        .tagName(etagTagInfo.getTagName())
                        .tagId(etagTagInfo.getTagId().byteValue())
                        .ledBlinking(LedBlinkingEnum.LED_OFF)
                        .ledColor(LedColorEnum.GREEN)
                        .build();
            }
            lightParamsList.add(lightParams);
        }
        // 执行点亮或者熄灭动作
        for (EtagLightParams lightParamsItem : lightParamsList) {
            etagAtopOperation.lightTag(lightParamsItem);
        }
    }


    /**
     * 点亮汇总标签
     */
    public void lightSummaryTag() {
        AppEtagTagInfo querySummaryTag = new AppEtagTagInfo();
        querySummaryTag.setBusinessType(EtagBusinessTypeEnum.AREA.getCode());
        List<AppEtagTagInfo> etagTagInfoList = etagTagInfoService.queryIgnoreNull(querySummaryTag); // 所有的区域标签数据
        if(etagTagInfoList == null || etagTagInfoList.isEmpty()) {
            return;
        }
        List<EtagLightParams> lightParamsList = new ArrayList<>(); // 各个区域标签的点亮参数
        for (AppEtagTagInfo etagTagInfo : etagTagInfoList) {
            String etagAreaVehicle = etagRedis.getEtagAreaVehicle(etagTagInfo.getAreaId());
            if(AppStringUtils.isEmpty(etagAreaVehicle)) {
                // 没有绑定的载具了
                lightParamsList.add(EtagLightParams.builder().tagName(etagTagInfo.getTagName())
                        .tagId(etagTagInfo.getTagId().byteValue()).tagValue("0").tagString("无任务")
                        .ledBlinking(LedBlinkingEnum.LED_OFF).ledColor(LedColorEnum.GREEN).build());
                continue;
            }
            // 还有绑定的载具
            List<Integer> notCompletedTaskStatus = Arrays.asList(EtagTaskStatusEnum.NOT_ACTIVATED.getCode(), EtagTaskStatusEnum.LIGHTING.getCode());
            // 检查这个载具有没有完成所有的任务
            List<AppEtagTask> allEtagTaskList = etagTaskService.queryByVehicleAndStatus(etagAreaVehicle, notCompletedTaskStatus);
            if(allEtagTaskList == null) {
                continue; // 查询数据库失败
            }
            if(allEtagTaskList.isEmpty()) {
                lightParamsList.add(EtagLightParams.builder().tagName(etagTagInfo.getTagName())
                        .tagId(etagTagInfo.getTagId().byteValue()).tagValue("0").tagString("全部完成：" + etagAreaVehicle)
                        .ledBlinking(LedBlinkingEnum.LED_OFF).ledColor(LedColorEnum.GREEN).build());
                continue;
            }
            // 检查这个区域还有没有这个载具的任务
            List<AppEtagTask> thisAreaEtagTaskList = etagTaskService.queryByTagAreaIdAndVehicleAndStatus(etagTagInfo.getAreaId(), etagAreaVehicle, notCompletedTaskStatus);
            if(thisAreaEtagTaskList == null) {
                continue; // 查询数据库失败
            }
            if(thisAreaEtagTaskList.isEmpty()) {
                lightParamsList.add(EtagLightParams.builder().tagName(etagTagInfo.getTagName())
                        .tagId(etagTagInfo.getTagId().byteValue()).tagValue("0").tagString("任务完成：" + etagAreaVehicle)
                        .ledBlinking(LedBlinkingEnum.LED_ON).ledColor(LedColorEnum.BLUE).build());
                continue;
            }
            // 正在捡选的情况
            lightParamsList.add(EtagLightParams.builder().tagName(etagTagInfo.getTagName())
                    .tagId(etagTagInfo.getTagId().byteValue()).tagValue(String.valueOf(thisAreaEtagTaskList.size())).tagString("正在捡选：" + etagAreaVehicle)
                    .ledBlinking(LedBlinkingEnum.LED_ON).ledColor(LedColorEnum.ORANGE).build());
        }
        // 执行点亮或者熄灭动作
        for (EtagLightParams lightParamsItem : lightParamsList) {
            etagAtopOperation.lightTag(lightParamsItem);
        }
    }



}
