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

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
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.entity.corporation.po.Corporation;
import com.fjhx.common.entity.documentary.bo.DocumentaryData;
import com.fjhx.common.enums.FlowStatusEnum1;
import com.fjhx.common.service.corporation.CorporationService;
import com.fjhx.common.service.documentary.GetDocumentaryBusinessTemplate;
import com.fjhx.flow.service.flow.FlowExampleService;
import com.fjhx.item.service.product.ProductInfoService;
import com.fjhx.purchase.entity.invoice.vo.InvoiceDetailsVo;
import com.fjhx.purchase.entity.pay.vo.PayDetailVo;
import com.fjhx.purchase.entity.purchase.bo.PurchaseDocumentaryBo;
import com.fjhx.purchase.entity.purchase.enums.PurchaseStatusEnum;
import com.fjhx.purchase.service.invoice.InvoiceDetailsService;
import com.fjhx.purchase.service.pay.PayDetailService;
import com.fjhx.sale.entity.pack.po.PackDetail;
import com.fjhx.sale.entity.pack.po.PackDetailProduct;
import com.fjhx.sale.entity.pack.vo.PackDetailProductVo;
import com.fjhx.sale.entity.purchase.dto.EhsdPurchaseDto;
import com.fjhx.sale.entity.purchase.dto.EhsdPurchaseSelectDto;
import com.fjhx.sale.entity.purchase.po.*;
import com.fjhx.sale.entity.purchase.vo.EhsdPurchaseDocumentaryVo;
import com.fjhx.sale.entity.purchase.vo.EhsdPurchaseProductVo;
import com.fjhx.sale.entity.purchase.vo.EhsdPurchaseVo;
import com.fjhx.sale.mapper.purchase.EhsdPurchaseMapper;
import com.fjhx.sale.service.pack.PackDetailProductService;
import com.fjhx.sale.service.pack.PackDetailService;
import com.fjhx.sale.service.purchase.*;
import com.fjhx.supply.entity.supplier.po.SupplierInfo;
import com.fjhx.supply.service.supplier.SupplierInfoService;
import com.ruoyi.common.core.domain.BaseSelectDto;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.ruoyi.common.utils.wrapper.SqlField;
import com.ruoyi.system.utils.UserUtil;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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


/**
 * <p>
 * ehsd采购表 服务实现类
 * </p>
 *
 * @author
 * @since 2023-05-17
 */
@Service
@DS(SourceConstant.SALE)
public class EhsdPurchaseServiceImpl extends ServiceImpl<EhsdPurchaseMapper, EhsdPurchase> implements EhsdPurchaseService, GetDocumentaryBusinessTemplate {

    @Autowired
    private EhsdPurchaseProductService ehsdPurchaseProductService;
    @Autowired
    private PackDetailProductService packDetailProductService;
    @Autowired
    private PackDetailService packDetailService;
    @Autowired
    private SupplierInfoService supplierInfoService;
    @Autowired
    private CorporationService corporationService;
    @Autowired
    private FlowExampleService flowExampleService;
    @Autowired
    private EhsdPurchaseProjectService ehsdPurchaseProjectService;
    @Autowired
    private EhsdPurchaseArrivalService ehsdPurchaseArrivalService;
    @Autowired
    private ProductInfoService productInfoService;
    @Autowired
    private EhsdPurchaseProductMountingsService ehsdPurchaseProductMountingsService;
    @Autowired
    private InvoiceDetailsService invoiceDetailsService;
    @Autowired
    private PayDetailService payDetailService;

    /**
     * 分页
     *
     * @param dto
     * @return
     */
    @Override
    public Page<EhsdPurchaseVo> getPage(EhsdPurchaseSelectDto dto) {
        IWrapper<EhsdPurchase> wrapper = getWrapper();
        wrapper.orderByDesc("t1", EhsdPurchase::getCreateTime);
        if (ObjectUtils.isNotEmpty(dto.getPurchaseStatus())) {
            wrapper.eq("t1", EhsdPurchase::getStatus, dto.getPurchaseStatus());
        }
        if (ObjectUtils.isNotEmpty(dto.getPayStatus())) {
            wrapper.eq("t1", EhsdPurchase::getPayStatus, dto.getPayStatus());
        }
        if (ObjectUtils.isNotEmpty(dto.getKeyword())) {
            wrapper.keyword(dto.getKeyword(), new SqlField("t2.name"), new SqlField("t1.`code`"));
        }

        //不显示已变更数据
        wrapper.ne(EhsdPurchase::getStatus, FlowStatusEnum1.UPDATE.getKey());

        //不显示 在审批中 但是 有历史合同id的数据
        wrapper.not(q->q
                .eq(EhsdPurchase::getStatus, FlowStatusEnum1.UNDER_REVIEW.getKey())
                .isNotNull("t1.old_purchase_id")
        );

        Page<EhsdPurchaseVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        List<EhsdPurchaseVo> records = page.getRecords();
        if (ObjectUtils.isEmpty(records)) {
            return page;
        }
        //  赋值流程id
        flowExampleService.setFlowId(records, EhsdPurchaseVo::setFlowId);

        //赋值以付款金额
        List<Long> pids = records.stream().map(EhsdPurchaseVo::getId).collect(Collectors.toList());
        List<PayDetailVo> payDetailVoList = payDetailService.getSumMoneyByPurchaseIds(pids);
        Map<Long, BigDecimal> payMap = payDetailVoList.stream().collect(Collectors.toMap(PayDetailVo::getPurchaseId, PayDetailVo::getSumMoney));
        records.forEach(item -> item.setSumPayMoney(payMap.getOrDefault(item.getId(), BigDecimal.ZERO)));

        //赋值用户名称
        UserUtil.assignmentNickName(records, EhsdPurchase::getCreateUser, EhsdPurchase::setUserName);

        return page;
    }

