package com.ruoyi.logistics.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.redis.service.RedisIdGenerator;
import com.ruoyi.logistics.config.SFExpressConfig;
import com.ruoyi.logistics.domain.BizWaybillOrder;
import com.ruoyi.logistics.domain.LogisticsOrder;
import com.ruoyi.logistics.service.LogisticsService;
import com.ruoyi.logistics.util.SFExpressHttpUtil;
import com.ruoyi.system.controller.SysUserController;
import com.sf.csim.express.service.CallExpressServiceTools;
import com.sf.csim.express.service.HttpClientUtil;
import com.sf.csim.express.service.IServiceCodeStandard;
import com.sf.csim.express.service.code.ExpressServiceCodeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 顺丰物流实现
 *
 * @author RuiJing
 * @date 2026-02-02
 */
@Service
public class SFLogisticsService implements LogisticsService {
    private static final Logger log = LoggerFactory.getLogger(SFLogisticsService.class);

    @Autowired
    private SFExpressConfig sfExpressConfig;


    /**
     * 顺丰物流预下单接口
     *
     * @author zxf
     * @date 2026-02-02
     */
    @Override
    public JSONObject precheckOrder(BizWaybillOrder bizWaybillOrder) {
        SFExpressHttpUtil sfExpressHttpUtil = new SFExpressHttpUtil(sfExpressConfig.getClientCode(), sfExpressConfig.getCheckWord(), sfExpressConfig.getCurrentApiUrl());
        String serviceCode = "EXP_RECE_PRE_ORDER";
        /* 物流预下单请求参数*/
        JSONObject msgData = new JSONObject();
        //预下单接口已拿到订单id 下单需要用到这个id

        msgData.put("orderId", bizWaybillOrder.getWaybillNo());
        msgData.put("cargoName", bizWaybillOrder.getGoodsName());
        msgData.put("monthlyCard", sfExpressConfig.getMonthlyCord());
        msgData.put("totalWeight", bizWaybillOrder.getGoodsWeight());
       /* 快递产品类别  目前未定义  先写死
        1 顺丰特快
        2 顺丰标快
        6 顺丰即日*/
        msgData.put("expressTypeId", bizWaybillOrder.getProductCode());
        //包裹数  未定义  非必填
        msgData.put("parcelQty", bizWaybillOrder.getGoodsQty());
        //收寄方地址参数
        List<Map<String, Object>> contactInfoList = new ArrayList<>();
        Map<String, Object> Consignor = new HashMap<>();
        Consignor.put("contactType",1);
        Consignor.put("mobile", bizWaybillOrder.getSenderPhone());
        Consignor.put("province", bizWaybillOrder.getSenderProvince());
        Consignor.put("city", bizWaybillOrder.getSenderCity());
        Consignor.put("county", bizWaybillOrder.getSenderCounty());
        Consignor.put("address", bizWaybillOrder.getSenderAddress());
        contactInfoList.add(Consignor);
        Map<String, Object> Consignee = new HashMap<>();
        Consignee.put("contactType", 2);
        Consignee.put("mobile", bizWaybillOrder.getReceiverPhone());
        Consignee.put("province", bizWaybillOrder.getReceiverProvince());
        Consignee.put("city", bizWaybillOrder.getReceiverCity());
        Consignee.put("county", bizWaybillOrder.getReceiverCounty());
        Consignee.put("address", bizWaybillOrder.getReceiverAddress());
        contactInfoList.add(Consignee);
        msgData.put("contactInfoList",contactInfoList);
        String result = sfExpressHttpUtil.sendRequest(serviceCode, msgData.toJSONString());
        JSONObject jsonObject = JSON.parseObject(result).getJSONObject("apiResultData");
        JSONObject resultInfo = new JSONObject();
        if (jsonObject != null && jsonObject.containsKey("success") && jsonObject.getBooleanValue("success")) {
            resultInfo.put("success", true);
            resultInfo.put("msg", "预下单校验成功！");
            return resultInfo;
        } else {
            resultInfo.put("success", false);
            resultInfo.put("msg", "预下单校验失败！失败原因："+jsonObject.get("errorMsg"));
            return resultInfo;
        }


    }
    /**
     * 顺丰物流下单接口
     *
     * @author zxf
     * @date 2026-02-02
     */
    @Override
    public JSONObject createOrder(BizWaybillOrder bizWaybillOrder) throws JsonProcessingException {
        IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_CREATE_ORDER; //下订单
        CallExpressServiceTools tools=CallExpressServiceTools.getInstance();
        Map<String, String> params = new HashMap<String, String>();
        String timeStamp = String.valueOf(System.currentTimeMillis());
        Map<String,Object> orderData= new HashMap<>();
        orderData.put("language","zh_CN");
        //预下单 已返回订单id
        orderData.put("orderId",bizWaybillOrder.getWaybillNo());
        orderData.put("monthlyCard",sfExpressConfig.getMonthlyCord());//月结账户
        //上门取件时间
        // 定义日期格式
        orderData.put("sendStartTm",bizWaybillOrder.getSendStartTime());
        //包裹数
        orderData.put("parcelQty",bizWaybillOrder.getGoodsQty());
        //产品类别
        orderData.put("expressTypeId",bizWaybillOrder.getProductCode());
        //商品信息
        List<Map<String,Object>> cargoDetails = new ArrayList<>();
        Map cargo=new HashMap<>();
        cargo.put("name",bizWaybillOrder.getGoodsName());
        cargo.put("count",bizWaybillOrder.getGoodsQty());
        cargo.put("weight",bizWaybillOrder.getGoodsWeight());
        cargoDetails.add(cargo);
        orderData.put("cargoDetails",cargoDetails);
        //将增值服务字符串转换完增值服务参数
        List<Map<String,Object>> serviceList=getAddedProducts(bizWaybillOrder.getAddedService());
        orderData.put("serviceList",serviceList);
        //收寄双方信息
        List<Map<String,Object>> contactInfoList = new ArrayList<>();
        Map<String,Object> Consignor= new HashMap<>();
        Consignor.put("contactType","1");
        Consignor.put("contact",bizWaybillOrder.getSenderName());
        Consignor.put("mobile",bizWaybillOrder.getSenderPhone());
        Consignor.put("province",bizWaybillOrder.getSenderProvince());
        Consignor.put("city",bizWaybillOrder.getSenderCity());
        Consignor.put("county",bizWaybillOrder.getSenderCounty());
        Consignor.put("address",bizWaybillOrder.getSenderAddress());
        contactInfoList.add(Consignor);
        Map<String,Object> Consignee= new HashMap<>();
        Consignee.put("contactType","2");
        Consignor.put("contact",bizWaybillOrder.getReceiverName());
        Consignee.put("mobile",bizWaybillOrder.getReceiverPhone());
        Consignee.put("province",bizWaybillOrder.getReceiverProvince());
        Consignee.put("city",bizWaybillOrder.getReceiverCity());
        Consignee.put("county",bizWaybillOrder.getReceiverCounty());
        Consignee.put("address",bizWaybillOrder.getReceiverAddress());
        contactInfoList.add(Consignee);
        orderData.put("contactInfoList",contactInfoList);
        try {
        String msgData =tools.packageMsgData(standardService);
        msgData= JSON.toJSONString(orderData);
        params.put("partnerID", sfExpressConfig.getClientCode());  // 顾客编码 ，对应丰桥上获取的clientCode
        params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
        params.put("serviceCode",standardService.getCode());// 接口服务码
        params.put("timestamp", timeStamp);
        params.put("msgData", msgData);
        params.put("msgDigest", tools.getMsgDigest(msgData, timeStamp, sfExpressConfig.getCheckWord()));
        String result = HttpClientUtil.post(sfExpressConfig.getCurrentApiUrl(), params);
            JSONObject jsonObject = JSON.parseObject(result).getJSONObject("apiResultData");
            JSONObject resultInfo = new JSONObject();
            if (jsonObject != null && jsonObject.containsKey("success") && jsonObject.getBooleanValue("success")) {
                resultInfo.put("success", true);  //.getJSONObject("waybillNoInfoList")
                resultInfo.put("data", jsonObject.getJSONObject("msgData").getJSONArray("waybillNoInfoList"));
                resultInfo.put("msg", "下单成功！");
                return resultInfo;
            } else {
                resultInfo.put("success", false);
                resultInfo.put("msg", "下单失败！失败原因："+jsonObject.get("errorMsg"));
                return resultInfo;
            }

        }catch(Exception e){
            throw new RuntimeException();
        }


    }

