package com.fs.hisStore.service.impl;

import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.fs.api.param.ExpressParam;
import com.fs.api.vo.ExpressVO;
import com.fs.common.config.FSSysConfig;
import com.fs.common.core.domain.R;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.DateUtils;
import com.fs.hisStore.config.StoreConfig;
import com.fs.hisStore.domain.FsStoreOrderScrm;
import com.fs.hisStore.dto.ExpressAddressDTO;
import com.fs.hisStore.dto.ExpressInfoDTO;
import com.fs.hisStore.dto.TracesDTO;
import com.fs.hisStore.enums.ShipperCodeEnum;
import com.fs.hisStore.mapper.FsStoreOrderScrmMapper;
import com.fs.hisStore.param.FsStoreOrderExpressParam;
import com.fs.live.domain.LiveOrder;
import com.fs.live.mapper.LiveOrderMapper;
import com.fs.system.service.ISysConfigService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fs.hisStore.mapper.FsExpressScrmMapper;
import com.fs.hisStore.domain.FsExpressScrm;
import com.fs.hisStore.service.IFsExpressScrmService;
import org.springframework.util.Base64Utils;

/**
 * 快递公司Service业务层处理
 *
 * @author fs
 * @date 2022-03-15
 */
@Service
public class FsExpressScrmServiceImpl implements IFsExpressScrmService
{
    Logger logger = LoggerFactory.getLogger(FsExpressScrmServiceImpl.class);
    @Autowired
    private FsExpressScrmMapper fsExpressMapper;
    @Autowired
    private FsStoreOrderScrmMapper fsStoreOrderMapper;
    @Autowired
    private ISysConfigService configService;

    @Autowired
    private LiveOrderMapper liveOrderMapper;
    /**
     * 查询快递公司
     *
     * @param id 快递公司ID
     * @return 快递公司
     */
    @Override
    public FsExpressScrm selectFsExpressById(Long id)
    {
        return fsExpressMapper.selectFsExpressById(id);
    }

    /**
     * 查询快递公司列表
     *
     * @param fsExpress 快递公司
     * @return 快递公司
     */
    @Override
    public List<FsExpressScrm> selectFsExpressList(FsExpressScrm fsExpress)
    {
        return fsExpressMapper.selectFsExpressList(fsExpress);
    }

    /**
     * 新增快递公司
     *
     * @param fsExpress 快递公司
     * @return 结果
     */
    @Override
    public int insertFsExpress(FsExpressScrm fsExpress)
    {
        fsExpress.setCreateTime(DateUtils.getNowDate());
        return fsExpressMapper.insertFsExpress(fsExpress);
    }

    /**
     * 修改快递公司
     *
     * @param fsExpress 快递公司
     * @return 结果
     */
    @Override
    public int updateFsExpress(FsExpressScrm fsExpress)
    {
        fsExpress.setUpdateTime(DateUtils.getNowDate());
        return fsExpressMapper.updateFsExpress(fsExpress);
    }

    /**
     * 批量删除快递公司
     *
     * @param ids 需要删除的快递公司ID
     * @return 结果
     */
    @Override
    public int deleteFsExpressByIds(Long[] ids)
    {
        return fsExpressMapper.deleteFsExpressByIds(ids);
    }

    /**
     * 删除快递公司信息
     *
     * @param id 快递公司ID
     * @return 结果
     */
    @Override
    public int deleteFsExpressById(Long id)
    {
        return fsExpressMapper.deleteFsExpressById(id);
    }

    @Override
    public ExpressInfoDTO getExpressInfo(String OrderCode, String ShipperCode, String LogisticCode, String lastFourNumber)     {

        //处理顺丰查询轨迹需手机号码后4位
        String requestData;
        if (ShipperCode.equals(ShipperCodeEnum.SF.getValue()) || ShipperCode.equals(ShipperCodeEnum.ZTO.getValue())) {
            requestData = "{'OrderCode':'" + OrderCode + "','ShipperCode':'" + ShipperCode + "','LogisticCode':'" + LogisticCode + "','CustomerName':'" + lastFourNumber + "'}";
        } else {
            requestData = "{'OrderCode':'" + OrderCode + "','ShipperCode':'" + ShipperCode + "','LogisticCode':'" + LogisticCode + "'}";
        }

        Map<String, Object> params = new HashMap<>();
        try {
            String json = this.configService.selectConfigByKey("his.config");
            FSSysConfig sysConfig= JSON.parseObject(json,FSSysConfig.class);
            params.put("RequestData", URLEncoder.encode(requestData, "UTF-8"));
            params.put("EBusinessID",sysConfig.getKdnId().trim());
            params.put("RequestType", "8001");
            String dataSign = encrypt(requestData, sysConfig.getKdnKeyId().trim(), "UTF-8");
            params.put("DataSign", URLEncoder.encode(dataSign, "UTF-8"));
            params.put("DataType", "2");

            String result = HttpUtil.post(sysConfig.getKdnUrl().trim(), params);

            //根据公司业务处理返回的信息......
            ExpressInfoDTO dto=JSONUtil.toBean(result,ExpressInfoDTO.class);
            return dto;
        } catch (Exception e) {
            throw  new CustomException(e.getMessage());
        }

    }

