package org.ta.pddserver.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.models.OpenAPI;
import jakarta.annotation.Resource;
import jakarta.annotation.security.RolesAllowed;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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 org.ta.pdd.entity.*;
import org.ta.pddserver.config.PddAPIConfig;
import org.ta.pddserver.model.api.request.*;
import org.ta.pddserver.model.api.response.StorageListResponse;
import org.ta.pddserver.model.api.response.StorageResponse;
import org.ta.pddserver.model.enums.MailNoStatusEnum;
import org.ta.pddserver.model.enums.OrderRejectCode;
import org.ta.pddserver.model.enums.StatusEnum;
import org.ta.pddserver.model.pddjy.request.JYBaseRequestModel;
import org.ta.pddserver.model.pddjy.request.PddServiceConsoCoBizActionNotifyRequest;
import org.ta.pddserver.model.pddjy.request.PddServiceConsoFirstBizActionNotifyRequest;
import org.ta.pddserver.model.pddjy.request.PddServiceConsoInboundRequest;
import org.ta.pddserver.service.impl.*;
import org.ta.pddserver.serviceutil.MailNoStatusOperator;
import org.ta.pddserver.utils.*;

import java.util.*;


@RestController
@RequestMapping("/work")
@Slf4j
public class FirstWorkController {

    @Resource
    MailNoStatusOperator mailNoStatusOperator;

    @Resource
    LogOrderMailDetailImpl logOrderMailDetailImpl;
    @Resource
    LogOrderImpl logOrderImpl;
    @Resource
    LogOrderMailDetailIoImpl logOrderMailDetailIoImpl;
    @Resource
    StorageImpl storageImpl;
    @Resource
    LogsMailScanImpl logsMailScanImpl;
    @Resource
    ShelvesImpl shelvesImpl;
    @Resource
    UnpackNoticeImpl unpackNoticeImpl;
    @Resource
    CollectOrderImpl collectOrderImpl;
    @Resource
    OutboundNoticeImpl outboundNoticeImpl;
    @Resource
    CollectMailDetailImpl collectMailDetailImpl;
    @Resource
    PackageDetailImpl packageDetailImpl;
    @Resource
    LogOrderPackageImpl logOrderPackageImpl;
    @Resource
    PackageNoticeImpl packageNoticeImpl;
    @Autowired
    private ExpMailLogsImpl expMailLogsImpl;
    @Resource
    PickRecordImpl pickRecordImpl;

    /* 查询一段包裹信息 */
    @Operation(
            summary = "查询一段包裹信息",
            description = "",
            deprecated = false      // 是否废弃
    )
    @PostMapping("/queryLogMail")
    public JSONObject queryLogMail(HttpServletRequest request, @RequestBody QueryLogMailRequest queryLogMailRequest) {
        String mailNo = queryLogMailRequest.getMailNo();
//        logsMailScanImpl.makeLog(mailNo, queryLogMailRequest.getAction());
        LogOrderMailDetailEntity mailDetailEntity = logOrderMailDetailImpl.getAllInfoByMailNo(mailNo);
        if (mailDetailEntity == null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "未找到包裹信息");
        }
        LogOrderEntity logOrderEntity = logOrderImpl.getByOrderCode(mailDetailEntity.getLogisticsOrderCode());

