package com.fjhx.victoriatourist.service.logistics.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.area.utils.CustomizeAreaUtil;
import com.fjhx.common.constant.SourceConstant;
import com.fjhx.common.utils.Assert;
import com.fjhx.kd100.entity.company.po.CompanyInfo;
import com.fjhx.kd100.entity.logistics.po.LogisticsInfo;
import com.fjhx.kd100.event.Kd100CallbackEvent;
import com.fjhx.kd100.service.company.CompanyInfoService;
import com.fjhx.kd100.util.KD100Result;
import com.fjhx.kd100.util.KD100Util;
import com.fjhx.purchase.entity.purchase.po.Purchase;
import com.fjhx.purchase.service.purchase.PurchaseService;
import com.fjhx.victoriatourist.entity.jd.po.JdBack;
import com.fjhx.victoriatourist.entity.jd.po.JdBackDetails;
import com.fjhx.victoriatourist.entity.logistics.dto.LogisticsInfosDto;
import com.fjhx.victoriatourist.entity.logistics.dto.LogisticsInfosSelectDto;
import com.fjhx.victoriatourist.entity.logistics.po.LogisticsDetails;
import com.fjhx.victoriatourist.entity.logistics.po.LogisticsInfos;
import com.fjhx.victoriatourist.entity.logistics.vo.LogisticsInfosVo;
import com.fjhx.victoriatourist.mapper.logistics.LogisticsInfosMapper;
import com.fjhx.victoriatourist.service.jd.JdBackDetailsService;
import com.fjhx.victoriatourist.service.jd.JdBackService;
import com.fjhx.victoriatourist.service.logistics.LogisticsDetailsService;
import com.fjhx.victoriatourist.service.logistics.LogisticsInfosService;
import com.fjhx.victoriatourist.utils.LogisticsConstant;
import com.ruoyi.common.utils.wrapper.IWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;

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


/**
 * <p>
 * 物流信息 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-17
 */
@Service
public class LogisticsInfosServiceImpl extends ServiceImpl<LogisticsInfosMapper, LogisticsInfos> implements LogisticsInfosService {
    @Autowired
    CompanyInfoService companyInfoService;
    @Autowired
    LogisticsDetailsService logisticsDetailsService;
    @Autowired
    PurchaseService purchaseService;
    @Autowired
    JdBackService jdBackService;
    @Autowired
    JdBackDetailsService jdBackDetailsService;

    @Override
    public Page<LogisticsInfosVo> getPage(LogisticsInfosSelectDto dto) {
        IWrapper<LogisticsInfos> wrapper = getWrapper();
        wrapper.eq(LogisticsInfos::getBusinessType, dto.getBusinessType());
        wrapper.eq(LogisticsInfos::getLogisticsStatus, dto.getLogisticsStatus());
        wrapper.eq(LogisticsInfos::getStatus, dto.getStatus());
        if (ObjectUtil.isNotEmpty(dto.getKeyword())) {
            wrapper.and(q -> q.like(LogisticsInfos::getCode, dto.getKeyword())
                    .or().like(LogisticsInfos::getBusinessCode, dto.getKeyword()));
        }
        wrapper.eq(LogisticsInfos::getCode, dto.getKeyword());
        wrapper.orderByDesc("li", LogisticsInfos::getId);
        Page<LogisticsInfosVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        List<LogisticsInfosVo> records = page.getRecords();
        //赋值物流公司名字
        List<String> codes = records.stream().map(LogisticsInfosVo::getLogisticsCompanyCode).collect(Collectors.toList());
        if (ObjectUtil.isEmpty(codes)) {
            return page;
        }
        List<CompanyInfo> list = companyInfoService.list(q -> q.in(CompanyInfo::getCode, codes));
        if (ObjectUtil.isNotEmpty(list)) {
            Map<String, String> companyMap = list.stream().collect(Collectors.toMap(CompanyInfo::getCode, CompanyInfo::getName));
            for (LogisticsInfosVo record : records) {
                String name = companyMap.get(record.getLogisticsCompanyCode());
                record.setLogisticsCompanyName(name);
            }
        }
        //赋值国省市名称
        CustomizeAreaUtil.setAreaName(records);
        return page;
    }

    @Override
    public LogisticsInfosVo detail(Long id) {
        LogisticsInfos LogisticsInfos = this.getById(id);
        LogisticsInfosVo result = BeanUtil.toBean(LogisticsInfos, LogisticsInfosVo.class);
        //赋值国省市名称
        CustomizeAreaUtil.setAreaName(Collections.singletonList(result));
        return result;
    }