    private List<Map<String, Object>> getAddedProducts(String addedService) throws JsonProcessingException {
        List<Map<String, Object>> serviceList = new ArrayList<>();
        ObjectMapper objectMapper = new ObjectMapper();
        TypeFactory typeFactory = objectMapper.getTypeFactory();
        Map<String, String> serviceMap = objectMapper.readValue(addedService, typeFactory.constructType(Map.class));

        // 遍历Map的key
        Set<String> keys = serviceMap.keySet();
        for (String key : keys) {
            switch (key) {
                case "isPack":
                    break;
                case "guaranteeMoney": //顺丰基础包
                    Map INSURE = new HashMap<>();
                    INSURE.put("name", "INSURE");
                    INSURE.put("value", serviceMap.get(key));
                    serviceList.add(INSURE);
                case "isOverLongWeight": //超长超重
                    break;

                case "isReceiptCollect": //签单返回
                    break;
                case "isWoodenCrate":   //打木架
                    break;
                default:
                    log.info("收到未定义的增值服务代码: {}", key);

            }

        }
       return serviceList;
    }


    /**
     * 顺丰物流取消订单接口
     * 客服描述 订单揽收前 可以进行取消订单或者修改订单信息
     * @author zxf
     * @date 2026-02-02
     */
    @Override
    public JSONObject cancelOrder(BizWaybillOrder bizWaybillOrder) {
        IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_UPDATE_ORDER;
        CallExpressServiceTools tools=CallExpressServiceTools.getInstance();
        Map<String, String> params = new HashMap<String, String>();
        String timeStamp = String.valueOf(System.currentTimeMillis());
        Map<String,Object> orderData= new HashMap<>();
        orderData.put("language","zh_CN");
        orderData.put("orderId",bizWaybillOrder.getWaybillNo());
        orderData.put("dealType",2);
        String msgData =tools.packageMsgData(standardService);
        msgData= JSON.toJSONString(orderData);
        try {
        params.put("partnerID", sfExpressConfig.getClientCode());  // 顾客编码 ，对应丰桥上获取的clientCode
        params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
        params.put("serviceCode",standardService.getCode());// 接口服务码
        params.put("timestamp", timeStamp);
        params.put("msgData", msgData);
        params.put("msgDigest", tools.getMsgDigest(msgData,timeStamp,sfExpressConfig.getCheckWord()));
        String result = HttpClientUtil.post(sfExpressConfig.getCurrentApiUrl(), params);
        JSONObject jsonObject = JSON.parseObject(result).getJSONObject("apiResultData");
        JSONObject resultInfo = new JSONObject();
            if (jsonObject != null && jsonObject.containsKey("success") && jsonObject.getBooleanValue("success")) {
                resultInfo.put("success", true);
                resultInfo.put("msg", "订单取消成功！");
                return resultInfo;
            } else {
                resultInfo.put("success", false);
                resultInfo.put("msg", "订单取消失败！失败原因："+jsonObject.get("errorMsg"));
                return resultInfo;
            }

        }
        catch(Exception e){
            throw new RuntimeException();
        }
    }
    /**
     * 顺丰物流修改订单接口
     *
     * @author zxf
     * @date 2026-02-02
     */
    @Override
    public JSONObject modifyOrder(BizWaybillOrder bizWaybillOrder) {
        IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_UPDATE_ORDER;
        CallExpressServiceTools tools=CallExpressServiceTools.getInstance();
        Map<String, String> params = new HashMap<String, String>();
        String timeStamp = String.valueOf(System.currentTimeMillis());
        Map<String,Object> orderData= new HashMap<>();
        orderData.put("language","zh_CN");
        orderData.put("orderId",bizWaybillOrder.getWaybillNo());
        orderData.put("dealType",1);
        String msgData =tools.packageMsgData(standardService);
        msgData= JSON.toJSONString(orderData);
        try {
            params.put("partnerID", sfExpressConfig.getClientCode());  // 顾客编码 ，对应丰桥上获取的clientCode
            params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
            params.put("serviceCode",standardService.getCode());// 接口服务码
            params.put("timestamp", timeStamp);
            params.put("msgData", msgData);
            params.put("msgDigest", tools.getMsgDigest(msgData,timeStamp,sfExpressConfig.getCheckWord()));
            String result = HttpClientUtil.post(sfExpressConfig.getCurrentApiUrl(), params);
            JSONObject jsonObject = JSON.parseObject(result).getJSONObject("apiResultData");
            JSONObject resultInfo = new JSONObject();
            if (jsonObject != null && jsonObject.containsKey("success") && jsonObject.getBooleanValue("success")) {

                resultInfo.put("success", true);
                resultInfo.put("data", bizWaybillOrder);
                resultInfo.put("msg", "订单取消成功！");
                return resultInfo;
            } else {
                resultInfo.put("success", false);
                resultInfo.put("msg", "订单取消失败！失败原因："+jsonObject.get("errorMsg"));
                return resultInfo;
            }

        }
        catch(Exception e){
            throw new RuntimeException();
        }
    }