        Map<String, Object> map = new HashMap<>();
        map.put("mail", mailDetailEntity);
        map.put("logOrder", logOrderEntity);
        map.put("list", logOrderMailDetailImpl.getListByCode(mailDetailEntity.getLogisticsOrderCode()));
        map.put("status", mailNoStatusOperator.getMailByMailNo(mailNo));
        return JsonResponse.generateLocalCommonSuccessResponse(map, "查询成功");
    }


    /* 一段签收 */
    @Operation(
            summary = "一段签收",
            description = "",
            deprecated = false      // 是否废弃
    )
    @PostMapping("/receive")
    public JSONObject receive(HttpServletRequest request, @RequestBody ReceiveRequest receiveRequest) {
//        logsMailScanImpl.makeLog(receiveRequest.getMailNo(), "SIGN");
        LogOrderMailDetailEntity mailDetailEntity = logOrderMailDetailImpl.getAllInfoByMailNo(receiveRequest.getMailNo());
        if (mailDetailEntity == null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "未找到需签收包裹");
        }
        String msg = mailNoStatusOperator.checkCanHandle(receiveRequest.getMailNo(), MailNoStatusEnum.SIGNED);
        if (msg != null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, msg);
        }

        String action = "warehouse_sign";

        PddServiceConsoFirstBizActionNotifyRequest notifyRequest = new PddServiceConsoFirstBizActionNotifyRequest();
        notifyRequest.setProviderCode(PddAPIConfig.PROVIDER_CODE);
        notifyRequest.setExecuteTime(TimeTool.getNowString());
        notifyRequest.setTimeZone("UTC+8");
        notifyRequest.setLogisticsOrderCode(mailDetailEntity.getLogisticsOrderCode());
        notifyRequest.setBizAction(action);
        PddServiceConsoFirstBizActionNotifyRequest.Result notifyResult = new PddServiceConsoFirstBizActionNotifyRequest.Result();
        notifyRequest.setMailNo(mailDetailEntity.getMailNo());
        notifyRequest.setExpressCode(mailDetailEntity.getExpressCode());

        notifyRequest.setBizActionDesc("仓库签收");
        notifyResult.setCode(0);
        notifyRequest.setResult(notifyResult);
        JYBaseRequestModel requestModel = new JYBaseRequestModel();
        requestModel.setRequest(JSON.toJSONString(notifyRequest));
        requestModel.setRequest_id("" + new Date().getTime());
        requestModel.setType("pdd.service.conso.first.biz.action.notify");
        requestModel.setTarget_client_id(PddAPIConfig.CLIENT_ID);
        requestModel.setClient_id(PddAPIConfig.CLIENT_ID);
        long time = new Date().getTime() / 1000;
        requestModel.setTimestamp(time);
        requestModel.setSign(PddSignTool.generateSign(requestModel, PddAPIConfig.CLIENT_SECRET));
        String resp = PddHttpTool.sendJsonPost(requestModel);
        JSONObject jsonObject = JSON.parseObject(resp);
        JSONObject respObject = (JSONObject) jsonObject.get("response");
        if (!respObject.getBoolean("success")) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "拼多多上送信息失败：" + respObject.getString("message") + "；请联系技术人员。");
        }
        //更新log_order_mail_detail
        Boolean result = logOrderMailDetailImpl.updateByMailNo(mailDetailEntity.getMailNo(), StatusEnum.SIGNED.getCode());
        LogOrderMailDetailIoEntity logOrderMailDetailIoEntity = new LogOrderMailDetailIoEntity();
        logOrderMailDetailIoEntity.setStatus(StatusEnum.SIGNED.getCode());
        logOrderMailDetailIoEntity.setAction("RECEIVE");
        logOrderMailDetailIoEntity.setMailNo(mailDetailEntity.getMailNo());
        logOrderMailDetailIoEntity.setLogisticsOrderCode(mailDetailEntity.getLogisticsOrderCode());
        logOrderMailDetailIoEntity.setExpressCode(mailDetailEntity.getExpressCode());
        logOrderMailDetailIoEntity.setReq(JSON.toJSONString(requestModel));
        logOrderMailDetailIoEntity.setResp(resp);
        logOrderMailDetailIoImpl.save(logOrderMailDetailIoEntity);
        mailNoStatusOperator.changeStatus(mailDetailEntity.getMailNo(), MailNoStatusEnum.SIGNED);
        return JsonResponse.generateLocalCommonSuccessResponse(true, "签收成功");
    }

    /* 一段拒收 */
    @Operation(
            summary = "一段拒收",
            description = "",
            deprecated = false      // 是否废弃
    )
    @PostMapping("/reject")
    public JSONObject reject(HttpServletRequest request, @RequestBody ReceiveRequest receiveRequest) {
//        logsMailScanImpl.makeLog(receiveRequest.getMailNo(), "REJECT");
        LogOrderMailDetailEntity mailDetailEntity = logOrderMailDetailImpl.getAllInfoByMailNo(receiveRequest.getMailNo());
        if (mailDetailEntity == null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "未找到需签收包裹");
        }
        String msg = mailNoStatusOperator.checkCanHandle(receiveRequest.getMailNo(), MailNoStatusEnum.REJECTED);
        if (msg != null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, msg);
        }
        String action = "warehouse_reject_sign";
        PddServiceConsoFirstBizActionNotifyRequest notifyRequest = new PddServiceConsoFirstBizActionNotifyRequest();
        notifyRequest.setProviderCode(PddAPIConfig.PROVIDER_CODE);
        notifyRequest.setExecuteTime(TimeTool.getNowString());
        notifyRequest.setTimeZone("UTC+8");
        notifyRequest.setLogisticsOrderCode(mailDetailEntity.getLogisticsOrderCode());
        notifyRequest.setBizAction(action);
        PddServiceConsoFirstBizActionNotifyRequest.Result notifyResult = new PddServiceConsoFirstBizActionNotifyRequest.Result();
        notifyRequest.setMailNo(mailDetailEntity.getMailNo());
        notifyRequest.setExpressCode(mailDetailEntity.getExpressCode());
        notifyRequest.setBizActionDesc("仓库拒签");
        notifyResult.setCode(receiveRequest.getCode());
        notifyResult.setDesc(OrderRejectCode.getByCode(receiveRequest.getCode()).getDesc());
        notifyResult.setRemark(OrderRejectCode.getByCode(receiveRequest.getCode()).getRemark());
        if (receiveRequest.getLength() != null && receiveRequest.getLength() > 0) {

            notifyRequest.setPackageInfo(new PddServiceConsoFirstBizActionNotifyRequest.PackageInfo());
            notifyRequest.getPackageInfo().setWeight((long) PddJYPriceTool.calculateWeight((int) receiveRequest.getLength().longValue(), (int) receiveRequest.getWidth().longValue(), (int) receiveRequest.getHeight().longValue(), (int) receiveRequest.getWeight().longValue(), true));
            notifyRequest.getPackageInfo().setActualWeight(receiveRequest.getWeight());
            notifyRequest.getPackageInfo().setLength(receiveRequest.getLength());
            notifyRequest.getPackageInfo().setWidth(receiveRequest.getWidth());
            notifyRequest.getPackageInfo().setHeight(receiveRequest.getHeight());
        }
        notifyRequest.setResult(notifyResult);
        JYBaseRequestModel requestModel = new JYBaseRequestModel();
        requestModel.setRequest(JSON.toJSONString(notifyRequest));
        requestModel.setRequest_id("" + new Date().getTime());
        requestModel.setType("pdd.service.conso.first.biz.action.notify");
        requestModel.setTarget_client_id(PddAPIConfig.CLIENT_ID);
        requestModel.setClient_id(PddAPIConfig.CLIENT_ID);
        long time = new Date().getTime() / 1000;
        requestModel.setTimestamp(time);
        requestModel.setSign(PddSignTool.generateSign(requestModel, PddAPIConfig.CLIENT_SECRET));
        String resp = PddHttpTool.sendJsonPost(requestModel);
        JSONObject jsonObject = JSON.parseObject(resp);
        JSONObject respObject = (JSONObject) jsonObject.get("response");
        if (!respObject.getBoolean("success")) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "拼多多上送信息失败：" + respObject.getString("message") + "；请联系技术人员。");
        }
        //更新log_order_mail_detail
        Boolean result = logOrderMailDetailImpl.updateByMailNo(mailDetailEntity.getMailNo(), StatusEnum.REJECTED.getCode());
        LogOrderMailDetailIoEntity logOrderMailDetailIoEntity = new LogOrderMailDetailIoEntity();
        logOrderMailDetailIoEntity.setStatus(StatusEnum.REJECTED.getCode());
        logOrderMailDetailIoEntity.setAction("REJECT");
        logOrderMailDetailIoEntity.setMailNo(mailDetailEntity.getMailNo());
        logOrderMailDetailIoEntity.setLogisticsOrderCode(mailDetailEntity.getLogisticsOrderCode());
        logOrderMailDetailIoEntity.setExpressCode(mailDetailEntity.getExpressCode());
        logOrderMailDetailIoEntity.setReq(JSON.toJSONString(requestModel));
        logOrderMailDetailIoEntity.setResp(resp);
        logOrderMailDetailIoImpl.save(logOrderMailDetailIoEntity);
        mailNoStatusOperator.changeStatus(mailDetailEntity.getMailNo(), MailNoStatusEnum.REJECTED);
        return JsonResponse.generateLocalCommonSuccessResponse(true, "拒签成功");
    }

    /* 一段入库*/
    @Operation(
            summary = "入库",
            description = "",
            deprecated = false      // 是否废弃
    )
    @PostMapping("/inBound")
    public JSONObject inBound(HttpServletRequest request, @RequestBody InBoundRequest inBoundRequest) {
//        logsMailScanImpl.makeLog(inBoundRequest.getMailNo(), "INBOUND");
        LogOrderMailDetailEntity mailNoResponse = logOrderMailDetailImpl.getByMailNo(inBoundRequest.getMailNo());
        if (mailNoResponse == null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "未找到需入库包裹");
        }
        String msg = mailNoStatusOperator.checkCanHandle(inBoundRequest.getMailNo(), MailNoStatusEnum.INBOUND);
        if (msg != null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, msg);
        }
        PddServiceConsoInboundRequest notifyRequest = new PddServiceConsoInboundRequest();
        LogOrderEntity logOrderEntity = logOrderImpl.getByOrderCode(mailNoResponse.getLogisticsOrderCode());

        int num = logOrderMailDetailImpl.getInboundedCountByOrderCode(mailNoResponse.getLogisticsOrderCode());
        num += 1;

        notifyRequest.setPackageQuantity(1);

        notifyRequest.setProviderCode(PddAPIConfig.PROVIDER_CODE);
        notifyRequest.setLogisticsOrderCode(mailNoResponse.getLogisticsOrderCode());
        notifyRequest.setExecuteTime(TimeTool.getNowString());
        notifyRequest.setTimeZone("UTC+8");

        if (num >= logOrderEntity.getPackageQuantity()) {
            notifyRequest.setStatus("FULL_INBOUND");
        } else {
            notifyRequest.setStatus("FULL_INBOUND");
        }

        notifyRequest.setPackageInfo(new PddServiceConsoInboundRequest.PackageInfo());
        notifyRequest.getPackageInfo().setMailNo(mailNoResponse.getMailNo());
        notifyRequest.getPackageInfo().setExpressCode(mailNoResponse.getExpressCode());
        notifyRequest.getPackageInfo().setLength(inBoundRequest.getLength());
        notifyRequest.getPackageInfo().setHeight(inBoundRequest.getHeight());
        notifyRequest.getPackageInfo().setWidth(inBoundRequest.getWidth());
        notifyRequest.getPackageInfo().setActualWeight(inBoundRequest.getWeight());
        notifyRequest.getPackageInfo().setWeight((long) PddJYPriceTool.calculateWeight(inBoundRequest.getLength().intValue(), inBoundRequest.getWidth().intValue(), inBoundRequest.getHeight().intValue(), inBoundRequest.getWeight().intValue(), true));
        notifyRequest.getPackageInfo().setGoodsType(inBoundRequest.getGoodsType());

        notifyRequest.setResult(new PddServiceConsoInboundRequest.Result());
        notifyRequest.getResult().setCode(0);

        JYBaseRequestModel requestModel = new JYBaseRequestModel();
        requestModel.setRequest(JSON.toJSONString(notifyRequest));
        requestModel.setRequest_id("" + new Date().getTime());
        requestModel.setType("pdd.service.conso.inbound");
        requestModel.setTarget_client_id(PddAPIConfig.CLIENT_ID);
        requestModel.setClient_id(PddAPIConfig.CLIENT_ID);
        long time = new Date().getTime() / 1000;
        time += time % 5; // 延时4秒内
        requestModel.setTimestamp(time);
        requestModel.setSign(PddSignTool.generateSign(requestModel, PddAPIConfig.CLIENT_SECRET));
        String resp = PddHttpTool.sendJsonPost(requestModel);
        JSONObject jsonObject = JSON.parseObject(resp);
        JSONObject respObject = (JSONObject) jsonObject.get("response");
        if (!respObject.getBoolean("success")) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "拼多多上送信息失败：" + respObject.getString("message") + "；请联系技术人员。");
        }

        LogOrderMailDetailIoEntity logOrderMailDetailIoEntity = new LogOrderMailDetailIoEntity();
        logOrderMailDetailIoEntity.setMailNo(inBoundRequest.getMailNo());
        logOrderMailDetailIoEntity.setStatus(StatusEnum.INBOUND.getCode());
        logOrderMailDetailIoEntity.setLogisticsOrderCode(mailNoResponse.getLogisticsOrderCode());
        logOrderMailDetailIoEntity.setExpressCode(mailNoResponse.getExpressCode());
        logOrderMailDetailIoEntity.setReq(JSON.toJSONString(requestModel));
        logOrderMailDetailIoEntity.setResp(resp);
        logOrderMailDetailIoEntity.setAction("INBOUND");
        logOrderMailDetailIoImpl.save(logOrderMailDetailIoEntity);

        List<LogOrderMailDetailEntity> list =  logOrderMailDetailImpl.getListByMailNo(inBoundRequest.getMailNo());
        for (LogOrderMailDetailEntity mailDetailEntity : list) {
            //更新入库包裹状态
            mailDetailEntity.setEnterTime(TimeTool.getNowDate());
            mailDetailEntity.setStatus(StatusEnum.INBOUND.getCode());
            mailDetailEntity.setLength(inBoundRequest.getLength().intValue());
            mailDetailEntity.setWidth(inBoundRequest.getWidth().intValue());
            mailDetailEntity.setHeight(inBoundRequest.getHeight().intValue());
            mailDetailEntity.setWeight(inBoundRequest.getWeight().intValue());

            logOrderMailDetailImpl.updateById(mailDetailEntity);
        }
        logOrderEntity.setNum(notifyRequest.getPackageQuantity().intValue());

        //判断是否全部入库
        if (notifyRequest.getStatus().equals("FULL_INBOUND")) {
            //全部入库
            logOrderEntity.setStatus(StatusEnum.FULLINBOUND.getCode());
        } else {
            logOrderEntity.setStatus(StatusEnum.PARTINBOUND.getCode());
        }
        logOrderImpl.updateById(logOrderEntity);

        mailNoStatusOperator.changeStatus(mailNoResponse.getMailNo(), MailNoStatusEnum.INBOUND);

        return JsonResponse.generateLocalCommonSuccessResponse(true, "入库成功");
    }

    /**
     * 分配仓储位置
     *
     * @param request        httpRequest
     * @param storageRequest 分配库位请求参数
     * @return 回复消息
     */
    @RolesAllowed({"TEMPORARY", "WORKER", "ADMIN"})
    @PostMapping("/generatePosition")
    public JSONObject generatePosition(HttpServletRequest request, @RequestBody StorageRequest storageRequest) {
//        logsMailScanImpl.makeLog(storageRequest.getMailNo(), "GENERATE-POSITION");
        StorageEntity storageEntity = storageImpl.getInfoByMailNo(storageRequest.getMailNo());
        if (storageEntity != null) {
            return JsonResponse.generateLocalCommonSuccessResponse(storageEntity, "查询成功0");
        }
        //当前包裹未上架，开始分配上架
        LogOrderMailDetailEntity mailNoResponse = logOrderMailDetailImpl.getAllInfoByMailNo(storageRequest.getMailNo());
        if (mailNoResponse == null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "1包裹无记录");
        }
        String msg = mailNoStatusOperator.checkCanHandle(storageRequest.getMailNo(), MailNoStatusEnum.POSITION);
        if (msg != null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, msg);
        }

        StorageEntity storageEntity2 = new StorageEntity();
        // 根据集运单分配位置
        storageEntity = storageImpl.getInfoByLogisticsOrderCode(mailNoResponse.getLogisticsOrderCode());
        if (storageEntity != null) {
            storageEntity2.setLogisticsOrderCode(mailNoResponse.getLogisticsOrderCode());
            storageEntity2.setCode(storageEntity.getCode());
            storageEntity2.setMailNo(mailNoResponse.getMailNo());
            storageEntity2.setNum(0);
            storageEntity2.setBuyerCode(storageEntity.getBuyerCode());
            storageImpl.save(storageEntity2);
            String[] codes = storageEntity.getCode().split("-");
            shelvesImpl.updateNum(1, codes[0].substring(0, 1), Integer.parseInt(codes[0].substring(1)), Integer.parseInt(codes[1]));
            mailNoStatusOperator.changeStatus(mailNoResponse.getMailNo(), MailNoStatusEnum.POSITION, storageEntity2.getCode());
            return JsonResponse.generateLocalCommonSuccessResponse(storageEntity2, "分配成功1");
        }
        // 集运单未分配位置
        LogOrderEntity logOrderEntity = logOrderImpl.getByOrderCode(mailNoResponse.getLogisticsOrderCode());
        if (logOrderEntity == null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "2入库集运单无记录");
        }
        // 取该会员已经存在的其他的未知
        storageEntity = storageImpl.getByBuyerCode(logOrderEntity.getBuyerCode());
        if (storageEntity != null) {
            storageEntity2.setLogisticsOrderCode(mailNoResponse.getLogisticsOrderCode());
            storageEntity2.setCode(storageEntity.getCode());
            storageEntity2.setMailNo(mailNoResponse.getMailNo());
            storageEntity2.setNum(0);
            storageEntity2.setBuyerCode(storageEntity.getBuyerCode());
            storageImpl.save(storageEntity2);
            String[] codes = storageEntity.getCode().split("-");
            shelvesImpl.updateNum(1, codes[0].substring(0, 1), Integer.parseInt(codes[0].substring(1)), Integer.parseInt(codes[1]));
            mailNoStatusOperator.changeStatus(mailNoResponse.getMailNo(), MailNoStatusEnum.POSITION, storageEntity2.getCode());
            return JsonResponse.generateLocalCommonSuccessResponse(storageEntity2, "分配成功2");
        }
        ShelvesEntity shelvesEntity = shelvesImpl.getUsableOrdered();
        storageEntity2.setLogisticsOrderCode(mailNoResponse.getLogisticsOrderCode());
        storageEntity2.setCode(shelvesEntity.getLevel1() + shelvesEntity.getLevel2() + "-" + shelvesEntity.getLevel3());
        storageEntity2.setMailNo(mailNoResponse.getMailNo());
        storageEntity2.setNum(0);
        storageEntity2.setBuyerCode(logOrderEntity.getBuyerCode());
        storageImpl.save(storageEntity2);
        shelvesImpl.updateNum(1, shelvesEntity.getLevel1(), shelvesEntity.getLevel2(), shelvesEntity.getLevel3());
        mailNoStatusOperator.changeStatus(mailNoResponse.getMailNo(), MailNoStatusEnum.POSITION, storageEntity2.getCode());
        return JsonResponse.generateLocalCommonSuccessResponse(storageEntity2, "分配成功3");
    }


    /* 通过运单号查询存放区域准备上架 */
    @PostMapping("/waitOnBoard")
    public JSONObject waitOnBoard(HttpServletRequest request, @RequestBody StorageRequest storageRequest) {
//        logsMailScanImpl.makeLog(storageRequest.getMailNo(), "WAIT-ONBOARD");
        StorageResponse response = storageImpl.storageSelect(storageRequest.getMailNo());
        if (response != null) {
            if (response.getPlace() != null && !response.getPlace().isEmpty()) {
                response.setCode(response.getCode() + '>' + response.getPlace());
            }
        }
        return JsonResponse.generateLocalCommonSuccessResponse(response, "");
    }

    /**
     * PDA 上架
     *
     * @param request        httpRequest
     * @param storageRequest 上架请求参数
     * @return 回复消息
     */
    @RolesAllowed({"TEMPORARY", "WORKER", "ADMIN"})
    @PostMapping("/onBoard")
    public JSONObject onBoard(HttpServletRequest request, @RequestBody StorageRequest storageRequest) {
//        logsMailScanImpl.makeLog(storageRequest.getMailNo(), "ONBOARD");
        StorageEntity storageEntity = storageImpl.getInfoByMailNo(storageRequest.getMailNo());
        if (storageEntity == null) {
            return JsonResponse.generateLocalCommonFailedResponse("-1", "未查询到商品区域信息");
        }
        String msg = mailNoStatusOperator.checkCanHandle(storageRequest.getMailNo(), MailNoStatusEnum.ONBOARD);
        if (msg != null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, msg);
        }
        String code = storageEntity.getCode().split("-")[0];
        if (!storageRequest.getPlace().startsWith(code)) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "位置信息不匹配");
        }
        storageEntity.setPlace(storageRequest.getPlace());
        storageImpl.updateById(storageEntity);
        mailNoStatusOperator.changeStatus(storageEntity.getMailNo(), MailNoStatusEnum.ONBOARD, storageRequest.getPlace());
        return JsonResponse.generateLocalCommonSuccessResponse(true, "上架成功");
    }

    /**
     * PDA 扫码拣货
     *
     * @param request        httpRequest
     * @param storageRequest 上架请求参数
     * @return 回复消息
     */
    @RolesAllowed({"TEMPORARY", "WORKER", "ADMIN"})
    @PostMapping("/scanPick")
    public JSONObject scanPick(HttpServletRequest request, @RequestBody StorageRequest storageRequest) {
//        logsMailScanImpl.makeLog(storageRequest.getMailNo(), "SCAN-PICK");
        StorageEntity storageEntity = storageImpl.getInfoByMailNo(storageRequest.getMailNo());
        if (storageEntity == null) {
            return JsonResponse.generateLocalCommonFailedResponse("-1", "未查询到商品区域信息");
        }
        String msg = mailNoStatusOperator.checkCanHandle(storageRequest.getMailNo(), MailNoStatusEnum.PICKING);
        if (msg != null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, msg);
        }
        mailNoStatusOperator.changeStatus(storageEntity.getMailNo(), MailNoStatusEnum.PICKING);
        return JsonResponse.generateLocalCommonSuccessResponse(storageEntity, "拣货成功");
    }

    /**
     * PDA 扫码撤回拣货
     *
     * @param request        httpRequest
     * @param storageRequest 上架请求参数
     * @return 回复消息
     */
    @RolesAllowed({"TEMPORARY", "WORKER", "ADMIN"})
    @PostMapping("/scanPickDel")
    public JSONObject scanPickDel(HttpServletRequest request, @RequestBody StorageRequest storageRequest) {
//        logsMailScanImpl.makeLog(storageRequest.getMailNo(), "DEL-SCAN-PICK");
        StorageEntity storageEntity = storageImpl.getInfoByMailNo(storageRequest.getMailNo());
        if (storageEntity == null) {
            return JsonResponse.generateLocalCommonFailedResponse("-1", "未查询到商品区域信息");
        }
        String msg = mailNoStatusOperator.checkCanHandle(storageRequest.getMailNo(), MailNoStatusEnum.ONBOARD);
        if (msg != null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, msg);
        }
        mailNoStatusOperator.changeStatus(storageEntity.getMailNo(), MailNoStatusEnum.ONBOARD);
        return JsonResponse.generateLocalCommonSuccessResponse(storageEntity, "拣货撤回成功");
    }


    /*拣货下架*/
    @PostMapping("/storageDel")
    public JSONObject storageDel(HttpServletRequest request, @RequestBody StorageDelRequest storageDelRequest) {
        List<StorageListResponse> list = storageImpl.storageLists(storageDelRequest.getLogisticsOrderCode());

        List<String> toMailList = new ArrayList<>();
        List<StorageListResponse> toRemoveList = new ArrayList<>();
        Map<String, Integer> integerMap = new HashMap<>();

        if (list.size() != storageDelRequest.getMailNo().size()) {
            return JsonResponse.generateLocalCommonFailedResponse("-1", "下架包裹数量异常");
        }
        StorageListResponse first = list.get(0);

        String ids = "(";

        for (StorageListResponse lists : list) {
            for (String mailNoLists : storageDelRequest.getMailNo()) {
                if (lists.getMailNo().equals(mailNoLists)) {
                    if (integerMap.containsKey(lists.getCode())) {
                        integerMap.put(lists.getCode(), integerMap.get(lists.getCode()) + 1);
                    } else {
                        integerMap.put(lists.getCode(), 1);
                    }
                    toRemoveList.add(lists);
                    toMailList.add(mailNoLists);

                    ids += "'" + mailNoLists + "',";
                }
            }
        }

        ids = ids.substring(0, ids.length() - 1);
        ids += ")";

        list.removeAll(toRemoveList);
        storageDelRequest.getMailNo().removeAll(toMailList);

        if (list.size() != 0 || storageDelRequest.getMailNo().size() != 0) {
            return JsonResponse.generateLocalCommonFailedResponse("-1", "下架包裹信息异常");
        }
        for (StorageListResponse lists : toRemoveList) {
            String msg = mailNoStatusOperator.checkCanHandle(lists.getMailNo(), MailNoStatusEnum.PICKED);
            if (msg != null) {
                return JsonResponse.generateLocalCommonFailedResponse("-1", lists.getMailNo() + msg);
            }
        }

        for (StorageListResponse lists : toRemoveList) {
//            logsMailScanImpl.makeLog(lists.getMailNo(), "DOWNBOARD");
            mailNoStatusOperator.changeStatus(lists.getMailNo(), MailNoStatusEnum.PICKED);
        }

        //删除位置
        storageImpl.storageDel(ids);

        // 释放货架位置
        for (String code: integerMap.keySet()) {
            String[] codes = code.split("-");
            shelvesImpl.updateNum(-1, codes[0].substring(0, 1), Integer.parseInt(codes[0].substring(1)), Integer.parseInt(codes[1]));

        }

        //根据type 区分修改状态
        if (("pick").equals(storageDelRequest.getType())) {
            // 出库拣货下架
            outboundNoticeImpl.updateStatusByOrderCode(storageDelRequest.getLogisticsOrderCode(), StatusEnum.PICKDOWN.getCode());
            // todo 申报拣货完成
        } else {
            // 拆包下架
            unpackNoticeImpl.updateStatusByOrderCode(storageDelRequest.getLogisticsOrderCode(), StatusEnum.UNPACKFINISHPICK.getCode());
        }
        // 处理拣货单完成人
        PickRecordEntity pickRecordEntity = pickRecordImpl.getByOrderCode(storageDelRequest.getLogisticsOrderCode());
        String orderCode = storageDelRequest.getLogisticsOrderCode();
        if (pickRecordEntity != null) {
            if (pickRecordImpl.saveFinisher(pickRecordEntity)) {
                if (pickRecordEntity.getType() == 2 && orderCode.startsWith("PP")) {
                    // 申报拣货完成
                    this.completePick(orderCode);
                }
            }
        }

        return JsonResponse.generateLocalCommonSuccessResponse(true, "拣货下架成功");
    }

    /**
     * 扫码打包
     *
     * @param request        httpRequest
     * @param storageRequest 上架请求参数
     * @return 回复消息
     */
    @RolesAllowed({"TEMPORARY", "WORKER", "ADMIN"})
    @PostMapping("/scanPacking")
    public JSONObject scanPacking(HttpServletRequest request, @RequestBody StorageRequest storageRequest) {
//        logsMailScanImpl.makeLog(storageRequest.getMailNo(), "SCAN-PACKING");
        String msg = mailNoStatusOperator.checkCanHandle(storageRequest.getMailNo(), MailNoStatusEnum.PACKAGING);
        if (msg != null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, msg);
        }
        mailNoStatusOperator.changeStatus(storageRequest.getMailNo(), MailNoStatusEnum.PACKAGING);
        return JsonResponse.generateLocalCommonSuccessResponse(true, "打包扫码成功");
    }

    /* 打包完成 */
    @PostMapping("/packageComplete")
    public JSONObject packageComplete(HttpServletRequest request, @RequestBody PackageCompleteRequest completeRequest) {
        List<String> mailList = new ArrayList<>();
        String orderCode = completeRequest.getOrderCode();
        for (PackageCompleteRequest.OutPackage outPackage : completeRequest.getOutPackageList()) {
            mailList.addAll(outPackage.getOutBound());
        }
        for (String mailNo : mailList) {
            String msg = mailNoStatusOperator.checkCanHandle(mailNo, MailNoStatusEnum.PACKAGED);
            if (msg != null) {
                return JsonResponse.generateLocalCommonFailedResponse("-1", mailNo + msg);
            }
        }

        for (String mailNo : mailList) {
//            logsMailScanImpl.makeLog(mailNo, "PACKAGED");
            mailNoStatusOperator.changeStatus(mailNo, MailNoStatusEnum.PACKAGED);
        }
        boolean unpack = false;
        //获取所有可出库订单
        List<CollectMailDetailEntity> list = collectMailDetailImpl.getListByOrderCode(orderCode);
        if (list == null || list.isEmpty()) {
            unpack = true;
        }
        packageDetailImpl.removeByOrderCode(completeRequest.getOrderCode());
        List<PackageDetailEntity> results = new ArrayList<>();
        for (PackageCompleteRequest.OutPackage outPackage : completeRequest.getOutPackageList()) {
            PackageDetailEntity detailEntity = new PackageDetailEntity();
            detailEntity.setOrderCode(completeRequest.getOrderCode());
            detailEntity.setMailNo(outPackage.getMailNo());
            detailEntity.setWidth(outPackage.getWidth());
            detailEntity.setHeight(outPackage.getHeight());
            detailEntity.setLength(outPackage.getLength());
            detailEntity.setWeight(outPackage.getWeight());
            detailEntity.setInMails(JSONObject.toJSONString(outPackage.getOutBound()));
            detailEntity.setPackageType(outPackage.getPackageType());
            detailEntity.setOrderType(outPackage.getOrderType());
//            detailEntity.setOperator(SecurityContextHolder.getContext().getAuthentication().getName());
            packageDetailImpl.save(detailEntity);
            results.add(detailEntity);
        }
        if (!unpack) {
            CollectOrderEntity collectOrderEntity = collectOrderImpl.getAllInfoByOrderCode(orderCode);
            String info = "打包成功";
            return JsonResponse.generateLocalCommonSuccessResponse(completeRequest.getOutPackageList(), info);
        }
        log.info("拆包单，同时发送拆包信息");
        String action = "finish_unpack";

        PddServiceConsoCoBizActionNotifyRequest notifyRequest = new PddServiceConsoCoBizActionNotifyRequest();
        notifyRequest.setProviderCode(PddAPIConfig.PROVIDER_CODE);
        notifyRequest.setOrderCode(orderCode);
        notifyRequest.setBizAction(action);
        notifyRequest.setExecuteTime(TimeTool.getNowString());
        notifyRequest.setTimeZone("UTC+8");

        LogOrderMailDetailIoEntity logOrderMailDetailIoEntity = new LogOrderMailDetailIoEntity();
        PddServiceConsoCoBizActionNotifyRequest.Result notifyResult = new PddServiceConsoCoBizActionNotifyRequest.Result();
        CollectOrderEntity collectOrderEntity = new CollectOrderEntity();
        UnpackNoticeEntity unpackNoticeEntity = unpackNoticeImpl.getByCode(orderCode);

        notifyRequest.setBizActionDesc("拆包完成");
        notifyRequest.setUnpackRemark("");
        notifyResult.setCode(0);
        notifyRequest.setPackageInfos(new ArrayList<>());


        for (PackageCompleteRequest.OutPackage outPackage : completeRequest.getOutPackageList()) {

            PddServiceConsoCoBizActionNotifyRequest.PackageInfo packageInfo = new PddServiceConsoCoBizActionNotifyRequest.PackageInfo();
            packageInfo.setWeight(outPackage.getWeight());
            packageInfo.setWidth(outPackage.getWidth());
            packageInfo.setHeight(outPackage.getHeight());
            packageInfo.setLength(outPackage.getLength());
            packageInfo.setActualWeight(PddJYPriceTool.calculateWeight(outPackage.getLength(), outPackage.getWidth(), outPackage.getHeight(), outPackage.getWeight(), true));
            packageInfo.setConsoType(unpackNoticeEntity.getConsoType());
            packageInfo.setGoodsType(outPackage.getOrderType());
            notifyRequest.getPackageInfos().add(packageInfo);

            LogOrderPackageEntity logOrderPackageEntity = new LogOrderPackageEntity();
            logOrderPackageEntity.setStatus("" + logOrderMailDetailIoEntity.getStatus());
            logOrderPackageEntity.setLogisticsOrderCode(orderCode);
            logOrderPackageEntity.setPackageType(outPackage.getOrderType());
            logOrderPackageEntity.setLength(outPackage.getLength());
            logOrderPackageEntity.setWidth(outPackage.getWidth());
            logOrderPackageEntity.setHeight(outPackage.getHeight());
            logOrderPackageEntity.setWeight(outPackage.getWeight());
            logOrderPackageImpl.save(logOrderPackageEntity);

            PackageNoticeEntity packageNoticeEntity = packageNoticeImpl.getByOrderCode(orderCode);

            if (packageNoticeEntity != null) {
                packageNoticeEntity.setStatus("" + logOrderMailDetailIoEntity.getStatus());
                packageNoticeImpl.updateById(packageNoticeEntity);
            }


        }
        notifyRequest.setResult(notifyResult);

        JYBaseRequestModel requestModel = new JYBaseRequestModel();
        requestModel.setRequest(JSON.toJSONString(notifyRequest));
        requestModel.setRequest_id("" + new Date().getTime());
        requestModel.setType("pdd.service.conso.co.biz.action.notify");
        requestModel.setTarget_client_id(PddAPIConfig.CLIENT_ID);
        requestModel.setClient_id(PddAPIConfig.CLIENT_ID);
        long time = new Date().getTime() / 1000;
        requestModel.setTimestamp(time);
        requestModel.setSign(PddSignTool.generateSign(requestModel, PddAPIConfig.CLIENT_SECRET));
        String resp = PddHttpTool.sendJsonPost(requestModel);
        JSONObject jsonObject = JSON.parseObject(resp);
        JSONObject respObject = (JSONObject) jsonObject.get("response");
        if (!respObject.getBoolean("success")) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "拼多多上送信息失败：" + respObject.getString("message") + "；请联系技术人员。");
        }


