package com.youchain.appupdate.rest;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.youchain.annotation.AnonymousAccess;
import com.youchain.annotation.Log;
import com.youchain.appupdate.inputJson.*;
import com.youchain.appupdate.service.ContainerService;
import com.youchain.basicdata.domain.Box;
import com.youchain.basicdata.domain.Item;
import com.youchain.basicdata.domain.Point;
import com.youchain.basicdata.domain.Stock;
import com.youchain.basicdata.repository.ZcjxbRepository;
import com.youchain.basicdata.service.ItemService;
import com.youchain.basicdata.service.PointService;
import com.youchain.basicdata.service.StockService;
import com.youchain.basicdata.service.dto.ItemDto;
import com.youchain.basicdata.service.dto.ItemQueryCriteria;
import com.youchain.businessdata.domain.*;
import com.youchain.businessdata.service.*;
import com.youchain.exception.handler.ApiResult;
import com.youchain.modules.system.service.DictService;
import com.youchain.modules.system.service.dto.DictDto;
import com.youchain.modules.system.service.dto.DictQueryCriteria;
import com.youchain.utils.AreaNameDic;
import com.youchain.utils.BaseStatus;
import com.youchain.utils.BizStatus;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.method.P;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;

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

@RestController
@RequiredArgsConstructor
@Api(tags = "app场景管理")
@RequestMapping("/api/appScene")
@Slf4j
public class SceneAppController {

    private final ItemService itemService;

    private final PointService pointService;

    private final StockService stockService;

    private final DictService dictService;
    private final AsnDetailService asnDetailService;
    private final PickDetailService pickDetailService;
    private final ItemKeyService itemKeyService;
    private final AgvTaskService agvTaskService;
    private final TaskService taskService;
    private final InventoryService inventoryService;
    //容器出场和入场
    private final ContainerService containerService;
    private final ZcjxbRepository zcjxbRepository;

