
package com.tmerclub.cloud.delivery.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.tmerclub.cloud.api.multishop.feign.ShopRefundAddrFeignClient;
import com.tmerclub.cloud.api.multishop.vo.ShopRefundAddrVO;
import com.tmerclub.cloud.api.supplier.feign.SupplierRefundAddrFeignClient;
import com.tmerclub.cloud.api.supplier.vo.SupplierApiRefundAddrVO;
import com.tmerclub.cloud.common.cache.constant.DeliveryCacheNames;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.constant.SysTypeEnum;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.util.PageUtil;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.common.util.PrincipalUtil;
import com.tmerclub.cloud.delivery.constant.DeliveryCompanyType;
import com.tmerclub.cloud.delivery.dto.OutletConfigDTO;
import com.tmerclub.cloud.delivery.mapper.OutletConfigMapper;
import com.tmerclub.cloud.delivery.model.OutletConfig;
import com.tmerclub.cloud.delivery.service.OutletConfigService;
import com.tmerclub.cloud.delivery.vo.OutletConfigInfoVO;
import com.tmerclub.cloud.delivery.vo.OutletConfigVO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 网点配置
 *
 * @author TRACK
 * @date 2023-08-23 14:48:23
 */
@Service
public class OutletConfigServiceImpl implements OutletConfigService {

    @Autowired
    private OutletConfigMapper outletConfigMapper;
    @DubboReference
    private ShopRefundAddrFeignClient shopRefundAddrFeignClient;
    @DubboReference
    private SupplierRefundAddrFeignClient supplierRefundAddrFeignClient;

    @Override
    public PageVO<OutletConfigVO> page(PageDTO pageDTO, OutletConfigDTO outletConfigDTO) {
        PageVO<OutletConfigVO> outletConfigPage = PageUtil.doPage(pageDTO, () -> outletConfigMapper.list(outletConfigDTO));
        for (OutletConfigVO outletConfigVO : outletConfigPage.getList()) {
            if (StrUtil.isNotBlank(outletConfigVO.getMobile())) {
                outletConfigVO.setMobile(PhoneUtil.hideBetween(outletConfigVO.getMobile()).toString());
            }
        }
        return outletConfigPage;
    }

    @Override
    public OutletConfig getByOutletConfig(Long outletConfigId, Integer sysType) {
        OutletConfig outletConfig = outletConfigMapper.getByOutletConfigId(outletConfigId);
        if (Objects.isNull(outletConfig)) {
            throw new LuckException("网点信息为空");
        }
        if (Objects.equals(sysType, SysTypeEnum.SUPPLIER.value())) {
            if (!Objects.equals(outletConfig.getSupplierId(), AuthUserContext.get().getTenantId())) {
                throw new LuckException("暂无权限查看该配置");
            }
        } else {
            // TODO : 本地开发先注释掉
//            if (!Objects.equals(outletConfig.getShopId(), AuthUserContext.get().getTenantId())) {
//                throw new LuckException("暂无权限查看该配置");
//            }
        }
        return outletConfig;
    }

    @Override
    public void save(OutletConfig outletConfig) {
        checkInfo(outletConfig);
        outletConfigMapper.save(outletConfig);
    }

