package com.fjhx.sale.service.pack.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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.common.enums.CodingRuleEnum;
import com.fjhx.common.enums.PushBusinessTypeEnum;
import com.fjhx.common.service.coding.CodingRuleService;
import com.fjhx.sale.entity.contract.po.Contract;
import com.fjhx.sale.entity.documents.po.Documents;
import com.fjhx.sale.entity.documents.po.DocumentsPdf;
import com.fjhx.sale.entity.documents.po.DocumentsProduct;
import com.fjhx.sale.entity.documents.po.DocumentsTransport;
import com.fjhx.sale.entity.pack.dto.PackDto;
import com.fjhx.sale.entity.pack.dto.PackSelectDto;
import com.fjhx.sale.entity.pack.po.*;
import com.fjhx.sale.entity.pack.vo.PackVo;
import com.fjhx.sale.mapper.pack.PackMapper;
import com.fjhx.sale.service.contract.ContractService;
import com.fjhx.sale.service.documents.DocumentsPdfService;
import com.fjhx.sale.service.documents.DocumentsProductService;
import com.fjhx.sale.service.documents.DocumentsService;
import com.fjhx.sale.service.documents.DocumentsTransportService;
import com.fjhx.sale.service.pack.*;
import com.fjhx.socket.core.PushTypeEnum;
import com.fjhx.socket.core.WebSocketPush;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.wrapper.IWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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


/**
 * <p>
 * 装箱出货表 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-18
 */
@Service
public class PackServiceImpl extends ServiceImpl<PackMapper, Pack> implements PackService {

    @Autowired
    private PackDetailService packDetailService;

    @Autowired
    private PackDetailProductService packDetailProductService;

    @Autowired
    private PackDetailGoodsService packDetailGoodsService;

    @Autowired
    private CodingRuleService codingRuleService;
    @Autowired
    private PackShipmentService packShipmentService;
    @Autowired
    private DocumentsService documentsService;
    @Autowired
    private DocumentsPdfService documentsPdfService;
    @Autowired
    private DocumentsProductService documentsProductService;
    @Autowired
    private DocumentsTransportService documentsTransportService;
    @Autowired
    private ContractService contractService;

    @Override
    public Page<PackVo> getPage(PackSelectDto dto) {
        IWrapper<Pack> wrapper = getWrapper();
        wrapper.orderByDesc("p", Pack::getId);
        Page<PackVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        return page;
    }

    @Override
    public PackVo detail(Long id) {
        Pack Pack = this.getById(id);
        PackVo result = BeanUtil.toBean(Pack, PackVo.class);
        return result;
    }

    /**
     * 新增
     *
     * @param pack
     */
    @Override
    @DSTransactional
    public void add(Pack pack) {
        if (StringUtils.isEmpty(pack.getContractIds())) {
            throw new ServiceException("参数异常");
        }
//        pack.setCode(CodeEnum.PACK.getCode());
        pack.setCode(codingRuleService.createCode(CodingRuleEnum.PACK.getKey(), null));
        this.save(pack);
        List<PackDetail> packDetailList = pack.getPackDetailList();
        if (CollectionUtils.isNotEmpty(packDetailList)) {
            List<PackDetailProduct> packDetailProductList = new ArrayList<>();
            List<PackDetailGoods> packDetailGoodsList = new ArrayList<>();
            for (PackDetail p : packDetailList) {
                p.setPackId(pack.getId());
                p.setId(IdWorker.getId());
                //处理装箱产品明细
                setPackDetailProducts(p, packDetailProductList);
                //处理自定义装箱货物
                setPackDetailGoods(p, packDetailGoodsList);
            }
            packDetailService.saveBatch(packDetailList);
            packDetailGoodsService.saveBatch(packDetailGoodsList);
            packDetailProductService.saveBatch(packDetailProductList);
        }
    }

    /**
     * 处理装箱产品明细
     *
     * @param packDetail
     * @param packDetailProductList
     */
    private void setPackDetailProducts(PackDetail packDetail, List<PackDetailProduct> packDetailProductList) {
        List<PackDetailProduct> list = packDetail.getPackDetailProductList();
        if (CollectionUtils.isNotEmpty(list)) {
            for (PackDetailProduct p : list) {
                p.setPackDetailId(packDetail.getId());
                packDetailProductList.add(p);
            }
        }
    }

    /**
     * 处理装箱产品明细
     *
     * @param packDetail
     * @param packDetailGoodsList
     */
    private void setPackDetailGoods(PackDetail packDetail, List<PackDetailGoods> packDetailGoodsList) {
        List<PackDetailGoods> list = packDetail.getPackDetailGoodsList();
        if (CollectionUtils.isNotEmpty(list)) {
            for (PackDetailGoods p : list) {
                p.setPackDetailId(packDetail.getId());
                packDetailGoodsList.add(p);
            }
        }
    }

    @Override
    public void edit(PackDto packDto) {
        this.updateById(packDto);
    }