    @Override
    public FsExpressScrm selectFsExpressByCode(String code) {
        return fsExpressMapper.selectFsExpressByCode(code);
    }

    @Override
    public FsExpressScrm selectFsExpressByOmsCode(String omsCode) {
        return fsExpressMapper.selectFsExpressByOmsCode(omsCode);
    }

    @Override
    public FsExpressScrm selectFsExpressByName(String deliveryName) {
        return fsExpressMapper.selectFsExpressByName(deliveryName);
    }

    @Override
    public void subscribeEspress(String orderCode, String deliverySn, String deliveryId, String userPhone) {
        //处理顺丰查询轨迹需手机号码后4位
        String requestData;
        if (deliverySn.equals(ShipperCodeEnum.SF.getValue()) || deliverySn.equals(ShipperCodeEnum.ZTO.getValue())) {
            requestData = "{'OrderCode':'" + orderCode + "','ShipperCode':'" + deliverySn + "','LogisticCode':'" + deliveryId + "','CustomerName':'" + userPhone + "'}";
        } else {
            requestData = "{'OrderCode':'" + orderCode + "','ShipperCode':'" + deliverySn + "','LogisticCode':'" + deliveryId + "'}";
        }

        Map<String, Object> params = new HashMap<>();
        try {
            String json = this.configService.selectConfigByKey("his.config");
            FSSysConfig sysConfig= JSON.parseObject(json,FSSysConfig.class);
            params.put("RequestData", URLEncoder.encode(requestData, "UTF-8"));
            params.put("EBusinessID",sysConfig.getKdnId().trim());
            params.put("RequestType", "8001");
            String dataSign = encrypt(requestData, sysConfig.getKdnKeyId().trim(), "UTF-8");
            params.put("DataSign", URLEncoder.encode(dataSign, "UTF-8"));
            params.put("DataType", "2");
            String result = HttpUtil.post(sysConfig.getKdnSubscribeUrl().trim(), params);
            logger.info("订阅物流:"+result);

        } catch (Exception e) {
            throw  new CustomException(e.getMessage());
        }
    }

    @Override
    public R parseAddress(String content) {
        //处理顺丰查询轨迹需手机号码后4位
        String requestData  = "{'Content':'" + content + "'}";

        Map<String, Object> params = new HashMap<>();
        try {
            String json = this.configService.selectConfigByKey("his.config");
            FSSysConfig sysConfig= JSON.parseObject(json,FSSysConfig.class);
            params.put("RequestData", URLEncoder.encode(requestData, "UTF-8"));
            params.put("EBusinessID",sysConfig.getKdnId().trim());
            params.put("RequestType", "6001");
            String dataSign = encrypt(requestData, sysConfig.getKdnKeyId().trim(), "UTF-8");
            params.put("DataSign", URLEncoder.encode(dataSign, "UTF-8"));
            params.put("DataType", "2");
            String result = HttpUtil.post(sysConfig.getKdnSubscribeUrl().trim(), params);
            ExpressAddressDTO dto=JSONUtil.toBean(result,ExpressAddressDTO.class);
            if(dto.getSuccess()){
                return R.ok().put("data",dto.getData());
            }
            else{
                return R.error(dto.getReason());
            }
        } catch (Exception e) {
            throw  new CustomException(e.getMessage());
        }
    }

    @Override
    public List<ExpressVO> getExpressInfoAPI(ExpressParam param) {
        FsStoreOrderScrm order=fsStoreOrderMapper.selectFsStoreOrderByDeliveryId(param.getPackageno());
        if(order!=null){

            String lastFourNumber = "";
            if (order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue())  || order.getDeliverySn().equals(ShipperCodeEnum.ZTO.getValue())) {
                lastFourNumber = order.getUserPhone();
                if (lastFourNumber.length() == 11) {
                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
                }
            }

            //处理顺丰查询轨迹需手机号码后4位
            String requestData;
            if (order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue())  || order.getDeliverySn().equals(ShipperCodeEnum.ZTO.getValue())) {
                requestData = "{'OrderCode':'" + order.getOrderCode() + "','ShipperCode':'" + order.getDeliverySn() + "','LogisticCode':'" + param.getPackageno() + "','CustomerName':'" + lastFourNumber + "'}";
            } else {
                requestData = "{'OrderCode':'" + order.getOrderCode() + "','ShipperCode':'" + order.getDeliverySn() + "','LogisticCode':'" + param.getPackageno() + "'}";
            }