    @PostMapping("/zCBindingItem")
    @Log("轴承座机械臂换邦物料")
    @ApiOperation("轴承座机械臂换邦物料")
    @AnonymousAccess
    public ResponseEntity<Object> zCBindingItem(@RequestBody ZCBindingMaterial zcBindingMaterial){
        //查询该物料是否存在
        ItemQueryCriteria itemQueryCriteria = new ItemQueryCriteria();
        itemQueryCriteria.setName("轴承座");
        itemQueryCriteria.setCode(zcBindingMaterial.getModbusTcpItem());
        List<ItemDto> itemDtos = itemService.queryAll(itemQueryCriteria);
        if (itemDtos.isEmpty()){
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "物料号输入错误", ""), HttpStatus.BAD_REQUEST);
        }
        //修改物料
        zcjxbRepository.updateZCJItem(zcBindingMaterial.getModbusTcpItem(),zcBindingMaterial.getCode());
        return new ResponseEntity<>(ApiResult.success(OK.value(), "物料更换成功!", ""), HttpStatus.OK);
    }
    @PostMapping("/fullStockIn")
    @Log("满车入库")
    @ApiOperation("满车入库")
    @AnonymousAccess
    public ResponseEntity<Object> fullStockIn(@RequestBody FullStockIn bi) {
        String agvScene = bi.getAgvScene();
        String itemCode = bi.getItemCode();//物料编号
        String pointCode = bi.getPointCode();
        String stockCode = bi.getStockCode();
        int checkCode = bi.getCheckCode();
        String endArea = "";
        String srcArea = "";
        String agv_on_off = "OFF";
        //判断满车入库是否全填完   判断是不是轴承卓空车点直接入的
        if (agvScene.equals("ZC") && itemCode != null && (pointCode != null && pointCode.length() > 0)) {//判断是否是轴承座的满车入库
            Point point = pointService.getPoint(pointCode, null, null, srcArea);
            //判断是人拉过去的还是呼叫空车过去的
            if (point.getStatus().equals(BaseStatus.FREE)) {
                Boolean b = this.stockOutIn(stockCode, pointCode);
                if (!b) {
                    return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "容器出场再入场失败", ""), HttpStatus.BAD_REQUEST);
                }
            }
        }
        agv_on_off = dictService.getDictDescription("agv_on_off") == null ? "OFF" : dictService.getDictDescription("agv_on_off").getDescription();
        Item item = itemService.existItem(itemCode);
        if (item == null) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "物料不存在!", ""), HttpStatus.BAD_REQUEST);
        } else if (checkCode == 1) {
            return new ResponseEntity<>(ApiResult.success(OK.value(), "校验成功!", ""), HttpStatus.OK);
        }
        if (agvScene.equals("ZC")) {
            if (!item.getGoodType().equals("ZC")) {
                return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "物料不属于轴承座!", ""), HttpStatus.BAD_REQUEST);
            }
            srcArea = AreaNameDic.ZCFB;
            endArea = AreaNameDic.ZCM;
        } else if (agvScene.equals("MF")) {
            if (!item.getGoodType().equals("MF")) {
                return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "物料不属于门封!", ""), HttpStatus.BAD_REQUEST);
            }
            srcArea = AreaNameDic.MFJB;
            endArea = AreaNameDic.MFM;
        }

        Stock stock = stockService.findByCode(stockCode, null);
        if (stock == null) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "容器不存在!", ""), HttpStatus.BAD_REQUEST);
        } else if (stock.getPoint() == null) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "容器未入场!", ""), HttpStatus.BAD_REQUEST);
        } else if (checkCode == 2) {
            return new ResponseEntity<>(ApiResult.success(OK.value(), "校验成功!", ""), HttpStatus.OK);
        }
        Point srcPoint = pointService.getPoint(pointCode, null, null, srcArea);
        if (srcPoint == null) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), pointCode + "没有料车!", ""), HttpStatus.BAD_REQUEST);
        } else if (!stock.getPoint().getCode().equals(pointCode)) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "点位和容器不匹配!", ""), HttpStatus.BAD_REQUEST);
        }
        Point endPoint = pointService.getPoint(null, BaseStatus.FREE, null, endArea);
        if (endPoint == null) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), endArea + "无空闲点位!", ""), HttpStatus.BAD_REQUEST);
        }
        //生成搬运任务
        AgvTask agvTask = new AgvTask(BizStatus.ASN, stock.getCode(), pointCode, endPoint.getCode(), BizStatus.OPEN, "RACK_MOVE");
        agvTaskService.create(agvTask);
        String code = "0";
        String message = null;
        if (agv_on_off.equals("ON")) {
            String resultJson = agvTaskService.sendAgvTaskImpl(agvTask);//发送任务
//            String resultJson =  "{\n" +
//                    "  \"data\": null,\n" +
//                    "  \"code\": 0,\n" +
//                    "  \"message\": null,\n" +
//                    "  \"success\": true\n" +
//                    "}";//发送任务
            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);
            //生成入库任务
            Date date = cn.hutool.core.date.DateUtil.date();
            String propC1 = DateUtil.format(date, "yyyyMMdd");
            AsnDetail asnDetail = asnDetailService.createAsnDetail(item, stock, srcPoint, propC1, null);
            //生成Itemkey
            ItemKey itemKey = itemKeyService.getItemKey(item, asnDetail.getPropC1(), asnDetail.getOrderNumber());
            //生成入库记录
            Task task = new Task(item, itemKey, asnDetail.getOrderNumber(), BizStatus.ASN, asnDetail, null, null, null, stock, stock, srcPoint, endPoint, stock.getCode(), stock.getCode(), srcPoint.getCode(), endPoint.getCode(), null, BizStatus.OPEN, asnDetail.getOrderQty(), null, null, item.getDept(), agvTask);
            taskService.create(task);*/
        } else {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), message, ""), HttpStatus.BAD_REQUEST);
        }
        return new ResponseEntity<>(ApiResult.success(OK.value(), "入库成功!", ""), HttpStatus.OK);
    }

    @PostMapping("/fullStockOut")
    @Log("满车出库")
    @ApiOperation("满车出库")
    @AnonymousAccess
    public ResponseEntity<Object> fullStockOut(@RequestBody 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) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "物料不存在!", ""), HttpStatus.BAD_REQUEST);
        } else if (checkCode == 1) {
            return new ResponseEntity<>(ApiResult.success(OK.value(), "校验成功!", ""), HttpStatus.OK);
        }
        if (agvScene.equals(BizStatus.ZC)) {
            if (!item.getGoodType().equals(BizStatus.ZC)) {
                return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "物料不属于轴承座!", ""), HttpStatus.BAD_REQUEST);
            }
            endArea = AreaNameDic.ZCJXB;
            srcArea = AreaNameDic.ZCM;
        } else if (agvScene.equals("MF")) {
            if (!item.getGoodType().equals("MF")) {
                return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "物料不属于门封!", ""), HttpStatus.BAD_REQUEST);
            }
            endArea = "门封出库缓存区";
            srcArea = "门封满车区";
        }
        Point endPoint = pointService.getPoint(pointCode, null, null, endArea);
        if (endPoint == null) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), pointCode + "点位错误!", ""), HttpStatus.BAD_REQUEST);
        } else if (endPoint.getStatus().equals(BaseStatus.USED)) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), pointCode + "点位被占用!", ""), HttpStatus.BAD_REQUEST);
        }
        List<Inventory> inventoryList = inventoryService.queryInventory(item.getId());
        if (inventoryList.size() == 0) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), itemCode + "无库存!", ""), HttpStatus.BAD_REQUEST);
        } else {
            PickDetail pickDetail = pickDetailService.createPickDetail(item, null);
            try {
                pickDetailService.allocateAll(pickDetail.getId(), endPoint);
            } catch (Exception e) {
                return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), e.getMessage(), ""), HttpStatus.BAD_REQUEST);
            }
            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 {
                throw new RuntimeException(message);
            }
        }
        return new ResponseEntity<>(ApiResult.success(OK.value(), "出库成功!", ""), HttpStatus.OK);
    }


    @PostMapping("/pointCallStock")
    @Log("容器搬运")
    @ApiOperation("容器搬运")
    @AnonymousAccess
    public ResponseEntity<Object> pointCallStock(@RequestBody JSONObject jsonObject) {
        System.out.println("容器搬运"+jsonObject);
        String pointEndCode = jsonObject.getString("pointCode");
        JSONArray ids=jsonObject.getJSONArray("ids");
        for (int i = 0; i < ids.size(); i++) {
            Long id=ids.getLong(i);
            agvTaskService.addAgvTask(id,pointEndCode);
        }
        /*String pointCode = pointCallStock.getPointCode();
        String agvScene = pointCallStock.getAgvScene();
        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();
        String srcAreaName = null;
        String endAreaName = null;
        if (agvScene.equals(BizStatus.ZC)) {
            endAreaName = AreaNameDic.ZCFB;
            srcAreaName = AreaNameDic.ZCK;
        } else if (agvScene.equals(BizStatus.MF)) {
            endAreaName = AreaNameDic.MFJB;
            srcAreaName = AreaNameDic.MFK;
        }
        Point endPoint = pointService.getPoint(pointCode, null, null, endAreaName);
        if (endPoint == null) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), pointCode + "点位不存在!", ""), HttpStatus.BAD_REQUEST);
        } else if (endPoint.getStatus().equals(BaseStatus.USED)) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), pointCode + "点位状态已占用!", ""), HttpStatus.BAD_REQUEST);
        }
        //查询空料车
        Stock stock = stockService.findStockByPoint(srcAreaName);
        if (stock == null) {
            throw new RuntimeException(srcAreaName + "没有空料车!");
        }
        Point srcPoint = stock.getPoint();
        String stockCode = stock.getCode();

        //生成搬运任务
        AgvTask agvTask = new AgvTask(BizStatus.EMPTY_OUT, stockCode, srcPoint.getCode(), endPoint.getCode(), BizStatus.OPEN, "RACK_MOVE");
        agvTaskService.create(agvTask);

        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);
            //将容器对应地标改为目的地标
            if (stock != null) {
                stock.setPoint(endPoint);
                stockService.update(stock);
            }
            srcPoint.setStatus(BaseStatus.FREE);
            pointService.update(srcPoint);
        } else {
            throw new RuntimeException(message);
        }*/
        return new ResponseEntity<>(ApiResult.success(OK.value(), "", ""), HttpStatus.OK);
    }

    @PostMapping("/pointStockBack")
    @Log("容器入场")
    @ApiOperation("容器入场")
    @AnonymousAccess
    public ResponseEntity<Object> pointStockBack(@RequestBody JSONObject jsonObject) {
        System.out.println("容器入场："+jsonObject);
        String storageType = jsonObject.getString("storageType");
        JSONArray ids=jsonObject.getJSONArray("ids");
        for (int i = 0; i < ids.size(); i++) {
            Long id = ids.getLong(i);
            agvTaskService.pointStockRk(storageType,id);

        }
        /*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) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), pointCode + "点位不存在!", ""), HttpStatus.BAD_REQUEST);
        }
        Stock st = stockService.findByPointCode(srcPoint.getCode());
        String stockCode = null;
        if (st != null) {
            stockCode = st.getCode();
        } else {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), srcPoint.getCode() + "对应点位无容器!", ""), HttpStatus.BAD_REQUEST);
        }

        //查找空车区是否点位

        Point endPoint = pointService.getPointByFree(endAreaName, null);
        if (endPoint == null) {
            throw new RuntimeException("空车区没有空闲点位!");
        }
        //生成搬运任务
        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 {
            throw new RuntimeException(message);
        }*/
        return new ResponseEntity<>(ApiResult.success(OK.value(), "", ""), HttpStatus.OK);
    }

    public Boolean stockOutIn(String stockCode, String pointCode) {//容器出场再入场
        Stock stock = stockService.findByCode(stockCode, null);
        //容器出场
        ContainerIn containerIn = new ContainerIn();
        containerIn.setContainerCode(stockCode);
        containerIn.setPosition(stock.getPoint().getCode());
        //xyjAppController.containerOut(containerIn);
        if (!containerService.ContainerOut(containerIn)){
            log.error("容器出场失败");
            return false;
        }
        //容器容器入场
        ContainerIn containerIn1 = new ContainerIn();
        containerIn1.setContainerCode(stockCode);
        containerIn1.setPosition(pointCode);
        //xyjAppController.containerIn(containerIn1);
        if (!containerService.ContainerIn(containerIn1)){
            log.error("容器入场失败");
            return false;
        }
        Point point = pointService.getPoint(pointCode, null, null, null);
        point.setStatus(BaseStatus.USED);
        pointService.update(point);
        return true;
    }
}