   /* @Override
    public AjaxResult monthlyCode(LogisticsOrder logisticsOrder) {

        SFExpressHttpUtil sfExpressHttpUtil= new SFExpressHttpUtil(sfExpressConfig.getClientCode(),sfExpressConfig.getCheckWord(),sfExpressConfig.getCurrentApiUrl());
        String serviceCode="ACSP_CREATE_MONTHLY_CODE";
        JSONObject msgData = new JSONObject();
        msgData.put("monthCard",sfExpressConfig.getMonthlyCord());
        msgData.put("needDynamicCode",true);
        msgData.put("remak","月结码第一次测试");

        String result= sfExpressHttpUtil.sendRequest(serviceCode,msgData.toJSONString());
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult queryOrder(LogisticsOrder logisticsOrder) {

        SFExpressHttpUtil sfExpressHttpUtil= new SFExpressHttpUtil(sfExpressConfig.getClientCode(),sfExpressConfig.getCheckWord(),sfExpressConfig.getCurrentApiUrl());
        String serviceCode="EXP_RECE_QUERY_SFWAYBILL";
        JSONObject msgData = new JSONObject();
        msgData.put("trackingType","1");
        msgData.put("trackingNum","RJSD20260123000001");


        String result= sfExpressHttpUtil.sendRequest(serviceCode,msgData.toJSONString());
        return AjaxResult.success(result);
    }*/

