package com.ms.biz.service.impl;

import com.ms.biz.consts.LogisticsConst;
import com.ms.biz.tool.CommonTool;
import com.ms.dal.entity.Logistics;
import com.ms.biz.service.LogisticsService;
import com.ms.dal.entity.LogisticsMatchRule;
import com.ms.dal.mapper.LogisticsMapper;
import com.ms.dal.mapper.LogisticsMatchRuleMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
 *
 */
@Slf4j
@Service
public class LogisticsServiceImpl implements LogisticsService{

    @Autowired
    private LogisticsMapper logisticsMapper;

    @Autowired
    private LogisticsMatchRuleMapper logisticsMatchRuleMapper;

    @Override
    public int deleteByPrimaryKey(Long id) {
        return logisticsMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(Logistics record) {
        return logisticsMapper.insert(record);
    }

    @Override
    public int insertSelective(Logistics record) {
        return logisticsMapper.insertSelective(record);
    }

    @Override
    public Logistics selectByPrimaryKey(Long id) {
        return logisticsMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(Logistics record) {
        return logisticsMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(Logistics record) {
        return logisticsMapper.updateByPrimaryKey(record);
    }

    @Override
    public Map<String, String> matchLogisticsInfo(String platform, String originLogisticsName, String originWaybillCode, Map<String, Logistics> logisticsNameAndLogisticsInfoMap) {
        if (logisticsNameAndLogisticsInfoMap == null) {
            List<Logistics> logisticsList = logisticsMapper.getList();
            logisticsNameAndLogisticsInfoMap = logisticsList.stream().collect(Collectors.toMap(Logistics::getLogisticsName, x -> x));
        }
        String logisticsName = correctLogisticsNameByLogisticsMatchRule(originLogisticsName, originWaybillCode, platform);
        if (!isMatchDdLogistics(logisticsNameAndLogisticsInfoMap, logisticsName, originWaybillCode)) {
            originWaybillCode = getCorrectDdWaybillCode(originWaybillCode, logisticsName);
            logisticsName = correctLogisticsName(logisticsName, originWaybillCode);

        }
        boolean isMatch = logisticsNameAndLogisticsInfoMap.containsKey(logisticsName);
        if (!isMatch && !isIgnoreNoticeLogisticsNameMismatch(logisticsName, originWaybillCode)) {
            log.error("matchPurchaseLogisticsInfoError: " + logisticsName);
        }
        Map<String, String> result = new HashMap<>();
        result.put("logisticsName", logisticsName);
        result.put("waybillCode", originWaybillCode);
        return result;
    }

    private String correctLogisticsNameByLogisticsMatchRule(String logisticsName, String purchaseOrderWaybillCode, String platform) {
        List<LogisticsMatchRule> rules = logisticsMatchRuleMapper.getListByPlatform(platform);
        if (rules.isEmpty()) {
            return logisticsName;
        }

        for (LogisticsMatchRule rule: rules) {
            String realLogisticsName = rule.getLogisticsName();
            if (!"all".equals(rule.getPlatform()) && !rule.getPlatform().equals(platform)) {
                break;
            }
            String purchaseLogisticsName = rule.getPlatformLogisticsName().toLowerCase();
            String waybillCodeRule = rule.getWaybillCodeRule();
            if (!purchaseLogisticsName.equals(logisticsName.toLowerCase())) {
                continue;
            }
            if (!waybillCodeRule.isEmpty() && !purchaseOrderWaybillCode.isEmpty()) {
                Pattern p = Pattern.compile(waybillCodeRule);
                Matcher m = p.matcher(purchaseOrderWaybillCode);
                if (!m.find()) {
                    continue;
                }
            }
            logisticsName = realLogisticsName;
            break;
        }
        return logisticsName;
    }

    private boolean isMatchDdLogistics(Map<String, Logistics> logisticsNameAndLogisticsInfoMap, String logisticsName, String waybillCode) {
        boolean isMatch = logisticsNameAndLogisticsInfoMap.containsKey(logisticsName);
        Pattern p = Pattern.compile("^JT\\d+$");
        Matcher m = p.matcher(waybillCode.trim().toLowerCase());
        if (m.find() && logisticsName.trim().toLowerCase().contains("龙邦速递")) {
            isMatch = false;
        }
        return isMatch;
    }

    public String getCorrectDdWaybillCode(String waybillCode, String logisticsName) {
        waybillCode = waybillCode.trim().toUpperCase();
        Pattern p = Pattern.compile("^([T|W])(JT\\d+)$");
        Matcher m = p.matcher(waybillCode);
        if (m.find()) {
            waybillCode = m.group(2);
        }
        if ("极兔快递".equals(logisticsName) && Pattern.compile("^\\d+$").matcher(waybillCode).find()) {
            return "JT" + waybillCode;
        }
        String[] others = {"其他", "其它", "其它快递"};
        List<String> otherList = Arrays.stream(others).collect(Collectors.toList());
        if (otherList.contains(logisticsName)) {
            Matcher m2 = Pattern.compile("^[A-Z]{2}(YT\\d+)$").matcher(waybillCode);
            Matcher m3 = Pattern.compile("^[A-Z]{2}(JT\\d+)$").matcher(waybillCode);

            p = Pattern.compile("^T77[03567]\\d+$");
            if (p.matcher(waybillCode).find()) {
                return waybillCode.trim();
            } else if (Pattern.compile("^77[03567]\\d+ST$").matcher(waybillCode).find()) {
                return waybillCode.replaceAll("^ST", "");
            } else if (Pattern.compile("^A78299\\d+$").matcher(waybillCode).find()) {
                return waybillCode.replaceAll("^A", "");
            } else if (Pattern.compile("^YT\\d+YT$").matcher(waybillCode).find()) {
                return waybillCode.replaceAll("^YT", "");
            } else if (Pattern.compile("^TYT\\d+$").matcher(waybillCode).find()) {
                return waybillCode.replaceAll("^T", "");
            } else if (m2.find()) {
                return m.group(2);
            } else if (m3.find()) {
                return m.group(2);
            }
        }
        if (Pattern.compile("^WL77[03567]\\d+$").matcher(waybillCode).find() && Objects.equals(logisticsName, "点点送")) {
            return waybillCode.replaceAll("^WL", "");
        }
        if (Pattern.compile("^WLJT\\d+$").matcher(waybillCode).find() && Objects.equals(logisticsName, "点点送")) {
            return waybillCode.replaceAll("^WL", "");
        }
        if (Pattern.compile("^T462\\d+$").matcher(waybillCode).find() && Objects.equals(logisticsName, "官方物流")) {
            return waybillCode.replaceAll("^T", "");
        }
        if (Pattern.compile("^CS\\d+$").matcher(waybillCode).find() && Objects.equals(logisticsName, "其他物流")) {
            return waybillCode.replaceAll("^CS", "");
        }
        if (Pattern.compile("^KF\\d+$").matcher(waybillCode).find() && Objects.equals(logisticsName, "其他物流")) {
            return waybillCode.replaceAll("^KF", "");
        }
        if (Pattern.compile("^EN\\d+$").matcher(waybillCode).find() && Objects.equals(logisticsName, "其他物流")) {
            return waybillCode.replaceAll("^EN", "");
        }
        if (Pattern.compile("^JT\\d+Q$").matcher(waybillCode).find() && Objects.equals(logisticsName, "ju ti")) {
            return waybillCode.replaceAll("^Q", "");
        }
        return waybillCode;
    }

    public String correctLogisticsName(String logisticsName, String waybillCode) {
        if (logisticsName.contains("丹鸟")) {
            logisticsName = "丹鸟";
        }
        logisticsName = logisticsName.replaceAll("\\([^\\\\(]+\\)", "");
        logisticsName = logisticsName.replace("股份", "");
        logisticsName = logisticsName.replace("'有限公司'", "");

        if (logisticsName.contains("无界")) {
            logisticsName = logisticsName.replace("无界", "");
            if (!Pattern.compile("速递").matcher(logisticsName).find()) {
                logisticsName += "快递";
            }
        }

        if ((logisticsName.contains("中通") &&  logisticsName.contains("中通快运")) || (Arrays.asList("其他", "其它", "其它快递", "卖家负责配送").contains(logisticsName) && CommonTool.isMatch("^78299\\d+$", waybillCode))) {
            logisticsName = "中通快递";
        }
        if (logisticsName.contains("EMS") || logisticsName.contains("邮政标准")) {
            logisticsName = "邮政EMS";
        } else if (logisticsName.contains("邮政") && logisticsName.contains("邮政电商标快")) {
            logisticsName = "邮政快递包裹";
        }

        if ((logisticsName.contains("圆通") && logisticsName.contains("圆通快运")) || (Arrays.asList("其他", "其它", "其它快递", "卖家负责配送").contains(logisticsName) && Pattern.compile("^YT\\d+$").matcher(waybillCode).find())) {
            logisticsName = "圆通快递";
        }
        if (logisticsName.contains("国通")) {
            logisticsName = "国通快递";
        }
        if (logisticsName.contains("申通达") || (Arrays.asList("点点送", "菜鸟裹裹商家寄件", "官方直送", "其他", "其它", "其它快递", "卖家负责配送").contains(logisticsName) && Pattern.compile("^77[03567]\\d+$").matcher(waybillCode).find())) {
            logisticsName = "申通快递";
        }
        if ((logisticsName.contains("韵达") && logisticsName.contains("韵达快运")) || ("官方物流".equals(logisticsName) && Pattern.compile("^462\\d+$").matcher(waybillCode).find())) {
            logisticsName = "韵达快递";
        }
        if (logisticsName.contains("德邦") && (logisticsName.contains("德邦物流") || Pattern.compile("^DPK\\d+$").matcher(waybillCode).find())) {
            logisticsName = "德邦快递";
        }
        if (Arrays.asList("其他", "其它", "卖家负责配送").contains(logisticsName) && Pattern.compile("^2\\d{8,9}").matcher(waybillCode).find()) {
            logisticsName = "德邦快递";
        }
        if (Pattern.compile("圆通.+快递").matcher(logisticsName).find()) {
            logisticsName = "圆通快递";
        }
        if (Pattern.compile("^JT\\d+$").matcher(waybillCode).find() && (logisticsName.contains("龙邦速递") || logisticsName.contains("百世") || logisticsName.contains("极兔") || Arrays.asList("其他", "其它", "卖家负责配送", "点点送", "ju ti").contains(logisticsName))) {
            logisticsName = "极兔速递";
        }
        if (logisticsName.contains("百世物流") && Pattern.compile("^919\\d+$").matcher(waybillCode).find()) {
            logisticsName = "百世快运";
        }
        if (Pattern.compile("^SF\\d+$").matcher(waybillCode).find()) {
            logisticsName = "顺丰快递";
        }
        if (logisticsName.contains("丰网")) {
            logisticsName = "丰网速运";
        }
        if (Pattern.compile("^JD[a-zA-Z0-9]+$").matcher(waybillCode).find() && logisticsName.contains("京东")) {
            logisticsName = "京东快递";
        }

        return logisticsName;
    }

    private boolean isIgnoreNoticeLogisticsNameMismatch(String logisticsName, String waybillCode) {
        if (logisticsName.isEmpty() && waybillCode.isEmpty()) {
            return true;
        }
        if (LogisticsConst.getIgnoreNoticeLogisticsNameList().contains(logisticsName)) {
            return true;
        }
        if (Pattern.compile("^(LE)?\\d+$").matcher(logisticsName).find()) {
            return true;
        }
        if (Objects.equals(waybillCode, "-") || !Pattern.compile("^[\\da-zA-Z]+$").matcher(waybillCode).find()) {
            return true;
        }
        if (waybillCode.contains("停发")) {
            return true;
        }
        if (logisticsName.contains("停发")) {
            return true;
        }
        if (logisticsName.contains("疫情")) {
            return true;
        }
        if (logisticsName.contains("C2M")) {
            return true;
        }
        return waybillCode.length() <= 5;
    }
}