    @DSTransactional
    @Override
    public void add(LogisticsInfosDto logisticsInfosDto) {
        long logisticsInfosId = IdWorker.getId();
        logisticsInfosDto.setId(logisticsInfosId);
        if (logisticsInfosDto.getIsKd100() == 1) {
            //发起快递100订阅
            DynamicDataSourceContextHolder.push(SourceConstant.KD100);
            Integer state = KD100Util.monitor(logisticsInfosDto.getLogisticsCompanyCode(), logisticsInfosDto.getCode(), logisticsInfosId, 1, LogisticsInfos.class).getState();
            logisticsInfosDto.setLogisticsStatus(state);
            DynamicDataSourceContextHolder.poll();
        }
        this.save(logisticsInfosDto);
        LogisticsDetails logisticsDetails = new LogisticsDetails();
        logisticsDetails.setLogisticsInfoId(logisticsInfosDto.getId());
        logisticsDetails.setRemark(logisticsInfosDto.getRemark());
        logisticsDetailsService.save(logisticsDetails);
    }

    @DSTransactional
    @EventListener
    public void kd100EventListener(Kd100CallbackEvent event) {
        LogisticsInfo logisticsInfo = event.getLogisticsInfo();
        //监听物流状态变化
        if (KD100Util.getTableName(LogisticsInfos.class).equals(logisticsInfo.getTableName())) {
            LogisticsInfos byId = getById(logisticsInfo.getBusinessId());
            if (ObjectUtil.notEqual(logisticsInfo.getState(), byId.getLogisticsStatus())) {
                byId.setLogisticsStatus(logisticsInfo.getState());
                updateById(byId);
                //如果是京东退货且物流状态为完成
                updateJdBack(byId);
            }
        }
    }

    @Override
    public void edit(LogisticsInfosDto logisticsInfosDto) {
        this.updateById(logisticsInfosDto);
    }

    @Override
    public void delete(Long id) {
        this.removeById(id);
    }

    @Override
    public KD100Result getLogistics(Long id) {
        LogisticsInfos logisticsInfo = this.getById(id);
        Assert.notEmpty(logisticsInfo, "没有找到物流信息");
        return KD100Util.queryTrack(logisticsInfo.getLogisticsCompanyCode(), logisticsInfo.getCode());
    }

    @Override
    @DSTransactional
    public void dataInfoEdit(Long id) {
        LogisticsInfos logisticsInfo = getById(id);
        Assert.notEmpty(logisticsInfo, "没有找到物流信息");
        KD100Result kd100Result = KD100Util.queryTrack(logisticsInfo.getLogisticsCompanyCode(), logisticsInfo.getCode());
        Integer state = kd100Result.getState();
        if (ObjectUtil.notEqual(state, logisticsInfo.getLogisticsStatus())) {
            logisticsInfo.setLogisticsStatus(state);
            updateById(logisticsInfo);
            //如果是京东退货且物流状态为完成
            updateJdBack(logisticsInfo);
        }
    }

    @Override
    public void arrivalNotice(LogisticsInfosVo entity) {
        // 采购id
        Long purchaseId = entity.getPurchaseId();
        Assert.notEmpty(purchaseId, "采购id不能为空");

        entity.setStatus(LogisticsConstant.Status.STATUS_1);
        updateById(entity);

        Purchase purchase = new Purchase();
        purchase.setId(purchaseId);
        purchase.setArrivalStatus(10);//设置部分到货
        purchaseService.updateById(purchase);

        //物流到货通知
        Assert.notEmpty(entity.getId(), "物流id不能为空");
        LogisticsInfos logisticsInfo = new LogisticsInfos();
        logisticsInfo.setId(entity.getId());
        logisticsInfo.setLogisticsStatus(15);
        updateById(logisticsInfo);
    }

    /**
     * 如果物流状态完成，更新京东退货状态，添加待质检数据
     */
    public void updateJdBack(LogisticsInfos logisticsInfo) {
        if (ObjectUtil.isEmpty(logisticsInfo) || ObjectUtil.isEmpty(logisticsInfo.getLogisticsStatus())) {
            return;
        }
        if (logisticsInfo.getLogisticsStatus() == 15 && logisticsInfo.getBusinessType() == 4) {
            //京东退货状态修改添加待质检数据
            JdBack jdBack = jdBackService.getById(logisticsInfo.getBusinessId());
            if (ObjectUtil.isNotEmpty(jdBack)) {
                jdBack.setStatus(3);//待质检
                jdBackService.updateById(jdBack);
                //创建待质检记录
                List<JdBackDetails> jdBackDetailsList = jdBackDetailsService.list(q -> q.eq(JdBackDetails::getJdBackId, logisticsInfo.getBusinessId()));
                jdBackService.createJdBackQualityWait(jdBackDetailsList);
            }
        }
    }

}