    @Override
    public EhsdPurchaseVo detail(Long id) {
        EhsdPurchase ehsdPurchase = this.getById(id);
        EhsdPurchaseVo result = BeanUtil.toBean(ehsdPurchase, EhsdPurchaseVo.class);

        List<Long> ids = new ArrayList<>();
//        ids.add(result.getBuyCountryId());
//        ids.add(result.getBuyProvinceId());
//        ids.add(result.getBuyCityId());
        ids.add(result.getSellCountryId());
        ids.add(result.getSellProvinceId());
        ids.add(result.getSellCityId());
        Map<Long, String> areaMapByIds = CustomizeAreaUtil.getAreaMapByIds(ids);
        //赋值卖方地址
        result.setSellCountryName(areaMapByIds.get(result.getSellCountryId()));
        result.setSellProvinceName(areaMapByIds.get(result.getSellProvinceId()));
        result.setSellCityName(areaMapByIds.get(result.getSellCityId()));
        //赋值买方地址
//        result.setBuyCountryName(areaMapByIds.get(result.getBuyCountryId()));
//        result.setBuyProvinceName(areaMapByIds.get(result.getBuyProvinceId()));
//        result.setBuyCityName(areaMapByIds.get(result.getBuyCityId()));

        //赋值卖方名称
        SupplierInfo supplierInfo = supplierInfoService.getById(result.getSellCorporationId());
        if (ObjectUtils.isNotEmpty(supplierInfo)) {
            result.setSellCorporationName(supplierInfo.getName());
        }
        //赋值卖方（供应商）银行信息
        result.setOpeningBank(supplierInfo.getOpeningBank());//开户银行
        result.setOpeningName(supplierInfo.getOpeningName());//账户名
        result.setContactPerson(supplierInfo.getContactPerson());//联系人
        result.setAccountOpening(supplierInfo.getAccountOpening());//账户
        //赋值买方名称
        Corporation corporation = corporationService.getById(result.getBuyCorporationId());
        if (ObjectUtils.isNotEmpty(corporation)) {
            result.setBuyCorporationName(corporation.getName());
        }
        //赋值采购明细
        List<EhsdPurchaseProduct> ehsdPurchaseProductList = ehsdPurchaseProductService.list(q ->
                q.eq(EhsdPurchaseProduct::getPurchaseId, ehsdPurchase.getId())
        );
        List<EhsdPurchaseProductVo> ehsdPurchaseProductVos = BeanUtil.copyToList(ehsdPurchaseProductList, EhsdPurchaseProductVo.class);
        //赋值产品配件信息
        if (ObjectUtils.isNotEmpty(ehsdPurchaseProductList)) {
            List<Long> eppIds = ehsdPurchaseProductVos.stream().map(EhsdPurchaseProductVo::getId).collect(Collectors.toList());
            Map<Long, List<EhsdPurchaseProductMountings>> eppMap = ehsdPurchaseProductMountingsService.mapKGroup(
                    EhsdPurchaseProductMountings::getPurchaseProductId, q -> q
                            .in(EhsdPurchaseProductMountings::getPurchaseProductId, eppIds)
            );
            for (EhsdPurchaseProductVo ehsdPurchaseProductVo : ehsdPurchaseProductVos) {
                List<EhsdPurchaseProductMountings> ehsdPurchaseProductMountings = eppMap.get(ehsdPurchaseProductVo.getId());
                ehsdPurchaseProductVo.setPurchaseProductMountingsList(ehsdPurchaseProductMountings);
            }
        }

        //赋值产品信息
        productInfoService.attributeAssign(ehsdPurchaseProductVos, EhsdPurchaseProductVo::getProductId, (item, product) -> {
            item.setDefinition(product.getDefinition());
        });
        result.setEhsdPurchaseProductList(ehsdPurchaseProductVos);
        //赋值出货明细
        List<Long> cpIds = ehsdPurchaseProductVos.stream().map(EhsdPurchaseProductVo::getDataResourceId).collect(Collectors.toList());
        List<PackDetailProduct> packDetailProductList = packDetailProductService.list(q ->
                q.in(PackDetailProduct::getContractProductId, cpIds)
        );
        List<PackDetailProductVo> packDetailProductVos = BeanUtil.copyToList(packDetailProductList, PackDetailProductVo.class);
        //赋值出货时间
        if (ObjectUtils.isNotEmpty(packDetailProductVos)) {
            PackDetail packDetail = packDetailService.getById(packDetailProductVos.get(0).getPackDetailId());
            packDetailProductVos.forEach(item -> item.setShipmentTime(packDetail.getShipmentTime()));
        }
        result.setPackDetailProductList(packDetailProductVos);


        //赋值其他收费项目
        List<EhsdPurchaseProject> ehsdPurchaseProjects = ehsdPurchaseProjectService.list(q -> q.eq(EhsdPurchaseProject::getPurchaseId, id));
        result.setPurchaseProjectList(ehsdPurchaseProjects);
        //赋值到货信息
        List<EhsdPurchaseArrival> ehsdPurchaseArrivalList = ehsdPurchaseArrivalService.list(q -> q.eq(EhsdPurchaseArrival::getPurchaseId, id));
        productInfoService.attributeAssign(ehsdPurchaseArrivalList, EhsdPurchaseArrival::getProductId, (item, product) -> {
            item.setProductName(product.getName());
            item.setProductCode(product.getCode());
        });
        result.setPurchaseArrivalList(ehsdPurchaseArrivalList);

        return result;
    }

