package com.youchain.timingtask.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.youchain.appupdate.inputJson.FullStockOut;
import com.youchain.appupdate.inputJson.PointCallStock;
import com.youchain.appupdate.rest.SceneAppController;
import com.youchain.appupdate.rest.XyjAppController;
import com.youchain.basicdata.domain.Item;
import com.youchain.basicdata.domain.Point;
import com.youchain.basicdata.domain.Stock;
import com.youchain.basicdata.service.ItemService;
import com.youchain.basicdata.service.PointService;
import com.youchain.basicdata.service.StockService;
import com.youchain.basicdata.service.ZcjxbService;
import com.youchain.basicdata.service.dto.ZcjxbDto;
import com.youchain.basicdata.service.mapstruct.ZcjxbMapper;
import com.youchain.businessdata.domain.AgvTask;
import com.youchain.businessdata.domain.Inventory;
import com.youchain.businessdata.domain.PickDetail;
import com.youchain.businessdata.domain.Task;
import com.youchain.businessdata.repository.AgvTaskRepository;
import com.youchain.businessdata.service.*;
import com.youchain.exception.handler.ApiResult;
import com.youchain.modules.system.service.DictService;
import com.youchain.timingtask.service.ZCJXBService;
import com.youchain.utils.AreaNameDic;
import com.youchain.utils.BaseStatus;
import com.youchain.utils.BizStatus;
import com.youchain.utils.RedisUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;

import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.OK;

@Slf4j
@Service
@RequiredArgsConstructor
public class ZCJXBServiceImpl implements ZCJXBService {
    //轴承座的操作
    private final PointService pointService;
    private final ItemService itemService;


    private final StockService stockService;

    private final DictService dictService;
    private final PickDetailService pickDetailService;
    private final AgvTaskService agvTaskService;
    private final AgvTaskRepository agvTaskRepository;
    private final TaskService taskService;
    private final InventoryService inventoryService;
    private final RedisUtils redisUtils;


    @Override
    public boolean zcJxbFKC(ZcjxbDto zcjxbDto) {//返空车
        //判断该点位是否有任务
        List<AgvTask> startTask = agvTaskRepository.findStartTask(zcjxbDto.getModbusTcpPoint());
        if (!startTask.isEmpty()) {
            log.error("{}该点位已有任务", zcjxbDto.getModbusTcpPoint());
            redisUtils.set("fkcData", zcjxbDto.getModbusTcpPoint() + "该点位已有任务");
            return false;
        }
        PointCallStock pointCallStock = new PointCallStock();
        pointCallStock.setAgvScene("ZC");
        pointCallStock.setPointCode(zcjxbDto.getModbusTcpPoint());
        //发任务
        //空车入库
        if (this.pointStockBack(pointCallStock)) {
            log.info("空车返回成功");
        } else {
            log.error("反空车失败");
            return false;
        }
        return true;
    }

    @Override
    public boolean zcJxbJMC(ZcjxbDto zcjxbDto) {//叫满车
        //判断点位是否有任务
        List<AgvTask> endTask = agvTaskRepository.findEndTask(zcjxbDto.getModbusTcpPoint());
        if (!endTask.isEmpty()) {
            log.error("{}该点位已有任务", zcjxbDto.getModbusTcpPoint());
            redisUtils.set("jlData", zcjxbDto.getModbusTcpPoint() + "该点位已有任务");
            return false;
        }
        FullStockOut fullStockOut = new FullStockOut();
        fullStockOut.setItemCode(zcjxbDto.getModbusTcpItem());
        fullStockOut.setPointCode(zcjxbDto.getModbusTcpPoint());
        fullStockOut.setAgvScene("ZC");
        //发任务
        if (this.fullStockOut(fullStockOut)) {
            log.info("成功叫料");
        } else {
            log.error("叫料失败");
            return false;
        }
        return true;
    }

