package com.ruoyi.web.modules.freight.facade.impl;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.freight.constant.FreightTemplateConstants;
import com.ruoyi.web.modules.freight.domain.BizShopFreightTemplate;
import com.ruoyi.web.modules.freight.domain.BizShopFreightTemplateRegion;
import com.ruoyi.web.modules.freight.facade.IFreightTemplateFacade;
import com.ruoyi.web.modules.freight.mapper.BizShopFreightTemplateMapper;
import com.ruoyi.web.modules.freight.mapper.BizShopFreightTemplateRegionMapper;
import com.ruoyi.web.modules.freight.service.IFreightTemplateService;
import com.ruoyi.web.modules.freight.support.FreightCalcRule;
import com.ruoyi.web.modules.freight.support.FreightCalcSupport;
import com.ruoyi.web.modules.freight.vo.FreightTemplateDetailVO;
import com.ruoyi.web.modules.freight.vo.FreightTemplateOptionVO;

/**
 * 运费模版 Facade 实现
 */
@Service
public class FreightTemplateFacadeImpl implements IFreightTemplateFacade
{
    @Autowired
    private IFreightTemplateService freightTemplateService;

    @Autowired
    private BizShopFreightTemplateMapper templateMapper;

    @Autowired
    private BizShopFreightTemplateRegionMapper regionMapper;

    @Override
    public List<FreightTemplateOptionVO> listOptionsByShopId(Long shopId)
    {
        return freightTemplateService.selectOptionsByShopId(shopId);
    }

    @Override
    public FreightTemplateOptionVO getDefaultTemplate(Long shopId)
    {
        return freightTemplateService.getDefaultTemplate(shopId);
    }

    @Override
    public FreightTemplateDetailVO getDetailForGoods(Long templateId, Long shopId)
    {
        return freightTemplateService.selectDetailForGoods(templateId, shopId);
    }

    @Override
    public String buildFreightDesc(Long templateId, Long shopId)
    {
        BizShopFreightTemplate template = loadTemplate(templateId, shopId);
        if (FreightTemplateConstants.FREE_FLAG_YES.equals(template.getFreeFlag()))
        {
            return "包邮";
        }
        return FreightCalcSupport.buildFreightDesc(false, template.getFirstFee(), template.getFreeThreshold());
    }

    @Override
    public BigDecimal calcFreight(Long templateId, Long shopId, Integer provinceId, BigDecimal pieceCount,
            BigDecimal totalWeightKg, BigDecimal goodsAmount)
    {
        BizShopFreightTemplate template = loadTemplate(templateId, shopId);
        if (FreightTemplateConstants.FREE_FLAG_YES.equals(template.getFreeFlag()))
        {
            return BigDecimal.ZERO;
        }
        List<BizShopFreightTemplateRegion> regions = regionMapper.selectByTemplateId(templateId);
        FreightCalcRule rule = resolveRule(template, regions, provinceId);
        if (FreightCalcSupport.isFreeByThreshold(goodsAmount, rule.getFreeThreshold()))
        {
            return BigDecimal.ZERO;
        }
        if (FreightTemplateConstants.PRICING_TYPE_WEIGHT.equals(template.getPricingType()))
        {
            return FreightCalcSupport.calcByWeight(totalWeightKg, rule);
        }
        return FreightCalcSupport.calcByPiece(pieceCount, rule);
    }

    private BizShopFreightTemplate loadTemplate(Long templateId, Long shopId)
    {
        if (templateId == null || shopId == null || shopId <= 0)
        {
            throw new ServiceException(FreightTemplateConstants.MSG_TEMPLATE_NOT_FOUND);
        }
        BizShopFreightTemplate template = templateMapper.selectById(templateId, shopId);
        if (template == null)
        {
            throw new ServiceException(FreightTemplateConstants.MSG_TEMPLATE_NOT_FOUND);
        }
        return template;
    }

    private FreightCalcRule resolveRule(BizShopFreightTemplate template, List<BizShopFreightTemplateRegion> regions,
            Integer provinceId)
    {
        if (provinceId != null && regions != null)
        {
            for (BizShopFreightTemplateRegion region : regions)
            {
                if (containsProvince(region.getProvinceIds(), provinceId))
                {
                    return toCalcRule(region);
                }
            }
        }
        FreightCalcRule rule = new FreightCalcRule();
        rule.setFirstUnit(template.getFirstUnit());
        rule.setFirstFee(template.getFirstFee());
        rule.setAddUnit(template.getAddUnit());
        rule.setAddFee(template.getAddFee());
        rule.setFreeThreshold(template.getFreeThreshold());
        return rule;
    }

    private boolean containsProvince(String provinceIds, Integer provinceId)
    {
        if (StringUtils.isEmpty(provinceIds) || provinceId == null)
        {
            return false;
        }
        Set<String> ids = new HashSet<>(Arrays.asList(provinceIds.split(",")));
        return ids.contains(String.valueOf(provinceId));
    }

    private FreightCalcRule toCalcRule(BizShopFreightTemplateRegion region)
    {
        FreightCalcRule rule = new FreightCalcRule();
        rule.setFirstUnit(region.getFirstUnit());
        rule.setFirstFee(region.getFirstFee());
        rule.setAddUnit(region.getAddUnit());
        rule.setAddFee(region.getAddFee());
        rule.setFreeThreshold(region.getFreeThreshold());
        return rule;
    }
}
