package com.wms_main.service.controller.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms_main.app.AppCommon;
import com.wms_main.constant.enums.wms.OrderStatusEnum;
import com.wms_main.constant.enums.wms.WmsLocationOccupyStatusEnums;
import com.wms_main.constant.enums.wms.WmsStockStatusEnums;
import com.wms_main.dao.ITAppLocationService;
import com.wms_main.dao.ITAppOrderInService;
import com.wms_main.dao.ITAppOrderOutService;
import com.wms_main.dao.ITAppStockService;
import com.wms_main.dao.ITAppTaskService;
import com.wms_main.dao.ITAppWcsTaskService;
import com.wms_main.model.dto.request.mywms.*;
import com.wms_main.model.dto.request.wcs.WcsCanFeedRequest;
import com.wms_main.model.dto.response.mywms.MyWmsResponse;
import com.wms_main.model.dto.response.mywms.OrderResponse;
import com.wms_main.model.dto.response.wcs.WcsApiResponse;
import com.wms_main.model.dto.response.wcs.WcsCanFeedResponse;
import com.wms_main.model.po.TAppLocation;
import com.wms_main.model.po.TAppOrderIn;
import com.wms_main.model.po.TAppOrderOut;
import com.wms_main.model.po.TAppStock;
import com.wms_main.model.po.TAppTask;
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.api.IWcsApiService;
import com.wms_main.service.controller.IMyWmsControllerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

@Service
@Slf4j
@RequiredArgsConstructor
public class MyWmsControllerServiceImpl implements IMyWmsControllerService {

    private final ITAppOrderInService appOrderInService;
    private final ITAppOrderOutService appOrderOutService;
    private final ITAppStockService appStockService;
    private final ITAppLocationService appLocationService;
    private final IWcsApiService wcsApiService;
    private final ITAppTaskService appTaskService;
    private final ITAppWcsTaskService appWcsTaskService;
    private final AppCommon appCommon;

    @Override
    public OrderResponse orderIn(OrderInReq request) {
        try {
            if (request == null)
                return OrderResponse.error("参数错误");
            if (!request.isValid()) {
                return OrderResponse.error("参数错误");
            }
            // 校验是否存在相同的入库单
            List<TAppOrderIn> withTaskId = appOrderInService.getWithTaskId(request.getTaskId());
            if (withTaskId == null) {
                return OrderResponse.error("数据服务异常，请稍后重试");
            }
            if (!withTaskId.isEmpty()) {
                return OrderResponse.error("入库单已存在，请勿重复推送");
            }
            Boolean isDup = appStockService
                    .exists(new LambdaQueryWrapper<TAppStock>().eq(TAppStock::getVehicleId, request.getVehicleNo())
                            .eq(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode()));
            if (isDup) {
                return OrderResponse.error("库存重复，托盘号: " + request.getVehicleNo());
            }
            TAppOrderIn orderIn = new TAppOrderIn();
            orderIn.setRecordId(UUIDUtils.getNewUUID());
            orderIn.setOrderId(request.getTaskId());
            orderIn.setVehicleNo(request.getVehicleNo());
            orderIn.setInStand("CR");
            orderIn.setRequestUser("wms");
            orderIn.setOrderStatus(OrderStatusEnum.CREATE.getCode());
            orderIn.setCreateTime(LocalDateTime.now());
            orderIn.setUpdateTime(LocalDateTime.now());
            if (!appOrderInService.save(orderIn)) {
                return OrderResponse.error("入库单保存失败，请稍后再试");
            }
            return OrderResponse.success();
        } catch (Exception e) {
            return OrderResponse.error("入库单添加异常");
        }
    }

    @Override
    public OrderResponse orderOut(OrderOutReq request) {
        try {
            if (request == null || StringUtils.isEmpty(request.getTaskId())
                    || StringUtils.isEmpty(request.getVehicleNo())) {
                return OrderResponse.error("参数错误");
            }

            List<TAppOrderOut> orderOutCheckList = appOrderOutService.getWithTaskId(request.getTaskId());
            if (orderOutCheckList == null) {
                return OrderResponse.error("数据服务异常，请稍后重试");
            }
            if (!orderOutCheckList.isEmpty()) {
                return OrderResponse.error("出库单已存在，请勿重复推送");
            }

            List<TAppStock> vehicleStocks = appStockService.list(
                    new LambdaQueryWrapper<TAppStock>()
                            .eq(TAppStock::getVehicleId, request.getVehicleNo())
                            .eq(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode()));

            if (vehicleStocks == null || vehicleStocks.isEmpty()) {
                return OrderResponse.error("载具号" + request.getVehicleNo() + "无库存记录");
            }

            TAppOrderOut orderOut = new TAppOrderOut();
            orderOut.setRecordId(UUIDUtils.getNewUUID());
            orderOut.setOrderId(request.getTaskId());
            orderOut.setVehicleNo(request.getVehicleNo());
            orderOut.setOrderStatus(OrderStatusEnum.CREATE.getCode());
            orderOut.setCreateTime(LocalDateTime.now());
            orderOut.setUpdateTime(LocalDateTime.now());

            if (!appOrderOutService.save(orderOut)) {
                return OrderResponse.error("出库单保存失败，请稍后再试");
            }
            return OrderResponse.success();
        } catch (Exception e) {
            log.error("出库任务添加失败", e);
            return OrderResponse.error("出库任务添加失败，请稍后再试");
        }
    }

