package com.wms.service.business.serviceImplements;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wms.constants.enums.*;
import com.wms.entity.app.request.GoodsInRequest;
import com.wms.entity.app.request.TaskInRequest;
import com.wms.entity.app.request.TaskOutRequest;
import com.wms.entity.app.request.WorkQuery;
import com.wms.entity.app.wcs.WcsBoxArriveRequest;
import com.wms.entity.app.wcs.WcsTaskResultRequest;
import com.wms.entity.app.wcs.WcsVehicleInRequest;
import com.wms.entity.table.*;
import com.wms.service.*;
import com.wms.service.business.IValidateService;
import com.wms.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Objects;

import static com.wms.constants.WmsConstants.MYSQL_JSON_CI;

/**
 * 验证服务接口的实现
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ValidateServiceImplements implements IValidateService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());// 日志
    private final VehicleService vehicleService;// 载具服务
    private final TaskService taskService;// 任务服务
    private final StandService standService;// 站台服务
    private final GoodsService goodsService;// 物料服务
    private final LocationService locationService;// 库位服务
    private final StockService stockService;// 库存服务
    private final PickTaskService pickTaskService;// 拣选任务

    /**
     * 验证入库请求
     * @param taskInRequest 入库请求
     * @return 验证结果
     */
    @Override
    public String validateTaskInRequest(TaskInRequest taskInRequest) {
        if (taskInRequest == null) {
            return TaskInValidationEnum.NO_REQUEST_BODY.getErrorMessage();
        }
        // 验证载具号
        if (StringUtils.isEmpty(taskInRequest.getVehicleId())) {
            return TaskInValidationEnum.NO_VEHICLE_ID.getErrorMessage();
        }
        // 验证载具号是否重复入库
        if (vehicleService.exists(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, taskInRequest.getVehicleId())
                .and(wrapper -> wrapper.eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode())))) {
            return TaskInValidationEnum.DUPLICATE_VEHICLE_ID.getErrorMessage();
        }
        // 如果这个箱子还有拣选任务，不允许操作
        if (pickTaskService.exists(new LambdaQueryWrapper<PickTask>()
                .eq(PickTask::getVehicleId, taskInRequest.getVehicleId()))) {
            return TaskInValidationEnum.ON_PICKING.getErrorMessage();
        }
        // 验证当前的箱子是否有其他不是暂存状态的任务
        if(taskService.exists(new LambdaQueryWrapper<Task>()
                .eq(Task::getVehicleId, taskInRequest.getVehicleId())
                .ne(Task::getTaskStatus, WmsTaskStatus.TEMP.getCode()))) {
            return TaskInValidationEnum.OTHER_TASKS.getErrorMessage();
        }
        // 验证物料信息
        if (taskInRequest.getGoodsList() != null && !taskInRequest.getGoodsList().isEmpty()) {
            for (GoodsInRequest goodsInRequest : taskInRequest.getGoodsList()) {
                // 验证物料编号
                if (StringUtils.isEmpty(goodsInRequest.getGoodsId())) {
                    return TaskInValidationEnum.NO_GOODS_ID.getErrorMessage();
                } else {
                    Goods goods = goodsService.getOne(new LambdaQueryWrapper<Goods>().eq(Goods::getGoodsId, goodsInRequest.getGoodsId()));
                    if (goods == null) {
                        return TaskInValidationEnum.ERROR_GOODS_ID.getErrorMessage();
                    }
                    // TODO 超重验证
//                    // 验证重量
//                    BigDecimal max_weight = BigDecimal.valueOf(10000000);
//                    try {
//                        max_weight = new BigDecimal(configMap.get(ConfigMapKeyEnum.MAX_WEIGHT.getConfigKey()));
//                    } catch (Exception e) {
//                        logger.error("转换配置项---最大承重，发生错误");
//                    }
//                    if (taskInRequest.getTotalWeight().compareTo(max_weight) > 0) {
//                        // 超重
//                        return TaskInValidationEnum.OVER_WEIGHT.getErrorMessage();
//                    }
                }
                // 验证数量
                if (goodsInRequest.getGoodsNum() == null || goodsInRequest.getGoodsNum().compareTo(BigDecimal.ZERO) <= 0) {
                    return TaskInValidationEnum.ERROR_GOODS_NUM.getErrorMessage();
                }
            }
        }
        return TaskInValidationEnum.OK.getErrorMessage();
    }

    /**
     * 验证出库请求
     * @param taskOutRequest 出库请求
     * @return 验证结果
     */
    @Override
    public String validateTaskOutRequest(TaskOutRequest taskOutRequest) {
        // 验证任务
        if (taskOutRequest == null) {
            return TaskOutValidationEnum.NO_REQUEST_BODY.getErrorMessage();
        }
        // 验证是否包含请求信息
        if (StringUtils.isEmpty(taskOutRequest.getGoodsId())
                && StringUtils.isEmpty(taskOutRequest.getVehicleId())
                && StringUtils.isEmpty(taskOutRequest.getOriginPoint())) {
            return TaskOutValidationEnum.LACK_REQUIRED_PARAM.getErrorMessage();
        }
        // 验证载具号
        if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())
                && vehicleService.exists(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()))) {
            return TaskOutValidationEnum.ERROR_VEHICLE_ID.getErrorMessage();
        }
        // 验证库位
        if (StringUtils.isNotEmpty(taskOutRequest.getOriginPoint())
                && locationService.exists(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, taskOutRequest.getOriginPoint()))) {
            return TaskOutValidationEnum.ERROR_ORIGIN_POINT.getErrorMessage();
        }
        // 验证终点站台
        if (taskOutRequest.getIsPicking() == 0) {// 出库
            if (!standService.validateStand(taskOutRequest.getDestinationPoint(), 2)) {
                return TaskOutValidationEnum.ERROR_DESTINATION_POINT.getErrorMessage();
            }
        } else {// 拣选出库
            if (!standService.validateStand(taskOutRequest.getDestinationPoint(), 3)) {
                return TaskOutValidationEnum.ERROR_PICK_STAND.getErrorMessage();
            }
        }
        // 验证物料信息
        if (StringUtils.isNotEmpty(taskOutRequest.getGoodsId())) {
            if (taskOutRequest.getGoodsNum() == null || taskOutRequest.getGoodsNum().compareTo(BigDecimal.ZERO) <= 0) {
                return TaskOutValidationEnum.ERROR_GOODS_NUM.getErrorMessage();
            }
            // 查询库存信息
            LambdaQueryWrapper<Stock> stockQueryWrapper = new LambdaQueryWrapper<Stock>()
                    .apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, taskOutRequest.getGoodsId())
                    .apply("goods_related ->> '$.remainNum' > 0")
                    .eq(StringUtils.isNotEmpty(taskOutRequest.getVehicleId()), Stock::getVehicleId, taskOutRequest.getVehicleId())
                    .eq(StringUtils.isNotEmpty(taskOutRequest.getOriginPoint()), Stock::getLocationId, taskOutRequest.getOriginPoint());
            if (!stockService.exists(stockQueryWrapper)) {
                return TaskOutValidationEnum.NO_STOCK.getErrorMessage();
            }
        } else {
            if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())) {
                Vehicle currentVehicle = vehicleService.getOne(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()));
                Location currentLocation = locationService.getOne(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, currentVehicle.getCurrentLocation()));
                if (!Objects.equals(currentVehicle.getVehicleStatus(), VehicleStatus.ON.getCode())) {
                    return TaskOutValidationEnum.ERROR_VEHICLE_STATUS.getErrorMessage();
                }
                if (!Objects.equals(currentLocation.getIsLock(), 1)) {
                    return TaskOutValidationEnum.LOCKED_LOCATION.getErrorMessage();
                }
            } else {
                Location currentLocation = locationService.getOne(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, taskOutRequest.getOriginPoint()));
                if (!Objects.equals(currentLocation.getIsLock(), 1)) {
                    return TaskOutValidationEnum.LOCKED_LOCATION.getErrorMessage();
                }
                if (!Objects.equals(currentLocation.getLocationStatus(), LocationStatus.OCCUPY.getCode())) {
                    return TaskOutValidationEnum.ERROR_ORIGIN_POINT_STATUS.getErrorMessage();
                }
            }
        }
        return TaskOutValidationEnum.OK.getErrorMessage();
    }

    /**
     * 验证任务反馈的请求信息
     *
     * @param wcsTaskResultRequest 任务反馈的请求
     * @return 验证结果
     */
    @Override
    public String validateTaskResult(WcsTaskResultRequest wcsTaskResultRequest) {
        // 验证请求体是否为空
        if (wcsTaskResultRequest == null) {
            return TaskResultValidationEnum.NO_REQUEST_BODY.getErrorMessage();
        }
        // 验证是否缺少必须信息
        if (StringUtils.isEmpty(wcsTaskResultRequest.getTaskId()) || StringUtils.isEmpty(wcsTaskResultRequest.getVehicleId())
                || wcsTaskResultRequest.getTaskStatus() == null) {
            return TaskResultValidationEnum.LACK_REQUIRED_PARAM.getErrorMessage();
        }
        // 验证反馈的任务号是否正确
        if (!taskService.exists(new LambdaQueryWrapper<Task>().eq(Task::getTaskGroup, wcsTaskResultRequest.getTaskId()))) {
            return TaskResultValidationEnum.ERROR_TASK_GROUP.getErrorMessage();
        }
        // 验证反馈的任务状态枚举是否正确
        boolean isValidWcsTaskStatus = false;
        for (WcsTaskStatus wcsTaskStatus : WcsTaskStatus.values()) {
            if (Objects.equals(wcsTaskStatus.getCode(), wcsTaskResultRequest.getTaskStatus())) {
                isValidWcsTaskStatus = true;
                break;
            }
        }
        if (!isValidWcsTaskStatus) {
            return TaskResultValidationEnum.ERROR_TASK_STATUS.getErrorMessage();
        }
        return TaskResultValidationEnum.OK.getErrorMessage();
    }

    /**
     * 验证载具入库请求的正确性
     * @param wcsVehicleInRequest 载具入库请求
     * @return 验证结果
     */
    @Override
    public String validateVehicleRequest(WcsVehicleInRequest wcsVehicleInRequest) {
        // 判断请求信息
        if (wcsVehicleInRequest == null) {
            return "请求信息为空";
        }
        // 判断是否缺少载具号
        if (StringUtils.isEmpty(wcsVehicleInRequest.getVehicleNo())) {
            return "缺少载具号";
        }
        // 判断当前载具号是否存在任务
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<Task>()
                .eq(Task::getVehicleId, wcsVehicleInRequest.getVehicleNo())
                .eq(Task::getTaskType, TaskType.IN.getCode())
                .eq(Task::getTaskStatus, WmsTaskStatus.TEMP.getCode());
        if (!taskService.exists(queryWrapper)) {
            return "当前载具没有待下发的入库或回库任务";
        }

        return "";
    }

    /**
     * 验证重复入库问题反馈的请求
     * @param duplicateLocationRequest 请求信息
     * @return 验证结果
     */
    @Override
    public String validateDuplicateLocationRequest(WcsTaskResultRequest duplicateLocationRequest) {
        // 判断请求信息
        if (duplicateLocationRequest == null) {
            return "请求信息为空";
        }
        // 判断是否缺少任务号
        if (StringUtils.isEmpty(duplicateLocationRequest.getTaskId())) {
            return "缺少任务号";
        }
        // 判断是否缺少载具号
        if (StringUtils.isEmpty(duplicateLocationRequest.getVehicleId())) {
            return "缺少载具号";
        }
        // 判断当前载具号是否存在任务
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<Task>()
                .eq(Task::getTaskGroup, duplicateLocationRequest.getTaskId())
                .eq(Task::getVehicleId, duplicateLocationRequest.getVehicleId())
                .eq(Task::getTaskType, TaskType.IN.getCode());
        if (!taskService.exists(queryWrapper)) {
            return "当前反馈的重复入库任务不存在";
        }

        return "";
    }

    /**
     * 验证Wcs上报箱子到达请求
     * @param boxArriveRequest Wcs上报箱子到达请求
     * @return 验证结果
     */
    @Override
    public String validateBoxArriveRequest(WcsBoxArriveRequest boxArriveRequest) {
        if (boxArriveRequest == null || StringUtils.isEmpty(boxArriveRequest.getVehicleNo()) || StringUtils.isEmpty(boxArriveRequest.getLocation())) {
            return "请求参数不全，载具号和站台号不可缺少";
        }

        return "";
    }

    /**
     * 验证获取工作信息请求
     * @param workQuery 请求参数
     * @return 验证结果
     */
    @Override
    public String validateGetWorkVoRequest(WorkQuery workQuery) {
        if (workQuery == null || StringUtils.isEmpty(workQuery.getGoodsId())) {
            return "请求参数不完整，料号必须可少";
        }

        return "";
    }
}