    /**
     * 删除装箱
     *
     * @param id
     */
    @DSTransactional
    @Override
    public void delete(Long id) {
//        this.removeById(id);//删除装箱
//        List<PackDetail> packDetailList = packDetailService.list(Wrappers.<PackDetail>query().lambda().eq(PackDetail::getPackId,id));
//        if(CollectionUtils.isEmpty(packDetailList)){
//            throw new ServiceException("删除失败,装箱明细数据异常");
//        }
//        List<Long> detailIds = packDetailList.stream().map(PackDetail::getId).collect(Collectors.toList());
//        packDetailService.remove(Wrappers.<PackDetail>query().lambda().in(PackDetail::getId,detailIds));
//        packDetailProductService.remove(Wrappers.<PackDetailProduct>query().lambda().in(PackDetailProduct::getPackDetailId,detailIds));
//        packDetailGoodsService.remove(Wrappers.<PackDetailGoods>query().lambda().in(PackDetailGoods::getPackDetailId,detailIds));
//        PackShipment packShipment = packShipmentService.getOne(Wrappers.<PackShipment>query().lambda().eq(PackShipment::getPackDetailIds,StringUtils.join(detailIds,",")).last("limit 1"));
//        if(ObjectUtils.isNotEmpty(packShipment)){//已出货
//            packShipmentService.removeById(packShipment.getId());
//            //查询是否单证
//            Documents documents = documentsService.getOne(Wrappers.<Documents>query().lambda().eq(Documents::getPackShipmentId,packShipment.getId()).last("limit 1"));
//            if(ObjectUtils.isNotEmpty(documents)){
//                //删除单证相关数据
//                documentsService.removeById(documents.getId());
//                documentsProductService.remove(Wrappers.<DocumentsProduct>query().lambda().eq(DocumentsProduct::getDocumentsId,documents.getId()));
//                documentsPdfService.remove(Wrappers.<DocumentsPdf>query().lambda().eq(DocumentsPdf::getDocumentId,documents.getId()));
//                documentsTransportService.remove(Wrappers.<DocumentsTransport>query().lambda().eq(DocumentsTransport::getDocumentsId,documents.getId()));
//            }
//        }
        //删除主表信息
        this.removeById(id);

        List<PackDetail> packDetailList = packDetailService.list(q -> q.eq(PackDetail::getPackId, id));
        if (ObjectUtil.isEmpty(packDetailList)) {
            return;
        }
        List<Long> packDetailIds = packDetailList.stream().map(PackDetail::getId).distinct().collect(Collectors.toList());

        //删除装箱明细
        packDetailService.remove(q -> q.eq(PackDetail::getPackId, id));
        //删除自定义装箱出货
        packDetailGoodsService.remove(q -> q.in(PackDetailGoods::getPackDetailId, packDetailIds));
        //删除装箱出货产品明细
        packDetailProductService.remove(q -> q.in(PackDetailProduct::getPackDetailId, packDetailIds));
        //删除装箱绑定主合同信息
        IWrapper<PackShipment> wrapper = IWrapper.getWrapper();
        packDetailIds.forEach(item -> wrapper.like(PackShipment::getPackDetailIds, item).or());
        List<PackShipment> packShipmentList = packShipmentService.list(wrapper);
        if (ObjectUtil.isEmpty(packShipmentList)) {
            return;
        }
        packShipmentService.remove(wrapper);

        List<Long> packShipmentIds = packShipmentList.stream().map(PackShipment::getId).distinct().collect(Collectors.toList());
        //删除单证信息
        List<Documents> documentsList = documentsService.list(q -> q.in(Documents::getPackShipmentId, packShipmentIds));
        if (ObjectUtil.isEmpty(documentsList)) {
            return;
        }
        documentsService.remove(q -> q.in(Documents::getPackShipmentId, packShipmentIds));
        List<Long> documentsIds = documentsList.stream().map(Documents::getId).distinct().collect(Collectors.toList());
        //删除单证PDF信息
        documentsPdfService.remove(q -> q.in(DocumentsPdf::getDocumentId, documentsIds));
        //删除单证产品信息
        documentsProductService.remove(q -> q.in(DocumentsProduct::getDocumentsId, documentsIds));
        //删除单证货运信息
        documentsTransportService.remove(q -> q.in(DocumentsTransport::getDocumentsId, documentsIds));

        //发送消息告诉单证创建人 单证被删除
        List<Long> cIds = documentsList.stream().map(Documents::getContractId).distinct().collect(Collectors.toList());
        Map<Long, Contract> contractMap = contractService.mapKEntity(Contract::getId, q -> q.in(Contract::getId, cIds));
        for (Documents documents : documentsList) {
            Contract contract = contractMap.get(documents.getContractId());
            String contractCode = ObjectUtil.isNotEmpty(contract) ? contract.getCode() : String.valueOf(documents.getContractId());
            String userName = SecurityUtils.getLoginUser().getUser().getNickName();
            String msg = "您创建的单证，主合同号：（{}）被（{}）删除，原因：装箱信息被（{}）删除";
            WebSocketPush.byUser(
                    PushTypeEnum.MESSAGE,
                    documents.getCreateUser(),
                    StrUtil.format(msg, contractCode, userName, userName),
                    PushBusinessTypeEnum.DOCUMENTS_DEL.getType()
            );
        }
    }

}