    @Override
    public MyWmsResponse<List<StockRespGoodsDetail>> stock(StockReq request) {
        if (request == null || request.empty())
            return MyWmsResponse.error("参数错误", null);
        List<TAppStock> stocks = new ArrayList<>();
        Map<String, TAppStock> vehicleStockMap = new HashMap<>();
        if (request.getDetails() == null || request.getDetails().isEmpty()) {
            stocks = appStockService.list();
        } else {
            for (StockReqGoodsDetail stockReqGoodsDetail : request.getDetails()) {
                List<TAppStock> stockList = appStockService.list(
                        new LambdaQueryWrapper<TAppStock>()
                                .eq(StringUtils.isNotEmpty(stockReqGoodsDetail.getVehicleNo()), TAppStock::getVehicleId,
                                        stockReqGoodsDetail.getVehicleNo())
                                .eq(StringUtils.isNotEmpty(stockReqGoodsDetail.getLocationId()),
                                        TAppStock::getLocationId, stockReqGoodsDetail.getLocationId()));
                if (stockList != null && !stockList.isEmpty()) {
                    for (TAppStock stock : stockList) {
                        if (!vehicleStockMap.containsKey(stock.getVehicleId())) {
                            stocks.add(stock);
                            vehicleStockMap.put(stock.getVehicleId(), stock);
                        }
                    }
                }
            }
        }
        if (stocks == null) {
            return MyWmsResponse.error("数据服务异常，请稍后重试", null);
        }
        List<StockRespGoodsDetail> respList = new ArrayList<>();
        for (TAppStock stock : stocks) {
            StockRespGoodsDetail stockRespGoodsDetail = new StockRespGoodsDetail();
            stockRespGoodsDetail.setVehicleNo(stock.getVehicleId());
            stockRespGoodsDetail.setLocationId(stock.getLocationId());
            stockRespGoodsDetail.setInTaskId(stock.getInTaskId());

            respList.add(stockRespGoodsDetail);
        }
        return MyWmsResponse.success(respList);
    }

    @Override
    public MyWmsResponse<Boolean> queryCanFeed() {
        try {
            // 1. 检查库位是否足够
            if (!appLocationService.exists(new LambdaQueryWrapper<TAppLocation>().eq(TAppLocation::getIsOccupy,
                    WmsLocationOccupyStatusEnums.EMPTY.getCode()))) {
                return MyWmsResponse.error("无剩余可用库位", false);
            }

            // 2. 调用wcs.canFeed检查wcs状态
            WcsApiResponse<WcsCanFeedResponse> wcsResponse = wcsApiService.canFeed(new WcsCanFeedRequest("CR"));
            if (wcsResponse == null || wcsResponse.getData() == null) {
                return MyWmsResponse.error("WCS系统查询失败", false);
            }

            return MyWmsResponse.success(true);
        } catch (Exception e) {
            return MyWmsResponse.error("系统异常，请稍后重试", false);
        }
    }

    @Override
    public MyWmsResponse<Boolean> queryCanOut() {
        try {
            // 1. 调用wcs.canFeed检查wcs状态 (使用CR口)
            WcsApiResponse<WcsCanFeedResponse> wcsResponse = wcsApiService.canFeed(new WcsCanFeedRequest("CR"));
            if (wcsResponse == null || wcsResponse.getData() == null) {
                return MyWmsResponse.error("WCS系统查询失败", false);
            }

            return MyWmsResponse.success(true);
        } catch (Exception e) {
            return MyWmsResponse.error("系统异常，请稍后重试", false);
        }
    }

    @Override
    public String cancelOrderIn(OrderInCancel request) {
        String vehicleNo = request.getVehicleNo();
        if (!appOrderInService.remove(new LambdaQueryWrapper<TAppOrderIn>().eq(StringUtils.isNotEmpty(vehicleNo),
                TAppOrderIn::getVehicleNo, vehicleNo))) {
            log.info("fail to delete orderIn, vehicleNo: " + vehicleNo);
        }
        if (!appTaskService.remove(new LambdaQueryWrapper<TAppTask>().eq(StringUtils.isNotEmpty(vehicleNo),
                TAppTask::getVehicleId, vehicleNo))) {
            log.info("fail to delete wmsTask, vehicleNo: " + vehicleNo);
        }
        if (!appWcsTaskService.remove(new LambdaQueryWrapper<TAppWcsTask>().eq(StringUtils.isNotEmpty(vehicleNo),
                TAppWcsTask::getVehicleId, vehicleNo))) {
            log.info("fail to delete wcsTask, vehicleNo: " + vehicleNo);
        }
        List<TAppLocation> locationList = appLocationService.list(
                new LambdaQueryWrapper<TAppLocation>().eq(StringUtils.isNotEmpty(vehicleNo), TAppLocation::getVehicleId,
                        vehicleNo));
        TAppLocation location = null;
        if (locationList != null && locationList.size() > 0) {
            location = locationList.getFirst();
        }
        if (location != null && !appStockService.exists(new LambdaQueryWrapper<TAppStock>()
                .eq(StringUtils.isNotEmpty(vehicleNo),
                        TAppStock::getVehicleId, vehicleNo)
                .eq(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode()))) {
            if (!appLocationService.update(
                    new LambdaUpdateWrapper<TAppLocation>().eq(TAppLocation::getLocationId, location.getLocationId())
                            .set(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.EMPTY.getCode())
                            .set(TAppLocation::getVehicleId, ""))) {
                log.info("fail to update location, vehicleNo: {}, location: {}", vehicleNo, location.getLocationId());
            }
            appCommon.updateWorkingLocations(location.getLocationId(), 0);
            return "成功清理";
        } else {
            return "该载具已在库中，无法清除库位信息 / 库位表中无数据";
        }

    }
}
