package com.ruoyi.logistics.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.logistics.constant.JDDictConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.logistics.mapper.SysDeptRateMapper;
import com.ruoyi.logistics.domain.SysDeptRate;
import com.ruoyi.logistics.service.ISysDeptRateService;

/**
 * 供应商费率配置Service业务层处理
 * 
 * @author RuiJing
 * @date 2026-03-17
 */
@Service
public class SysDeptRateServiceImpl implements ISysDeptRateService 
{
    @Autowired
    private SysDeptRateMapper sysDeptRateMapper;

    /**
     * 查询供应商费率配置
     * 
     * @param rateId 供应商费率配置主键
     * @return 供应商费率配置
     */
    @Override
    public SysDeptRate selectSysDeptRateByRateId(Long rateId)
    {
        return sysDeptRateMapper.selectSysDeptRateByRateId(rateId);
    }

    /**
     * 查询供应商费率配置列表
     * 
     * @param sysDeptRate 供应商费率配置
     * @return 供应商费率配置
     */
    @Override
    public List<SysDeptRate> selectSysDeptRateList(SysDeptRate sysDeptRate)
    {
        List<SysDeptRate> sysDeptRates = sysDeptRateMapper.selectSysDeptRateList(sysDeptRate);
            
        // 根据 companyType 和 productType 分组后，再根据 intervalBegins 正序排列
        return sysDeptRates.stream()
            .sorted(
                Comparator.comparing(SysDeptRate::getCompanyType)
                    .thenComparing(SysDeptRate::getProductType)
                    .thenComparing(SysDeptRate::getIntervalBegins)
            )
            .collect(Collectors.toList());
    }

    /**
     * 新增供应商费率配置
     * 
     * @param sysDeptRates 供应商费率配置
     * @return 结果
     */
    @Override
    public int insertSysDeptRate(List<SysDeptRate> sysDeptRates, Long deptId)
    {
//        if (sysDeptRates == null || sysDeptRates.isEmpty()) {
//            throw new ServiceException("批量插入的费率配置列表不能为空");
//        }

        // 按 companyType + productType 分组校验区间重叠
        Map<String, List<SysDeptRate>> groupedRates = new HashMap<>();

        for (SysDeptRate rate : sysDeptRates) {
            // 构建分组 key: companyType_productType
            String groupKey = rate.getCompanyType() + "_" + rate.getProductType();
            groupedRates.computeIfAbsent(groupKey, k -> new ArrayList<>()).add(rate);
        }

        // 对每个分组进行区间重叠校验
        for (Map.Entry<String, List<SysDeptRate>> entry : groupedRates.entrySet()) {
            List<SysDeptRate> rates = entry.getValue();
            validateIntervalOverlap(rates);
        }

        // 设置创建时间并批量插入
        sysDeptRateMapper.deleteSysDeptRateByDeptId(deptId);
        for (SysDeptRate rate : sysDeptRates) {
            rate.setCreateTime(DateUtils.getNowDate());
            rate.setCreateBy(SecurityUtils.getUsername());
            rate.setUserId(SecurityUtils.getUserId());
            rate.setDeptId(deptId);
            sysDeptRateMapper.insertSysDeptRate(rate);
        }

        if (sysDeptRates.size() == 0) {
            return 1;
        }

        return sysDeptRates.size();
    }

    /**
     * 修改供应商费率配置
     * 
     * @param sysDeptRate 供应商费率配置
     * @return 结果
     */
    @Override
    public int updateSysDeptRate(SysDeptRate sysDeptRate)
    {
        sysDeptRate.setUpdateTime(DateUtils.getNowDate());
        return sysDeptRateMapper.updateSysDeptRate(sysDeptRate);
    }

    /**
     * 批量删除供应商费率配置
     * 
     * @param rateIds 需要删除的供应商费率配置主键
     * @return 结果
     */
    @Override
    public int deleteSysDeptRateByRateIds(Long[] rateIds)
    {
        return sysDeptRateMapper.deleteSysDeptRateByRateIds(rateIds);
    }

    /**
     * 删除供应商费率配置信息
     * 
     * @param rateId 供应商费率配置主键
     * @return 结果
     */
    @Override
    public int deleteSysDeptRateByRateId(Long rateId)
    {
        return sysDeptRateMapper.deleteSysDeptRateByRateId(rateId);
    }
    