    public boolean pointStockBack(PointCallStock pointCallStock) {//空车入库
        String pointCode = pointCallStock.getPointCode();
        String agvScene = pointCallStock.getAgvScene();
        String srcAreaName = null;
        String endAreaName = null;
        if (agvScene.equals(BizStatus.ZC)) {
            srcAreaName = AreaNameDic.ZCJXB;
            endAreaName = AreaNameDic.ZCK;
        }
        Point srcPoint = pointService.getPoint(pointCode, null, null, srcAreaName);
        if (srcPoint == null) {
            log.error(pointCode + "点位不存在!");
            redisUtils.set("fkcData", pointCode + "点位不存在!");
            return false;
        }
        Stock st = stockService.findByPointCode(srcPoint.getCode());
        String stockCode = null;
        if (st != null) {
            stockCode = st.getCode();
        } else {
            log.error(srcPoint.getCode() + "对应点位无容器!");
            redisUtils.set("fkcData", srcPoint.getCode() + "对应点位无容器!");
            return false;
        }
        //查找空车区是否点位
        Point endPoint = pointService.getPointByFree(endAreaName, null);
        if (endPoint == null) {
            log.error("轴承座空车区没有空闲点位!");
            redisUtils.set("fkcData", "轴承座空车区没有空闲点位!");
            return false;
        }
        //生成搬运任务
        AgvTask agvTask = new AgvTask(BizStatus.EMPTY_IN, stockCode, srcPoint.getCode(), endPoint.getCode(), BizStatus.OPEN, "RACK_MOVE");
        agvTaskService.create(agvTask);
        String code = "0";
        String message = null;
        String agv_on_off = "OFF";
        agv_on_off = dictService.getDictDescription("agv_on_off") == null ? "OFF" : dictService.getDictDescription("agv_on_off").getDescription();
        if (agv_on_off.equals("ON")) {
            String resultJson = agvTaskService.sendAgvTaskImpl(agvTask);//发送任务
            JSONObject resulObject = JSON.parseObject(resultJson);
            code = resulObject.getString("code") == null ? "" : resulObject.getString("code");
            message = resulObject.getString("message") == null ? "" : resulObject.getString("message");
        }
        if (code.equals("0")) {
            endPoint.setStatus(BaseStatus.USED);
            pointService.update(endPoint);
        } else {
            log.error("kuka返回报错:{}", message);
            redisUtils.set("fkcData", "kuka返回报错:" + message);
            return false;
        }
        return true;
    }

    public boolean fullStockOut(FullStockOut bi) {//满车出库
        String itemCode = bi.getItemCode();
        String pointCode = bi.getPointCode();
        String agvScene = bi.getAgvScene();
        int checkCode = bi.getCheckCode();
        String agv_on_off = "OFF";
        agv_on_off = dictService.getDictDescription("agv_on_off") == null ? "OFF" : dictService.getDictDescription("agv_on_off").getDescription();
        String endArea = "";
        String srcArea = "";
        Item item = itemService.existItem(itemCode);
        if (item == null) {
            log.error("【{}】物料不存在!", itemCode);
            redisUtils.set("jlData", itemCode + "物料不存在!");
            return false;
        }
        if (agvScene.equals(BizStatus.ZC)) {
            if (!item.getGoodType().equals(BizStatus.ZC)) {
                log.error("【{}】物料不属于轴承座!", agvScene);
                redisUtils.set("jlData", agvScene + "物料不属于轴承座!");
                return false;
            }
            endArea = AreaNameDic.ZCJXB;
            srcArea = AreaNameDic.ZCM;
        }
        Point endPoint = pointService.getPoint(pointCode, null, null, endArea);
        if (endPoint == null) {
            log.error(pointCode + "点位错误!");
            redisUtils.set("jlData", "点位错误!");
            return false;
        } else if (endPoint.getStatus().equals(BaseStatus.USED)) {
            log.error(pointCode + "点位被占用!");
            redisUtils.set("jlData", "点位被占用!");
            return false;
        }
        List<Inventory> inventoryList = inventoryService.queryInventory(item.getId());
        if (inventoryList.size() == 0) {
            log.error(itemCode + "无库存!");
            redisUtils.set("jlData", itemCode + "无库存!");
            return false;
        } else {
            PickDetail pickDetail = pickDetailService.createPickDetail(item, null);
            try {
                pickDetailService.allocateAll(pickDetail.getId(), endPoint);
            } catch (Exception e) {
                log.error(e.getMessage());
                return false;
            }
            List<Task> taskList = taskService.getPickNotAllTask(pickDetail.getId());
            AgvTask agvTask = taskList.get(0).getAgvTask();
            String code = "0";
            String message = null;
            if (agv_on_off.equals("ON")) {
                String resultJson = agvTaskService.sendAgvTaskImpl(agvTask);//发送任务
                JSONObject resulObject = JSON.parseObject(resultJson);
                code = resulObject.getString("code") == null ? "" : resulObject.getString("code");
                message = resulObject.getString("message") == null ? "" : resulObject.getString("message");
            }
            if (code.equals("0")) {
                endPoint.setStatus(BaseStatus.USED);
                pointService.update(endPoint);
            } else {
                log.error("kuka返回报错:{}", message);
                redisUtils.set("jlData", "kuka返回报错:" + message);
                return false;
            }
        }
        return true;
    }
}
