package com.fjhx.service.logistics.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.constants.logistics.LogisticsConstant;
import com.fjhx.entity.logistics.LogisticsInfo;
import com.fjhx.mapper.logistics.LogisticsInfoMapper;
import com.fjhx.params.logistics.LogisticsInfoVo;
import com.fjhx.service.logistics.LogisticsDetailsService;
import com.fjhx.service.logistics.LogisticsInfoService;
import com.fjhx.uitl.kd100.KD100Util;
import com.fjhx.utils.FileClientUtil;
import com.fjhx.utils.wrapperUtil.IWrapper;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 物流信息 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2022-11-30
 */
@Service
public class LogisticsInfoServiceImpl extends ServiceImpl<LogisticsInfoMapper, LogisticsInfo> implements LogisticsInfoService {

    @Autowired
    private LogisticsDetailsService logisticsDetailsService;

    @Override
    public Page<LogisticsInfo> getPage(Map<String, Object> condition) {

        IWrapper<LogisticsInfo> wrapper = IWrapper.getWrapper(condition);

        return page(condition, wrapper);
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public void add(LogisticsInfoVo logisticsInfoVo) {
        if (Func.isAnyBlank(logisticsInfoVo.getLogisticsCompanyCode(), logisticsInfoVo.getCode())) {
            throw new ServiceException("物流信息不能为空");
        }

        //查询快递100的物流信息
        JSONObject result = KD100Util.queryTrack(logisticsInfoVo.getLogisticsCompanyCode(), logisticsInfoVo.getCode());
        Integer state = result.getInteger("state");
        if (state != LogisticsConstant.KD100Status.STATUS_3) {
            //如果不是已签收状态，则开启订阅（物流状态跟踪并推送）
            KD100Util.subscribe(logisticsInfoVo.getLogisticsCompanyCode(), logisticsInfoVo.getCode());
        }
        logisticsInfoVo.setLogisticsStatus(state);

        logisticsInfoVo.setStatus(LogisticsConstant.Status.STATUS_0);
        save(logisticsInfoVo);

        logisticsInfoVo.getDetails().forEach(o -> {
            o.setLogisticsInfoId(logisticsInfoVo.getId());
            o.setLogisticsInfoCode(logisticsInfoVo.getCode());
            o.setReceiptQuantity(new BigDecimal(BigDecimal.ZERO.intValue()));
        });

        //保存附件
        FileClientUtil.bindingFile(logisticsInfoVo.getId(), logisticsInfoVo.getFileInfos());

        logisticsDetailsService.saveBatch(logisticsInfoVo.getDetails());
    }

    @Override
    public void edit(LogisticsInfoVo logisticsInfoVo) {
        updateById(logisticsInfoVo);
    }

    @Override
    public void delete(LogisticsInfoVo logisticsInfoVo) {
        removeById(logisticsInfoVo.getId());
    }

    /**
     * 根据采购ID查询
     *
     * @param purchaseIds 采购ID集合
     * @return
     */
    @Override
    public List<LogisticsInfo> getByPurchaseIds(List<Long> purchaseIds) {
        if (Func.isEmpty(purchaseIds)) {
            return new ArrayList<>();
        }
        return lambdaQuery().in(LogisticsInfo::getPurchaseId, purchaseIds).list();
    }

    /**
     * 根据采购ID查询
     *
     * @param purchaseIds 采购ID集合
     * @return
     */
    @Override
    public Map<Long, List<LogisticsInfo>> getByPurchaseIdsToMap(List<Long> purchaseIds) {
        List<LogisticsInfo> list = getByPurchaseIds(purchaseIds);
        if (Func.isEmpty(list)) {
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.groupingBy(LogisticsInfo::getPurchaseId));
    }

    /**
     * 根据物流单号跟新物流状态
     *
     * @param code  物流单号
     * @param state 物流状态
     */
    @Override
    public void updateStatusByCode(String code, Integer state) {
        lambdaUpdate().set(LogisticsInfo::getStatus, state).eq(LogisticsInfo::getCode, code).update();
    }
}
