package com.wms_main.service.controller.serviceImpl;

import com.alibaba.fastjson2.JSON;
import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums;
import com.wms_main.constant.enums.wcs.WcsStackerTaskTypeEnums;
import com.wms_main.constant.enums.wms.OrderStatusEnum;
import com.wms_main.constant.enums.wms.WmsLocationTypeEnums;
import com.wms_main.dao.ITAppLocationService;
import com.wms_main.dao.ITAppOrderInService;
import com.wms_main.dao.ITAppWcsTaskService;
import com.wms_main.model.dto.request.wcs.WcsVehicleInRequest;
import com.wms_main.model.dto.response.wcs.InTaskResp;
import com.wms_main.model.dto.response.wcs.WcsApiResponse;
import com.wms_main.model.po.TAppLocation;
import com.wms_main.model.po.TAppOrderIn;
import com.wms_main.model.po.TAppWcsTask;
import com.wms_main.repository.utils.StringUtils;
import com.wms_main.repository.utils.UUIDUtils;
import com.wms_main.service.business.IStackerTaskService;
import com.wms_main.service.controller.IWcsControllerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class WcsControllerServiceImpl implements IWcsControllerService {

    private final ITAppOrderInService orderInService;
    private final IStackerTaskService stackerTaskService;
    private final ITAppWcsTaskService wcsTaskService;
    private final ITAppLocationService locationService;


    @Override
    @Transactional
    public WcsApiResponse<InTaskResp> requireInTask(WcsVehicleInRequest request) {
        log.info("WCS请求入栈任务请求参数{}", JSON.toJSON(request));
        if(request == null) return WcsApiResponse.error("参数错误", null);
        String point = request.getPoint();
        if(StringUtils.isEmpty(request.getVehicleNo()) || StringUtils.isEmpty(point)) {
            return WcsApiResponse.error("参数错误", null);
        }
        // 一号堆垛机，全部存空托盘
        if(point.equals("105") || point.equals("106") || point.equals("107")) {
            // 选一个库位
            TAppLocation targetLocation = stackerTaskService.getEmptyLocation(1, null);
            if(targetLocation == null) {
                return WcsApiResponse.error("没有空闲库位，请稍后再试", null);
            }
            String goodsId567 = point.equals("105") ? "3" : "2";
            String vehicleId = UUIDUtils.getNewUUID();
            // 插入一条默认入库单
            TAppOrderIn orderIn = new TAppOrderIn();
            orderIn.setRecordId(UUIDUtils.getNewUUID());
            orderIn.setOrderId(UUIDUtils.getNewUUID());
            orderIn.setVehicleNo(vehicleId);
            orderIn.setVehicleSize(point);
            orderIn.setInStand(point);
            orderIn.setDestination(targetLocation.getLocationId());
            orderIn.setClientId("WCS");
            orderIn.setGoodsId(goodsId567);
            orderIn.setGoodsName("空托盘");
            orderIn.setBatch("0");
            orderIn.setGoodsType("0");
            orderIn.setSpecification("");
            orderIn.setQuantity(1.0);
            orderIn.setGoodsDesc("");
            orderIn.setOrderStatus(OrderStatusEnum.RUNNING.getCode());
            orderIn.setCreateTime(LocalDateTime.now());
            orderIn.setUpdateTime(LocalDateTime.now());
            boolean saveOrderIn = orderInService.save(orderIn);
            if(!saveOrderIn) {
                return WcsApiResponse.error("入库单保存失败，请稍后再试", null);
            }
            // 插入一条WcsTask
            String taskId = UUIDUtils.getNewUUID();
            TAppWcsTask wcsTask = new TAppWcsTask();
            wcsTask.setWcsTaskId(taskId);
            wcsTask.setWcsTaskStatus(WcsStackerTaskStatusEnums.RUN.getCode());
            wcsTask.setWcsTaskType(WcsStackerTaskTypeEnums.IN.getCode());
            wcsTask.setTaskPriority(0);
            wcsTask.setVehicleId(vehicleId);
            wcsTask.setOrigin(point);
            wcsTask.setDestination(targetLocation.getLocationId());
            wcsTask.setCreateTime(LocalDateTime.now());
            wcsTask.setSendTime(LocalDateTime.now());
            boolean saveWcsTask = wcsTaskService.save(wcsTask);
            if(!saveWcsTask) {
                return WcsApiResponse.error("任务创建失败，请稍后再试", null);
            }
            // 锁定库位
            boolean lockLocation = locationService.updateLocationOccupy(targetLocation.getLocationId(), 1);
            if(!lockLocation) {
                return WcsApiResponse.error("库位锁定失败，请稍后再试", null);
            }
            InTaskResp inTaskResp = new InTaskResp();
            inTaskResp.setTaskId(taskId);
            inTaskResp.setUser("WMS");
            inTaskResp.setVehicleNo(vehicleId);
            inTaskResp.setDestination(targetLocation.getLocationId());
            inTaskResp.setSpare1("");
            inTaskResp.setSpare2("");
            return WcsApiResponse.success(inTaskResp);
        }
        // 二号堆垛机，一部分存空一部分存有货位置
        if(point.equals("103") || point.equals("104")) {
            if(request.getVehicleNo().equals("0")) {   // 空托盘
                // 选一个库位
                TAppLocation targetLocation = stackerTaskService.getEmptyLocation(2, WmsLocationTypeEnums.TYPE_EMPTY);
                if(targetLocation == null) {
                    return WcsApiResponse.error("没有空闲库位，请稍后再试", null);
                }
                String goodsId34 = point.equals("103") ? "0" : "1";
                String vehicleId = UUIDUtils.getNewUUID();
                // 插入一条默认入库单
                TAppOrderIn orderIn = new TAppOrderIn();
                orderIn.setRecordId(UUIDUtils.getNewUUID());
                orderIn.setOrderId(UUIDUtils.getNewUUID());
                orderIn.setVehicleNo(vehicleId);
                orderIn.setVehicleSize(point);
                orderIn.setInStand(point);
                orderIn.setDestination(targetLocation.getLocationId());
                orderIn.setClientId("WCS");
                orderIn.setGoodsId(goodsId34);
                orderIn.setGoodsName("空托盘");
                orderIn.setBatch("0");
                orderIn.setGoodsType("0");
                orderIn.setSpecification("");
                orderIn.setQuantity(1.0);
                orderIn.setGoodsDesc("");
                orderIn.setOrderStatus(OrderStatusEnum.RUNNING.getCode());
                orderIn.setCreateTime(LocalDateTime.now());
                orderIn.setUpdateTime(LocalDateTime.now());
                boolean saveOrderIn = orderInService.save(orderIn);
                if(!saveOrderIn) {
                    return WcsApiResponse.error("入库单保存失败，请稍后再试", null);
                }
                // 插入一条WcsTask
                String taskId = UUIDUtils.getNewUUID();
                TAppWcsTask wcsTask = new TAppWcsTask();
                wcsTask.setWcsTaskId(taskId);
                wcsTask.setWcsTaskStatus(WcsStackerTaskStatusEnums.RUN.getCode());
                wcsTask.setWcsTaskType(WcsStackerTaskTypeEnums.IN.getCode());
                wcsTask.setTaskPriority(0);
                wcsTask.setVehicleId(vehicleId);
                wcsTask.setOrigin(point);
                wcsTask.setDestination(targetLocation.getLocationId());
                wcsTask.setCreateTime(LocalDateTime.now());
                wcsTask.setSendTime(LocalDateTime.now());
                boolean saveWcsTask = wcsTaskService.save(wcsTask);
                if(!saveWcsTask) {
                    return WcsApiResponse.error("任务创建失败，请稍后再试", null);
                }
                // 锁定库位
                boolean lockLocation = locationService.updateLocationOccupy(targetLocation.getLocationId(), 1);
                if(!lockLocation) {
                    return WcsApiResponse.error("库位锁定失败，请稍后再试", null);
                }
                InTaskResp inTaskResp = new InTaskResp();
                inTaskResp.setTaskId(taskId);
                inTaskResp.setUser("WMS");
                inTaskResp.setVehicleNo(vehicleId);
                inTaskResp.setDestination(targetLocation.getLocationId());
                inTaskResp.setSpare1("");
                inTaskResp.setSpare2("");
                return WcsApiResponse.success(inTaskResp);
            } else {    // 带料
                // 选一个库位
                TAppLocation targetLocation = stackerTaskService.getEmptyLocation(2, WmsLocationTypeEnums.TYPE_PRODUCT);
                if(targetLocation == null) {
                    return WcsApiResponse.error("没有空闲库位，请稍后再试", null);
                }
                String vehicleNo = request.getVehicleNo();
                // 校验是否存在入库单
                List<TAppOrderIn> withOrderId = orderInService.getWithVehicleNoAndStatus(vehicleNo, OrderStatusEnum.CREATE);
                if(withOrderId == null) {
                    return WcsApiResponse.error("数据服务异常，请稍后重试", null);
                }
                if(withOrderId.isEmpty()) {
                    return WcsApiResponse.error("入库单不存在，请稍后再试", null);
                }
                // TODO 和 入库单校验，WCS 传过来的子条吗数据在条吗里面，用分号隔开
                // TODO 和 mes 校验
                // 更新入库单状态为运行中
                boolean updateStatusWithVehicleNo = orderInService.updateStatusAndDestinationWithVehicleNo(vehicleNo, OrderStatusEnum.RUNNING, targetLocation.getLocationId());
                if(!updateStatusWithVehicleNo) {
                    return WcsApiResponse.error("入库单状态更新失败，请稍后再试", null);
                }
                // 插入一条WcsTask
                String taskId = UUIDUtils.getNewUUID();
                TAppWcsTask wcsTask = new TAppWcsTask();
                wcsTask.setWcsTaskId(taskId);
                wcsTask.setWcsTaskStatus(WcsStackerTaskStatusEnums.RUN.getCode());
                wcsTask.setWcsTaskType(WcsStackerTaskTypeEnums.IN.getCode());
                wcsTask.setTaskPriority(0);
                wcsTask.setVehicleId(vehicleNo);
                wcsTask.setOrigin(point);
                wcsTask.setDestination(targetLocation.getLocationId());
                wcsTask.setCreateTime(LocalDateTime.now());
                wcsTask.setSendTime(LocalDateTime.now());
                boolean saveWcsTask = wcsTaskService.save(wcsTask);
                if(!saveWcsTask) {
                    return WcsApiResponse.error("任务创建失败，请稍后再试", null);
                }
                // 锁定库位
                boolean lockLocation = locationService.updateLocationOccupy(targetLocation.getLocationId(), 1);
                if(!lockLocation) {
                    return WcsApiResponse.error("库位锁定失败，请稍后再试", null);
                }
                InTaskResp inTaskResp = new InTaskResp();
                inTaskResp.setTaskId(taskId);
                inTaskResp.setUser("WMS");
                inTaskResp.setVehicleNo(vehicleNo);
                inTaskResp.setDestination(targetLocation.getLocationId());
                inTaskResp.setSpare1("");
                inTaskResp.setSpare2("");
                return WcsApiResponse.success(inTaskResp);
            }
        }
        // 三号堆垛机
        if(point.equals("101") || point.equals("102")) {
            // 选一个库位
            TAppLocation targetLocation = stackerTaskService.getEmptyLocation(3, WmsLocationTypeEnums.TYPE_PRODUCT);
            if(targetLocation == null) {
                return WcsApiResponse.error("没有空闲库位，请稍后再试", null);
            }
            String vehicleNo = request.getVehicleNo();
            // 校验是否存在入库单
            List<TAppOrderIn> withOrderId = orderInService.getWithVehicleNoAndStatus(vehicleNo, OrderStatusEnum.CREATE);
            if(withOrderId == null) {
                return WcsApiResponse.error("数据服务异常，请稍后重试", null);
            }
            if(withOrderId.isEmpty()) {
                return WcsApiResponse.error("入库单不存在，请稍后再试", null);
            }
            // TODO 和 入库单校验，WCS 传过来的子条吗数据在条吗里面，用分号隔开
            // TODO 和 mes 校验
            // 更新入库单状态为运行中
            boolean updateStatusWithVehicleNo = orderInService.updateStatusAndDestinationWithVehicleNo(vehicleNo, OrderStatusEnum.RUNNING, targetLocation.getLocationId());
            if(!updateStatusWithVehicleNo) {
                return WcsApiResponse.error("入库单状态更新失败，请稍后再试", null);
            }
            // 插入一条WcsTask
            String taskId = UUIDUtils.getNewUUID();
            TAppWcsTask wcsTask = new TAppWcsTask();
            wcsTask.setWcsTaskId(taskId);
            wcsTask.setWcsTaskStatus(WcsStackerTaskStatusEnums.RUN.getCode());
            wcsTask.setWcsTaskType(WcsStackerTaskTypeEnums.IN.getCode());
            wcsTask.setTaskPriority(0);
            wcsTask.setVehicleId(vehicleNo);
            wcsTask.setOrigin(point);
            wcsTask.setDestination(targetLocation.getLocationId());
            wcsTask.setCreateTime(LocalDateTime.now());
            wcsTask.setSendTime(LocalDateTime.now());
            boolean saveWcsTask = wcsTaskService.save(wcsTask);
            if(!saveWcsTask) {
                return WcsApiResponse.error("任务创建失败，请稍后再试", null);
            }
            // 锁定库位
            boolean lockLocation = locationService.updateLocationOccupy(targetLocation.getLocationId(), 1);
            if(!lockLocation) {
                return WcsApiResponse.error("库位锁定失败，请稍后再试", null);
            }
            InTaskResp inTaskResp = new InTaskResp();
            inTaskResp.setTaskId(taskId);
            inTaskResp.setUser("WMS");
            inTaskResp.setVehicleNo(vehicleNo);
            inTaskResp.setDestination(targetLocation.getLocationId());
            inTaskResp.setSpare1("");
            inTaskResp.setSpare2("");
            return WcsApiResponse.success(inTaskResp);
        }
        return WcsApiResponse.error("不支持的入库位置", null);
    }
}