    @Override
    public void add(EhsdPurchaseDto ehsdPurchaseDto) {
        this.save(ehsdPurchaseDto);
    }

    @Override
    public void edit(EhsdPurchaseDto ehsdPurchaseDto) {
        this.updateById(ehsdPurchaseDto);
    }

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

    /**
     * 根据供应商(卖方)查询无发票的采购合同
     */
    @Override
    public List<EhsdPurchaseVo> getListBySupplyId(String supplyId) {
        if (StringUtils.isEmpty(supplyId)) {
            throw new ServiceException("供应商ID不能为空");
        }
        List<EhsdPurchase> list = this.list(Wrappers.<EhsdPurchase>query().lambda().eq(EhsdPurchase::getSellCorporationId, supplyId).eq(EhsdPurchase::getStatus, PurchaseStatusEnum.PASS.getKey()));

        List<EhsdPurchaseVo> ehsdPurchases = BeanUtil.copyToList(list, EhsdPurchaseVo.class);
        List<Long> ids = list.stream().distinct().map(EhsdPurchase::getId).collect(Collectors.toList());
        List<InvoiceDetailsVo> invoiceDetailsList = invoiceDetailsService.getSumMoneyByPurchaseIds(ids);
        Map<Long, BigDecimal> invoiceMap = invoiceDetailsList.stream().collect(Collectors.toMap(InvoiceDetailsVo::getPurchaseId, InvoiceDetailsVo::getSumMoney));
        List<PayDetailVo> payDetailVoList = payDetailService.getSumMoneyByPurchaseIds(ids);
        Map<Long, BigDecimal> payMap = payDetailVoList.stream().collect(Collectors.toMap(PayDetailVo::getPurchaseId, PayDetailVo::getSumMoney));
        for (EhsdPurchaseVo p : ehsdPurchases) {
            if (MapUtils.isNotEmpty(invoiceMap)) {
                p.setSumInvoiceMoney(invoiceMap.getOrDefault(p.getId(), BigDecimal.ZERO));
            } else {
                p.setSumInvoiceMoney(BigDecimal.ZERO);
            }
            if (MapUtils.isNotEmpty(payMap)) {
                p.setSumPayMoney(payMap.getOrDefault(p.getId(), BigDecimal.ZERO));
            } else {
                p.setSumPayMoney(BigDecimal.ZERO);
            }
        }

        return ehsdPurchases;
    }

    @Override
    public Page<? extends DocumentaryData> getDocumentaryPage(JSONObject selectData, BaseSelectDto
            dto, List<Long> excludeBusinessId) {
        PurchaseDocumentaryBo bo = selectData.toJavaObject(PurchaseDocumentaryBo.class);

        IWrapper<EhsdPurchase> wrapper = IWrapper.getWrapper();
        wrapper.like(EhsdPurchase::getCode, bo.getCode());
        wrapper.eq(EhsdPurchase::getCreateUser, bo.getUserId());
        wrapper.eq(EhsdPurchase::getStatus, 30);
        wrapper.notIn(EhsdPurchase::getId, excludeBusinessId);
        wrapper.orderByDesc(EhsdPurchase::getId);

        Page<EhsdPurchase> itemPage = page(dto.getPage(), wrapper);
        Page<EhsdPurchaseDocumentaryVo> page = PageUtils.copyPage(itemPage, EhsdPurchaseDocumentaryVo.class);
        List<EhsdPurchaseDocumentaryVo> records = page.getRecords();

        if (records.size() == 0) {
            return page;
        }

        // 供应商名称
        supplierInfoService.attributeAssign(records, EhsdPurchase::getSellCorporationId, (item, supplier) -> {
            item.setSupplyName(supplier.getName());
        });

        return page;
    }

    /**
     * 采购id修改
     */
    @Override
    public boolean updatePurchaseId(Long id, long newId, Long userId) {
        return baseMapper.updatePurchaseId(id, newId, userId);
    }

}