    @Override
    public JSONObject getMonthQRCode(Integer type) {
        return null;
    }

    @Override
    public JSONObject queryOrderByQRCode(String qrCode, Integer qrcodeType) {
        return null;
    }

    @Override
    public JSONObject queryOrderDetailByWaybillCode(String waybillCode) {
        return null;
    }

    @Override
    public JSONObject queryOrderFeeInfo(String waybillCode) {
        return null;
    }




    /*获取面单pdf下载地址*/
    @Override
    public JSONObject queryWaybillPdf(BizWaybillOrder bizWaybillOrder) {

        IServiceCodeStandard standardService = ExpressServiceCodeEnum.COM_RECE_CLOUD_PRINT_WAYBILLS;
        CallExpressServiceTools tools=CallExpressServiceTools.getInstance();
        Map<String, String> params = new HashMap<String, String>();
        String timeStamp = String.valueOf(System.currentTimeMillis());
        Map<String,Object> orderData= new HashMap<>();
        orderData.put("templateCode","fm_150_standard_RJAHGDYVIJP8");
        orderData.put("version","2.0");
        orderData.put("fileType","pdf");
        orderData.put("sync",true);
        List<Map<String, Object>> documents = new ArrayList<>();
        Map<String, Object> doc = new HashMap<>();
        doc.put("masterWaybillNo",bizWaybillOrder.getExternalWaybillNo());
        documents.add(doc);
        orderData.put("documents",documents);
        String msgData =tools.packageMsgData(standardService);
        msgData= JSON.toJSONString(orderData);
        try {
            params.put("partnerID", sfExpressConfig.getClientCode());  // 顾客编码 ，对应丰桥上获取的clientCode
            params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
            params.put("serviceCode",standardService.getCode());// 接口服务码
            params.put("timestamp", timeStamp);
            params.put("msgData", msgData);
            params.put("msgDigest", tools.getMsgDigest(msgData,timeStamp,sfExpressConfig.getCheckWord()));
            String result = HttpClientUtil.post(sfExpressConfig.getCurrentApiUrl(), params);
            JSONObject jsonObject = JSON.parseObject(result).getJSONObject("apiResultData");
            JSONObject resultInfo = new JSONObject();
            if (jsonObject != null && jsonObject.containsKey("success") && jsonObject.getBooleanValue("success")) {
                resultInfo.put("success", true);
                JSONObject obj = jsonObject.getJSONObject("obj");
                // 4. 取出 files 数组，取第一个
                JSONObject file = obj.getJSONArray("files").getJSONObject(0);
                // 5. 拿到最终的 URL
                String url = file.getString("url");
                String token = file.getString("token");
                resultInfo.put("msg",url);
                resultInfo.put("token",token);
                return resultInfo;
            } else {
                resultInfo.put("success", false);
                resultInfo.put("msg", "获取面单失败！");
                return resultInfo;
            }

        }
        catch(Exception e){
            throw new RuntimeException();
        }
    }
}