    private void checkInfo(OutletConfig outletConfig) {
        DeliveryCompanyType deliveryCompanyType = DeliveryCompanyType.instance(outletConfig.getDeliveryCompanyType());
        if (Objects.isNull(deliveryCompanyType)) {
            throw new LuckException("快递公司不存在");
        }
        String tempId = DeliveryCompanyType.getTempId(outletConfig.getDeliveryCompanyType(), outletConfig.getPaperSize());
        if (Objects.isNull(tempId) || StrUtil.isBlank(tempId)) {
            throw new LuckException("关联面单不存在");
        }
        if (Objects.nonNull(outletConfig.getShopAddrId())) {
            if (Objects.nonNull(outletConfig.getShopId())) {
                ServerResponseEntity<ShopRefundAddrVO> addrResponse = shopRefundAddrFeignClient.getShopRefundAddrByRefundAddrId(outletConfig.getShopAddrId());
                if (!addrResponse.isSuccess()) {
                    throw new LuckException(addrResponse.getMsg());
                }
                ShopRefundAddrVO shopRefundAddrVO = addrResponse.getData();
                if (Objects.isNull(shopRefundAddrVO)) {
                    throw new LuckException("商家地址不存在");
                }
                outletConfig.setPrintAddr(shopRefundAddrVO.getProvince() + shopRefundAddrVO.getCity() + shopRefundAddrVO.getArea() + shopRefundAddrVO.getAddr());
            } else if (Objects.nonNull(outletConfig.getSupplierId())) {
                ServerResponseEntity<SupplierApiRefundAddrVO> addrResponse = supplierRefundAddrFeignClient.getSupplierRefundAddrByRefundAddrId(outletConfig.getShopAddrId());
                if (!addrResponse.isSuccess()) {
                    throw new LuckException(addrResponse.getMsg());
                }
                SupplierApiRefundAddrVO refundAddrVO = addrResponse.getData();
                if (Objects.isNull(refundAddrVO)) {
                    throw new LuckException("商家地址不存在");
                }
                outletConfig.setPrintAddr(refundAddrVO.getProvince() + refundAddrVO.getCity() + refundAddrVO.getArea() + refundAddrVO.getAddr());
            }
        }
        int count = outletConfigMapper.checkIsExist(outletConfig);
        if (count > 0) {
            throw new LuckException("请勿重复添加相同的快递公司及商家地址");
        }
    }

    @Override
    public void update(OutletConfig outletConfig) {
        checkInfo(outletConfig);
        OutletConfig dbOutlet = outletConfigMapper.getByOutletConfigId(outletConfig.getOutletConfigId());
        if (!PrincipalUtil.isDbPhone(outletConfig.getMobile(), dbOutlet.getMobile(), false)) {
            throw new LuckException("请输入正确的手机号");
        }
        if (outletConfig.getMobile().contains(Constant.ASTERISK)) {
            outletConfig.setMobile(dbOutlet.getMobile());
        }
        outletConfigMapper.update(outletConfig);
    }

    @Override
    public void deleteById(Long outletConfigId) {
        outletConfigMapper.deleteById(outletConfigId);
    }

    @Override
    public void setDefault(Long outletConfigId) {
        OutletConfig outletConfig = getByOutletConfig(outletConfigId, AuthUserContext.get().getSysType());
        if (Objects.isNull(outletConfig)) {
            throw new LuckException("网点信息不存在");
        }
        if (Objects.equals(outletConfig.getIsDefault(), 0)) {
            // 设为默认
            outletConfigMapper.cancelDefault(outletConfig.getShopId(), outletConfig.getSupplierId());
        }
        outletConfigMapper.setDefault(outletConfigId);
    }

    @Override
    @Cacheable(cacheNames = DeliveryCacheNames.OUTLET_CONFIG_LIST_KEY, key = "#shopId + ':' + #sysType")
    public List<OutletConfigInfoVO> listByShopId(Long shopId, Integer sysType) {
        List<OutletConfigInfoVO> infoList = DeliveryCompanyType.getInfoList();
        List<OutletConfigInfoVO> outletList = outletConfigMapper.listByShopId(shopId, sysType);
        if (CollUtil.isEmpty(outletList)) {
            return infoList;
        }
        Map<Integer, OutletConfigInfoVO> outletMap = outletList.stream().collect(Collectors.toMap(OutletConfigInfoVO::getDeliveryCompanyType, o -> o));
        for (OutletConfigInfoVO outletConfigInfoVO : infoList) {
            OutletConfigInfoVO shopOutletConfig = outletMap.get(outletConfigInfoVO.getDeliveryCompanyType());
            if (Objects.isNull(shopOutletConfig)) {
                continue;
            }
            long defaultCount = shopOutletConfig.getShopAddrList().stream().filter(addr -> Objects.equals(addr.getIsDefault(), 1)).count();
            outletConfigInfoVO.setIsConfig(1);
            outletConfigInfoVO.setIsDefault(defaultCount > 0L ? 1 : 0);
            outletConfigInfoVO.setShopAddrList(shopOutletConfig.getShopAddrList());
        }
        return infoList;
    }

    @Override
    @CacheEvict(cacheNames = DeliveryCacheNames.OUTLET_CONFIG_LIST_KEY, key = "#shopId + ':' + #sysType")
    public void removeCache(Long shopId, Integer sysType) {}
}
