package org.ta.pddserver.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.Operation;
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.*;
import org.ta.pdd.entity.*;
import org.ta.pddserver.config.PddAPIConfig;
import org.ta.pddserver.model.api.request.*;
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.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.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/operation")
@RolesAllowed({"WORKER", "ADMIN"})
public class OperationController {

    @Resource
    LogOrderMailDetailImpl logOrderMailDetailImpl;
    @Resource
    LogOrderImpl logOrderImpl;
    @Resource
    LogOrderMailDetailIoImpl logOrderMailDetailIoImpl;
    @Resource
    StorageImpl storageImpl;
    @Resource
    UnpackNoticeImpl unpackNoticeImpl;
    @Resource
    OutboundNoticeImpl outboundNoticeImpl;
    @Resource
    PackageDetailImpl packageDetailImpl;
    @Resource
    TempStorageImpl tempStorageImpl;
    @Resource
    LogsMailScanImpl logsMailScanImpl;
    @Resource
    OutboundRecordImpl outboundRecordImpl;
    @Resource
    private LogsPddIoImpl logsPddIoImpl;
    @Resource
    private LogOrderMailDetailIoImpl logOrderMailDetailIo;
    @Resource
    private LogsPddDownImpl logsPddDownImpl;
    @Resource
    TraceObjectImpl traceObjectImpl;
    @Resource
    MailNoStatusOperator mailNoStatusOperator;

    /* 签收 */
    @Operation(
            summary = "签收",
            description = "",
            deprecated = false      // 是否废弃
    )
    @PostMapping("/receive")
    public JSONObject receive(HttpServletRequest request, @RequestBody ReceiveRequest receiveRequest) {
        LogOrderMailDetailEntity mailDetailEntity = logOrderMailDetailImpl.getAllInfoByMailNo(receiveRequest.getMailNo());

        if (mailDetailEntity == null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "未找到需签收包裹");
        }

        boolean key = false;

        String str = "";