    /**
     * 校验同一物流公司和产品类型的区间是否重叠
     * 区间规则：(intervalBegins, intervalEnds] 左开右闭
     * 
     * @param rates 费率配置列表
     * @throws ServiceException 如果存在区间重叠
     */
    private static void validateIntervalOverlap(List<SysDeptRate> rates) {
        if (rates.size() <= 1) {
            SysDeptRate rate = rates.get(0);
            Long begins = rate.getIntervalBegins();
            Long ends = rate.getIntervalEnds();
            // 检查区间有效性
            if (begins == null || ends == null) {
                throw new ServiceException("区间开始和结束值不能为空");
            }

            if (begins >= ends) {
                throw new ServiceException(String.format(
                        "%s、%s配置的区间开始值必须小于结束值", getCompanyName(rate.getCompanyType()), getProductName(rate.getProductType())));
            }

            if (rate.getRate().compareTo(new BigDecimal("0")) == 0) {
                throw new ServiceException(String.format(
                        "%s、%s的费率不能为0", getCompanyName(rate.getCompanyType()), getProductName(rate.getProductType())));
            }
            return; // 单个或空列表无需校验
        }
        
        // 两两比较所有区间
        for (int i = 0; i < rates.size(); i++) {
            for (int j = i + 1; j < rates.size(); j++) {
                SysDeptRate rate1 = rates.get(i);
                SysDeptRate rate2 = rates.get(j);
                
                Long begins1 = rate1.getIntervalBegins();
                Long ends1 = rate1.getIntervalEnds();
                Long begins2 = rate2.getIntervalBegins();
                Long ends2 = rate2.getIntervalEnds();
                
                // 检查区间有效性
                if (begins1 == null || ends1 == null || begins2 == null || ends2 == null) {
                    throw new ServiceException("区间开始和结束值不能为空");
                }
                
                if (begins1 >= ends1) {
                    throw new ServiceException(String.format(
                        "第%d条配置的区间开始值必须小于结束值", i + 1));
                }
                
                if (begins2 >= ends2) {
                    throw new ServiceException(String.format(
                        "第%d条配置的区间开始值必须小于结束值", j + 1));
                }
                
                // 判断两个区间是否重叠
                // 区间 1: (begins1, ends1]
                // 区间 2: (begins2, ends2]
                // 不重叠的条件：ends1 <= begins2 或 ends2 <= begins1
                // 重叠的条件：!(ends1 <= begins2 || ends2 <= begins1)
                boolean isOverlap = !(ends1 <= begins2 || ends2 <= begins1);
                
                if (isOverlap) {
                    throw new ServiceException(String.format(
                        "%s、%s的区间配置存在重叠：区间%d(%d,%d] 与区间%d(%d,%d]",
                            getCompanyName(rates.get(i).getCompanyType()),
                            getProductName(rates.get(i).getProductType()),
                        i + 1, begins1, ends1,
                        j + 1, begins2, ends2));
                }

                if (rate1.getRate().compareTo(new BigDecimal("0")) == 0) {
                    throw new ServiceException(String.format(
                            "%s、%s的费率不能为0", getCompanyName(rate1.getCompanyType()), getProductName(rate1.getProductType())));
                }

                if (rate1.getRate().compareTo(rate2.getRate()) < 0) {
                    throw new ServiceException(String.format(
                            "%s、%s的费率配置有误：区间%d(%d,%d] 与区间%d(%d,%d]",
                            getCompanyName(rates.get(i).getCompanyType()),
                            getProductName(rates.get(i).getProductType()),
                            i + 1, begins1, ends1,
                            j + 1, begins2, ends2));
                }
            }
        }
    }

    private static String getCompanyName(String companyType) {
        if (companyType == null) {
            return null;
        }
        if (companyType.equals("1")) {
            return "京东";
        }
        if (companyType.equals("2")) {
            return "顺丰";
        }
        return null;
    }

    private static String getProductName(String productType) {
        if (productType == null) {
            return null;
        }
        if (productType.equals(JDDictConstants.PRODUCT_CODE_ED_M_0001)) {
            return "京东标快";
        }
        if (productType.equals(JDDictConstants.PRODUCT_CODE_ED_M_0002)) {
            return "京东特快";
        }
        if (productType.equals(JDDictConstants.PRODUCT_CODE_FR_M_0004)) {
            return "特快重货";
        }
        return null;
    }
}