//        logOrderMailDetailIoEntity.setMailNo(finishUnpackRequest.getMailNo());
        logOrderMailDetailIoEntity.setLogisticsOrderCode(orderCode);
        logOrderMailDetailIoEntity.setReq(JSON.toJSONString(requestModel));
        logOrderMailDetailIoEntity.setResp(resp);
        logOrderMailDetailIoEntity.setAction("FINISH-UNPACK");
        logOrderMailDetailIoImpl.save(logOrderMailDetailIoEntity);
        return JsonResponse.generateLocalCommonSuccessResponse(completeRequest.getOutPackageList(), "打包成功且拆包成功");
    }

    // 拣货完成集合函数
    public String completePick(String orderCode) {
        PddServiceConsoCoBizActionNotifyRequest notifyRequest = new PddServiceConsoCoBizActionNotifyRequest();
        notifyRequest.setProviderCode(PddAPIConfig.PROVIDER_CODE);
        notifyRequest.setOrderCode(orderCode);
        notifyRequest.setBizAction("finish_pick");
        notifyRequest.setExecuteTime(TimeTool.getNowString());
        notifyRequest.setTimeZone("UTC+8");

        LogOrderMailDetailIoEntity logOrderMailDetailIoEntity = new LogOrderMailDetailIoEntity();

        PddServiceConsoCoBizActionNotifyRequest.Result notifyResult = new PddServiceConsoCoBizActionNotifyRequest.Result();
        logOrderMailDetailIoEntity.setStatus(StatusEnum.FINISHPICK.getCode());

        notifyRequest.setBizActionDesc("拣货完成");
        notifyResult.setCode(0);
        notifyRequest.setResult(notifyResult);

        JYBaseRequestModel requestModel = new JYBaseRequestModel();
        requestModel.setRequest(JSON.toJSONString(notifyRequest));
        requestModel.setRequest_id("" + new Date().getTime());
        requestModel.setType("pdd.service.conso.co.biz.action.notify");
        requestModel.setTarget_client_id(PddAPIConfig.CLIENT_ID);
        requestModel.setClient_id(PddAPIConfig.CLIENT_ID);
        long time = new Date().getTime() / 1000;
        requestModel.setTimestamp(time);
        requestModel.setSign(PddSignTool.generateSign(requestModel, PddAPIConfig.CLIENT_SECRET));
        String resp = PddHttpTool.sendJsonPost(requestModel);
        JSONObject jsonObject = JSON.parseObject(resp);
        JSONObject respObject = (JSONObject) jsonObject.get("response");
        if (!respObject.getBoolean("success")) {
            return "拼多多上送拣货完成信息失败：" + respObject.getString("message") + "；请联系技术人员。";
        }

        logOrderMailDetailIoEntity.setLogisticsOrderCode(orderCode);
        logOrderMailDetailIoEntity.setReq(JSON.toJSONString(requestModel));
        logOrderMailDetailIoEntity.setResp(resp);
        logOrderMailDetailIoEntity.setAction("FINISH-PICK");
        logOrderMailDetailIoImpl.save(logOrderMailDetailIoEntity);

        collectOrderImpl.updateStatusByOrderCode(logOrderMailDetailIoEntity.getStatus(), orderCode);

        return null;
    }

    /**
     * 修正包裹状态
     *
     * @param request        httpRequest
     * @param storageRequest 上架请求参数
     * @return 回复消息
     */
    @RolesAllowed({"TEMPORARY", "WORKER", "ADMIN"})
    @PostMapping("/collectToPicked")
    public JSONObject collectToPicked(HttpServletRequest request, @RequestBody StorageRequest storageRequest) {
        mailNoStatusOperator.changeStatus(storageRequest.getMailNo(), MailNoStatusEnum.PICKED);
        return JsonResponse.generateLocalCommonSuccessResponse(true, "修复成功");
    }

    /**
     * PDA 扫码记录查询
     *
     * @param request        httpRequest
     * @param storageRequest 查询参数
     * @return 回复消息
     */
    @RolesAllowed({"WORKER", "ADMIN"})
    @PostMapping("/scanRecordList")
    public JSONObject scanRecordList(HttpServletRequest request, @RequestBody StorageRequest storageRequest) {
//        List<LogsMailScanEntity> list = logsMailScanImpl.getByMail(storageRequest.getMailNo());
        Map<String, Object> map = new HashMap<>();
        map.put("list", null);
        return JsonResponse.generateLocalCommonSuccessResponse(map, "查询成功");
    }

    /**
     * PDA 扫码记录查询
     *
     * @param request        httpRequest
     * @param storageRequest 查询参数
     * @return 回复消息
     */
    @RolesAllowed({"WORKER", "ADMIN"})
    @PostMapping("/flowRecord")
    public JSONObject flowRecord(HttpServletRequest request, @RequestBody StorageRequest storageRequest) {
        Map<String, Object> map = new HashMap<>();
        map.put("list", expMailLogsImpl.getByMail(storageRequest.getMailNo()));
        return JsonResponse.generateLocalCommonSuccessResponse(map, "查询成功");
    }


    /* 通过运单号查询存放区域盘点用 */
    @PostMapping("/getStorage")
    public JSONObject getStorage(HttpServletRequest request, @RequestBody StorageRequest storageRequest) {
//        logsMailScanImpl.makeLog(storageRequest.getMailNo(), "STOCKTAKING");
        StorageEntity response = storageImpl.getInfoByMailNo(storageRequest.getMailNo());
        if (response == null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "未找到上架信息");
        }
        return JsonResponse.generateLocalCommonSuccessResponse(response, "");
    }

    /* 通过库位查询包裹列表 */
    @PostMapping("/storageList")
    public JSONObject storageList(HttpServletRequest request, @RequestBody StorageRequest storageRequest) {
        List<StorageEntity> response = storageImpl.getListByPlace(storageRequest.getMailNo());
        if (response == null || response.isEmpty()) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "货位未记录上架信息");
        }
        return JsonResponse.generateLocalCommonSuccessResponse(response, "");
    }

    /* 拣货接单情况 */
    @Operation(
            summary = "分页查询拆包列表",
            description = "",
            deprecated = false      // 是否废弃
    )
    @PostMapping("/pickRecordList")
    public JSONObject pickRecordList(HttpServletRequest request, @RequestBody PackageNoticeRequest packageNoticeRequest) {

        return JsonResponse.generateLocalCommonSuccessResponse(pickRecordImpl.recordList(packageNoticeRequest), "");
    }

}