        String action = receiveRequest.getAction();

        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());

        LogOrderMailDetailIoEntity logOrderMailDetailIoEntity = new LogOrderMailDetailIoEntity();

        if (action.equals("warehouse_sign")) {
            notifyRequest.setBizActionDesc("仓库签收");
            notifyResult.setCode(0);
            logOrderMailDetailIoEntity.setStatus(StatusEnum.SIGNED.getCode());

            str = "签收成功";
            logOrderMailDetailIoEntity.setAction("RECEIVE");

        } else if (action.equals("warehouse_reject_sign")) {
            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);
            logOrderMailDetailIoEntity.setStatus(StatusEnum.REJECTED.getCode());
            logOrderMailDetailIoEntity.setAction("REJECT");

            str = "仓库拒签";
        } else if (action.equals("destroy")) {
            notifyRequest.setBizActionDesc("包裹销毁");
            notifyResult.setCode(0);
            logOrderMailDetailIoEntity.setStatus(StatusEnum.DESTROY.getCode());
            logOrderMailDetailIoEntity.setAction("DESTROY");

            str = "包裹销毁";
        }

        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(receiveRequest.getMailNo(), logOrderMailDetailIoEntity.getStatus());

        logOrderMailDetailIoEntity.setMailNo(receiveRequest.getMailNo());

        logOrderMailDetailIoEntity.setLogisticsOrderCode(mailDetailEntity.getLogisticsOrderCode());
        logOrderMailDetailIoEntity.setExpressCode(mailDetailEntity.getExpressCode());
        logOrderMailDetailIoEntity.setReq(JSON.toJSONString(requestModel));
        logOrderMailDetailIoEntity.setResp(resp);

        logOrderMailDetailIoImpl.save(logOrderMailDetailIoEntity);

        logOrderImpl.updateReceiveNum(1, mailDetailEntity.getLogisticsOrderCode());

        return JsonResponse.generateLocalCommonSuccessResponse(true, str);
    }

    /*入库*/
    @Operation(
            summary = "入库",
            description = "",
            deprecated = false      // 是否废弃
    )
    @PostMapping("/inBound")
    public JSONObject inBound(HttpServletRequest request, @RequestBody InBoundRequest inBoundRequest) {
        LogOrderMailDetailEntity mailNoResponse = logOrderMailDetailImpl.getByMailNo(inBoundRequest.getMailNo());
        PddServiceConsoInboundRequest notifyRequest = new PddServiceConsoInboundRequest();
        LogOrderEntity logOrderEntity = logOrderImpl.getByOrderCode(mailNoResponse.getLogisticsOrderCode());
        int currNum = logOrderEntity.getNum();
        int num = logOrderMailDetailImpl.getInboundedCountByOrderCode(mailNoResponse.getLogisticsOrderCode());

        //判断是否存在入库信息
        if (mailNoResponse.getStatus() == StatusEnum.INBOUND.getCode()) {
            //重复入库
            mailNoResponse.setEnterTime(TimeTool.getNowDate());
        } else {
            mailNoResponse.setEnterTime(TimeTool.getNowDate());
            mailNoResponse.setStatus(StatusEnum.INBOUND.getCode());
            num += 1;
        }
        notifyRequest.setPackageQuantity(num);
        mailNoResponse.setLength(inBoundRequest.getLength().intValue());
        mailNoResponse.setWidth(inBoundRequest.getWidth().intValue());
        mailNoResponse.setHeight(inBoundRequest.getHeight().intValue());
        mailNoResponse.setWeight(inBoundRequest.getWeight().intValue());

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

        log.info("已入库数量 {} ； 全部数量 {}", num, logOrderEntity.getPackageQuantity());
        if (currNum >= logOrderEntity.getPackageQuantity()) {
            notifyRequest.setStatus("FULL_INBOUND");
        } else {
            notifyRequest.setStatus("PART_INBOUND");
        }

        notifyRequest.setPackageInfo(new PddServiceConsoInboundRequest.PackageInfo());
        notifyRequest.getPackageInfo().setMailNo(mailNoResponse.getMailNo());
        notifyRequest.getPackageInfo().setExpressCode(mailNoResponse.getExpressCode());
        notifyRequest.getPackageInfo().setLength(inBoundRequest.getLength());
        notifyRequest.getPackageInfo().setActualWeight(inBoundRequest.getWidth());
        notifyRequest.getPackageInfo().setHeight(inBoundRequest.getHeight());
        notifyRequest.getPackageInfo().setWidth(inBoundRequest.getWidth());
        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;
        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.setExpressCode(mailNoResponse.getExpressCode());
        logOrderMailDetailIoEntity.setStatus(StatusEnum.INBOUND.getCode());
        logOrderMailDetailIoEntity.setLogisticsOrderCode(mailNoResponse.getLogisticsOrderCode());
        logOrderMailDetailIoEntity.setExpressCode(mailNoResponse.getExpressCode());
        logOrderMailDetailIoEntity.setReq(JSON.toJSONString(requestModel));
        logOrderMailDetailIoEntity.setResp(resp);

        logOrderMailDetailIoImpl.save(logOrderMailDetailIoEntity);

        //更新入库包裹状态
        mailNoResponse.setStatus(logOrderMailDetailIoEntity.getStatus());
        mailNoResponse.setEnterTime(TimeTool.getNowDate());
        logOrderMailDetailImpl.updateById(mailNoResponse);

        logOrderEntity.setNum(notifyRequest.getPackageQuantity().intValue());

        //判断是否全部入库
        if (notifyRequest.getPackageQuantity() <= num) {
            //全部入库
            logOrderEntity.setStatus(StatusEnum.FULLINBOUND.getCode());
        } else {
            logOrderEntity.setStatus(StatusEnum.PARTINBOUND.getCode());
        }

        logOrderImpl.updateById(logOrderEntity);

        return JsonResponse.generateLocalCommonSuccessResponse(true, "");
    }


    /*统计数字*/
    @Operation(
            summary = "统计数字",
            description = "",
            deprecated = false      // 是否废弃
    )
    @RolesAllowed("ADMIN")
    @PostMapping("/statics")
    public JSONObject statics(HttpServletRequest request) {
        String today = TimeTool.getNowDate() + " 00:00:00";
        Map<String, Long> result = new HashMap<>();
        // 集运单下发
        result.put("logisticAll", logOrderImpl.count());
        result.put("logisticToday", logOrderImpl.countFromDate(today));

        // 包裹下发
        result.put("logMailAll", logOrderMailDetailImpl.count());
        result.put("logMailToday", logOrderMailDetailImpl.countFromDate(today));

        // 拆包通知下发
        result.put("unpackNoticeAll", unpackNoticeImpl.count());
        result.put("unpackNoticeToday", unpackNoticeImpl.countFromDate(today));

        // 出库下发
        result.put("outboundNoticeAll", outboundNoticeImpl.count());
        result.put("outboundNoticeToday", outboundNoticeImpl.countFromDate(today));

        // 入库包裹
        result.put("inboundAll", logOrderMailDetailImpl.countEntered());
        result.put("inboundToday", logOrderMailDetailImpl.countEnteredFromDate(TimeTool.getNowDate()));

        // 打包数量
        result.put("packageAll", packageDetailImpl.count());
        result.put("packageToday", packageDetailImpl.countToday(today));

        // 申报出库单数量
        result.put("outboundOrderAll", logOrderMailDetailIoImpl.countOutboundOrder());
        result.put("outboundOrderToday", logOrderMailDetailIoImpl.countOutboundOrderFromDate(today));

        // 出库包裹数量
        result.put("outboundPackageAll", logOrderMailDetailIoImpl.countOutboundPackage());
        result.put("outboundPackageToday", logOrderMailDetailIoImpl.countOutboundPackageDate(today));

        // 在架包裹数量
        result.put("storageAll", storageImpl.count()); // 总数量
        result.put("storageOned", storageImpl.countOned());

        // 在架临时包裹数量
        result.put("tempStorageAll", tempStorageImpl.count());

        // 拆包数量
//        result.put("inboundAll", logOrderMailDetailImpl.countEntered());
//        result.put("inboundToday", logOrderMailDetailImpl.countEnteredFromDate(today));

        // 出库包裹数量
//        result.put("inboundAll", logOrderMailDetailImpl.countEntered());
//        result.put("inboundToday", logOrderMailDetailImpl.countEnteredFromDate(today));

        return JsonResponse.generateLocalCommonSuccessResponse(result, "");
    }

    @GetMapping("/calculateData")
    public JSONObject calculateData(HttpServletRequest request) {
        String body = HttpRequestHandlerTool.getStringFromRequest(request);
        log.info("{} calculateData:{}", HttpRequestHandlerTool.getClientIP(request), body);
        return JsonResponse.generateLocalCommonSuccessResponse(true, "");
    }


    /*未上架货物查看列表*/
    @Operation(summary = "未上架货物查看",description = "",deprecated = false)
    @PostMapping("/notListedStorageList")
    public JSONObject notListedStorageList(HttpServletRequest request, @RequestBody StorageListVORequest param) {
        return JsonResponse.generateLocalCommonSuccessResponse(storageImpl.notListedStorageList(param), "");
    }

    /*货物查看列表*/
    @Operation(summary = "货架货物查看",description = "",deprecated = false)
    @PostMapping("/storageListPage")
    public JSONObject storageListPage(HttpServletRequest request, @RequestBody StorageListVORequest param) {
        return JsonResponse.generateLocalCommonSuccessResponse(storageImpl.storageListPage(param), "");
    }

    /*查看扫码记录列表*/
    @Operation(summary = "查看扫码记录列表",description = "",deprecated = false)
    @PostMapping("/logsMailScanList")
    public JSONObject logsMailScanList(HttpServletRequest request, @RequestBody LogsMailScanListVORequest param) {
//        return JsonResponse.generateLocalCommonSuccessResponse(logsMailScanImpl.logsMailScanList(param), "");
        return JsonResponse.generateOpenCommonFailedResponse(-1, "系统已经停用");
    }

    /*查看出库记录列表*/
    @Operation(summary = "查看出库记录列表",description = "",deprecated = false)
    @PostMapping("/outboundRecordList")
    public JSONObject outboundRecordList(HttpServletRequest request, @RequestBody OutboundRecordRequest param) {
        return JsonResponse.generateLocalCommonSuccessResponse(outboundRecordImpl.outboundRecordList(param), "");
    }

    /* 查看通信记录1 */
    @Operation(summary = "查看通信记录1",description = "",deprecated = false)
    @PostMapping("/keywordSearch1")
    public JSONObject keywordSearch1(HttpServletRequest request, @RequestBody KeywordRequest param) {
        Map<String, Object> map = new HashMap<>();
        map.put("list", logsPddIoImpl.getByKeyWord(param.getKeyword()));
        return JsonResponse.generateLocalCommonSuccessResponse(map, "查询成功");
    }

    /* 查看通信记录详情1 */
    @Operation(summary = "查看通信记录详情1",description = "",deprecated = false)
    @PostMapping("/contactDetail1")
    public JSONObject contactDetail1(HttpServletRequest request, @RequestBody KeywordRequest param) {
        LogsPddIoEntity entity = logsPddIoImpl.getById(param.getKeyword());
        if (entity == null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "未找到信息");
        }
        return JsonResponse.generateLocalCommonSuccessResponse(entity, "查询成功");
    }

    /* 查看通信记录2 */
    @Operation(summary = "查看通信记录2",description = "",deprecated = false)
    @PostMapping("/keywordSearch2")
    public JSONObject keywordSearch2(HttpServletRequest request, @RequestBody KeywordRequest param) {
        Map<String, Object> map = new HashMap<>();
        map.put("list", logOrderMailDetailIo.getByKeyWord(param.getKeyword()));
        return JsonResponse.generateLocalCommonSuccessResponse(map, "查询成功");
    }

    /* 查看通信记录详情2 */
    @Operation(summary = "查看通信记录详情2",description = "",deprecated = false)
    @PostMapping("/contactDetail2")
    public JSONObject contactDetail2(HttpServletRequest request, @RequestBody KeywordRequest param) {
        LogOrderMailDetailIoEntity entity = logOrderMailDetailIo.getById(param.getKeyword());
        if (entity == null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "未找到信息");
        }
        return JsonResponse.generateLocalCommonSuccessResponse(entity, "查询成功");
    }

    /* 查看拼多多下发记录 */
    @Operation(summary = "查看拼多多下发记录",description = "",deprecated = false)
    @PostMapping("/keywordSearch3")
    public JSONObject keywordSearch3(HttpServletRequest request, @RequestBody KeywordRequest param) {
        Map<String, Object> map = new HashMap<>();
        map.put("list", logsPddDownImpl.getListByKeyword(param.getKeyword()));
        return JsonResponse.generateLocalCommonSuccessResponse(map, "查询成功");
    }

    /* 查看拼多多下发记录详情 */
    @Operation(summary = "查看拼多多下发记录详情",description = "",deprecated = false)
    @PostMapping("/contactDetail3")
    public JSONObject contactDetail3(HttpServletRequest request, @RequestBody KeywordRequest param) {
        LogsPddDownEntity entity = logsPddDownImpl.getById(param.getKeyword());
        if (entity == null) {
            return JsonResponse.generateOpenCommonFailedResponse(-1, "未找到信息");
        }
        return JsonResponse.generateLocalCommonSuccessResponse(entity, "查询成功");
    }

    /* 查看出库物流轨迹详情 */
    @Operation(summary = "查看出库物流轨迹详情",description = "",deprecated = false)
    @PostMapping("/traceList")
    public JSONObject traceList(HttpServletRequest request, @RequestBody KeywordRequest param) {
        Map<String, Object> map = new HashMap<>();
        map.put("list", traceObjectImpl.getListByOrderCode(param.getKeyword()));
        return JsonResponse.generateLocalCommonSuccessResponse(map, "查询成功");
    }
}