            Map<String, Object> params = new HashMap<>();
            try {
                String json = this.configService.selectConfigByKey("his.config");
                FSSysConfig sysConfig= JSON.parseObject(json,FSSysConfig.class);
                params.put("RequestData", URLEncoder.encode(requestData, "UTF-8"));
                params.put("EBusinessID",sysConfig.getKdnId().trim());
                params.put("RequestType", "8001");
                String dataSign = encrypt(requestData, sysConfig.getKdnKeyId().trim(), "UTF-8");
                params.put("DataSign", URLEncoder.encode(dataSign, "UTF-8"));
                params.put("DataType", "2");

                String result = HttpUtil.post(sysConfig.getKdnUrl().trim(), params);
                //根据公司业务处理返回的信息......
                ExpressInfoDTO dto=JSONUtil.toBean(result,ExpressInfoDTO.class);
                if(dto!=null&&dto.getTraces()!=null){
                    List<ExpressVO> list=new ArrayList<>();
                    for(TracesDTO tracesDTO:dto.getTraces()){
                        ExpressVO expressVO=new ExpressVO();
                        expressVO.setLocation(tracesDTO.getLocation());
                        expressVO.setRemark(tracesDTO.getAcceptStation());
                        expressVO.setStatus(tracesDTO.getAction());
                        expressVO.setTracedate(tracesDTO.getAcceptTime());
                        list.add(expressVO);

                    }
                    return list;
                }
            } catch (Exception e) {
                throw  new CustomException(e.getMessage());
            }
        }
        return null;

    }

    @Override
    public R getLiveExpressByDeliverId(FsStoreOrderExpressParam param) {
        // 添加日志 - 开始
        Logger logger = LoggerFactory.getLogger(this.getClass());
        logger.info("查询物流信息开始，参数：{}", param);
        LiveOrder liveOrder = liveOrderMapper.selectLiveOrderByOrderId(String.valueOf(param.getOrderId()));
        // 添加日志 - 订单信息
        logger.info("查询到订单信息：{}", liveOrder);
        if (liveOrder == null) {
            return R.error("未查询到订单信息");
        }
        //顺丰轨迹查询处理
        String lastFourNumber = "";
        if (StringUtils.equals(liveOrder.getDeliveryCode(),ShipperCodeEnum.SF.getValue()) || StringUtils.equals(liveOrder.getDeliveryCode(),ShipperCodeEnum.ZTO.getValue())) {
            lastFourNumber = getLastFourNum(liveOrder.getUserPhone());
            // 添加日志 - 顺丰单号
            logger.info("顺丰单号处理，获取用户手机号后四位：{}", lastFourNumber);
        }
        ExpressInfoDTO dto = null;
        try {
            dto = this.getExpressInfo(liveOrder.getOrderCode(),
                    liveOrder.getDeliveryCode(),
                    liveOrder.getDeliverySn(),
                    lastFourNumber);
            // 添加日志 - 成功获取物流信息
            logger.info("成功获取物流信息，订单号：{}，物流单号：{}， 快递公司ID：{}, 返回数据：{}", liveOrder.getOrderCode(), liveOrder.getDeliveryCode(),liveOrder.getDeliverySn(), dto);
        } catch (Exception e) {
            // 添加日志 - 异常
            logger.error("获取物流信息异常，订单号：{}，物流单号：{}，快递公司ID：{}", liveOrder.getOrderCode(), liveOrder.getDeliveryCode(), liveOrder.getDeliverySn(), e);
        }
        // 添加日志 - 结束
        logger.info("查询物流信息结束，订单号：{}", param.getOrderId());

        return R.ok().put("data",dto);
    }

    public static String getLastFourNum(String phone) {

        String lastFourNumber = phone;
        if (lastFourNumber.length() == 11) {
            lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
        }
        return lastFourNumber;
    }

    /**
     * Sign签名生成
     *
     * @param content  内容
     * @param keyValue Appkey
     * @param charset  编码方式
     * @return DataSign签名
     */
    private String encrypt(String content, String keyValue, String charset) {
        if (keyValue != null) {
            content = content + keyValue;
        }
        byte[] src;
        try {
            src = MD5(content, charset).getBytes(charset);
            return Base64Utils.encodeToString(src);
        } catch (Exception e) {
        }

        return null;
    }

    /**
     * MD5加密
     *
     * @param str     内容
     * @param charset 编码方式
     * @throws Exception
     */
    private String MD5(String str, String charset) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(str.getBytes(charset));
        byte[] result = md.digest();
        StringBuilder sb = new StringBuilder(32);
        for (int i = 0; i < result.length; i++) {
            int val = result[i] & 0xff;
            if (val <= 0xf) {
                sb.append("0");
            }
            sb.append(Integer.toHexString(val));
        }
        return sb.toString().toLowerCase();
    }

}
