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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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.common.constant.SourceConstant;
import com.fjhx.common.service.contract.ContractTemplateService;
import com.fjhx.common.service.corporation.CorporationService;
import com.fjhx.customer.service.customer.CustomerService;
import com.fjhx.flow.service.flow.FlowExampleService;
import com.fjhx.item.entity.product.po.ProductInfo;
import com.fjhx.item.service.product.ProductClassifyService;
import com.fjhx.item.service.product.ProductInfoService;
import com.fjhx.purchase.entity.purchase.vo.PurchaseDetailVo;
import com.fjhx.purchase.service.purchase.PurchaseDetailService;
import com.fjhx.sale.entity.contract.dto.ContractProductDto;
import com.fjhx.sale.entity.contract.dto.ContractProductSelectDto;
import com.fjhx.sale.entity.contract.po.ContractProduct;
import com.fjhx.sale.entity.contract.vo.ContractProductVo;
import com.fjhx.sale.entity.purchase.po.EhsdPurchaseProduct;
import com.fjhx.sale.mapper.contract.ContractProductMapper;
import com.fjhx.sale.service.claim.ClaimContractService;
import com.fjhx.sale.service.contract.ContractProductService;
import com.fjhx.sale.service.purchase.EhsdPurchaseProductService;
import com.fjhx.tenant.utils.DeptUstil;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.ruoyi.common.utils.wrapper.SqlField;
import com.ruoyi.system.service.ISysUserService;
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.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 外销合同-产品 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-17
 */
@Service
public class ContractProductServiceImpl extends ServiceImpl<ContractProductMapper, ContractProduct> implements ContractProductService {

    @Autowired
    private ProductInfoService productInfoService;

    @Autowired
    private ProductClassifyService productClassifyService;

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private CorporationService corporationService;

    @Autowired
    private ContractTemplateService contractTemplateService;

    @Autowired
    private FlowExampleService flowExampleService;
    @Autowired
    private ClaimContractService claimContractService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private EhsdPurchaseProductService ehsdPurchaseProductService;

    /**
     * 分页
     *
     * @param dto
     * @return
     */
    @Override
    public Page<ContractProductVo> getPage(ContractProductSelectDto dto) {
        IWrapper<ContractProduct> wrapper = getWrapper();
        wrapper.orderByDesc("t1", ContractProduct::getCreateTime);
//        wrapper.ne("t1", ContractProduct::getExpendQuantity, 0);
//        wrapper.between("t2", Contract::getStatus, FlowStatusEnum1.PASS.getKey(), FlowStatusEnum1.CANCELLATION.getKey() - 1);
//        if (ObjectUtil.isNotEmpty(dto.getDataType()) && dto.getDataType() == 0) {//合同交接单
//            wrapper.ne("t1", ContractProduct::getExpendQuantity, BigDecimal.ZERO);
//        }
//        if (ObjectUtil.isNotEmpty(dto.getPurchaseStatus()) && dto.getPurchaseStatus() == 2) {//已采购
//            wrapper.eq("t1", ContractProduct::getExpendQuantity, BigDecimal.ZERO);
//        } else if (ObjectUtil.isNotEmpty(dto.getPurchaseStatus()) && dto.getPurchaseStatus() == 1) {//部分采购
//            wrapper.gt("t1", ContractProduct::getExpendQuantity, BigDecimal.ZERO);
//            wrapper.apply("t1.expend_quantity <t1.quantity");
//        } else if (ObjectUtil.isNotEmpty(dto.getPurchaseStatus()) && dto.getPurchaseStatus() == 0) {//未采购
//            wrapper.apply("t1.expend_quantity = t1.quantity");
//        }
//        wrapper.eq("t2", Contract::getIssue, 1);
        if (StringUtils.isNotEmpty(dto.getKeyword())) {

            //关键字检索
            if (ObjectUtil.isNotEmpty(dto.getKeyword())) {
                List<Long> pIds = productInfoService.listObject(ProductInfo::getId, q -> q
                        .like(ProductInfo::getCustomCode, dto.getKeyword())
                        .or().like(ProductInfo::getName, dto.getKeyword())
                );
                wrapper.and(q -> q
                        .in("t1.product_id", pIds)
                        .or().like("t2.`code`", dto.getKeyword())
                        .or().like("t2.`user_name`", dto.getKeyword())
                );
            }
        }
        //是否到账过滤
        if (ObjectUtil.isNotEmpty(dto.getIsReceived())) {
            if (1 == dto.getIsReceived()) {
                wrapper.isNotNull("co.id");
            } else {
                wrapper.isNull("co.id");
            }
        }
        wrapper.groupBy("t1.id");
        Page<ContractProductVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        List<ContractProductVo> records = page.getRecords();
        if (records.size() == 0) {
            return page;
        }

        // 赋值产品属性
        productInfoService.attributeAssign(records, ContractProductVo::getProductId, (item, product) -> {
            item.setProductCategoryId(product.getProductClassifyId());

            item.setProductCode(product.getCustomCode());
            item.setProductName(product.getName());
            item.setProductUnit(product.getUnit());
            item.setProductSpec(product.getSpec());
            item.setProductLength(product.getLength());
            item.setProductWidth(product.getWidth());
            item.setProductHeight(product.getHeight());
            item.setProductColor(product.getColor());
        });
        //赋值已发起采购数量
//        List<PurchaseDetailVo> purchaseDetailVoList = purchaseDetailService.getSumCountByDataResourceId(idList);
//        Map<Long,BigDecimal> pMap = purchaseDetailVoList.stream().collect(Collectors.toMap(PurchaseDetailVo::getDataResourceId,PurchaseDetailVo::getSumCount));
//        list.forEach(i -> i.setStartPurchaseCount(MapUtils.isNotEmpty(pMap)?BigDecimal.ZERO:pMap.getOrDefault(i.getId(),BigDecimal.ZERO)));
        // 赋值产品分类名称
        productClassifyService.attributeAssign(records, ContractProductVo::getProductCategoryId, (item, productClassify) -> {
            item.setProductCategory(productClassify.getName());
        });
//
//        // 赋值公司名称
//        corporationService.attributeAssign(records, ContractProductVo::getCorporationId, (item, corporation) -> {
//            item.setCorporationName(corporation.getName());
//        });

//        // 赋值公司名称
//        corporationService.attributeAssign(list, ContractProductVo::getCorporationId, (item, corporation) -> {
//            item.setCorporationName(corporation.getName());
//        });

        // 赋值业务员名称
        UserUtil.assignmentNickName(records, ContractProductVo::getSalesmanId, ContractProductVo::setUserName);

        // 赋值流程id
        flowExampleService.setFlowId(records, ContractProductVo::getContractId, ContractProductVo::setFlowId);


        //获取生产公司信息
        List<Long> companyIds = records.stream().map(ContractProductVo::getCompanyId).collect(Collectors.toList());
        Map<Long, String> companyNameMap = DeptUstil.getDeptNameMap(companyIds);
        for (ContractProductVo record : records) {
            //赋值生产公司名称
            record.setCorporationName(companyNameMap.get(record.getCompanyId()));
        }


        return page;
    }

    /**
     * 根据合同ID和客户ID查询未包装的产品
     *
     * @param customerId
     * @return
     */
    @Override
    public List<ContractProductVo> getNoPackContractProductById(String customerId, String contractIds) {
        List<ContractProductVo> list = baseMapper.getNoPackContractProductById(customerId, Arrays.asList(contractIds.split(",")));
        // 赋值产品属性
        productInfoService.attributeAssign(list, ContractProductVo::getProductId, (item, product) -> {
            item.setProductCode(product.getCode());
            item.setProductUnit(product.getUnit());
            item.setProductType(product.getType());
            item.setProductName(product.getName());
            item.setProductSpec(product.getSpec());
            item.setProductCategoryId(product.getProductClassifyId());
        });
        // 赋值产品分类名称
        productClassifyService.attributeAssign(list, ContractProductVo::getProductCategoryId, (item, productClassify) -> {
            item.setProductCategory(productClassify.getName());
        });
        return list;
    }

    /**
     * 交接单
     *
     * @param dto
     * @return
     */
    @Override
    public Page<ContractProductVo> getEHSDPage(ContractProductSelectDto dto) {
        IWrapper<ContractProduct> wrapper = getWrapper();
        wrapper.orderByDesc("t1.ct");
        if (StringUtils.isNotEmpty(dto.getKeyword())) {
            wrapper.keyword(dto.getKeyword(), new SqlField("t1.`contractCode`"), new SqlField("t1.`userName`"));
        }
        if (StringUtils.isNotEmpty(dto.getIds())) {
            wrapper.in("t1.id", Arrays.asList(dto.getIds().split(",")));
        }
        Page<ContractProductVo> page = this.baseMapper.getEHSDPage(dto.getPage(), wrapper);
        List<ContractProductVo> list = page.getRecords();
        if (CollectionUtils.isNotEmpty(list)) {
            // 赋值产品属性
            productInfoService.attributeAssign(list, ContractProductVo::getProductId, (item, product) -> {
                item.setProductCode(product.getCode());
                item.setProductUnit(product.getUnit());
                item.setProductType(product.getType());
//                item.setProductName(product.getName());
                item.setProductSpec(product.getSpec());
                item.setProductCategoryId(product.getProductClassifyId());
            });
            // 赋值产品分类名称
            productClassifyService.attributeAssign(list, ContractProductVo::getProductCategoryId, (item, productClassify) -> {
                item.setProductCategory(productClassify.getName());
            });

            //重新赋值待采购数量
            List<Long> contractProductIds = list.stream().map(ContractProduct::getId).collect(Collectors.toList());
            List<EhsdPurchaseProduct> purchaseProducts = ehsdPurchaseProductService.getPurchaseProductByContractProductIds(contractProductIds);
            if (ObjectUtil.isNotEmpty(purchaseProducts)) {
                Map<Long, List<EhsdPurchaseProduct>> collect = purchaseProducts.stream()
                        .filter(item -> ObjectUtil.isNotEmpty(item.getDataResourceId()))
                        .collect(Collectors.groupingBy(EhsdPurchaseProduct::getDataResourceId));
                for (ContractProduct contractProduct : list) {
                    List<EhsdPurchaseProduct> ehsdPurchaseProductList = collect.get(contractProduct.getId());
                    if (ObjectUtil.isEmpty(ehsdPurchaseProductList)) {
                        continue;
                    }
                    BigDecimal purchaseQuantity = ehsdPurchaseProductList.stream().map(EhsdPurchaseProduct::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
                    BigDecimal subtract = contractProduct.getQuantity().subtract(purchaseQuantity);
                    contractProduct.setExpendQuantity(subtract);
                }
            }

        }
        return page;
    }

    /**
     * 待质检分页
     *
     * @param dto
     * @return
     */
    @Override
    public Page<ContractProductVo> getEHSDQualityPage(ContractProductSelectDto dto) {
        IWrapper<ContractProduct> wrapper = getWrapper();
        wrapper.orderByDesc("t1.ct");
        if (StringUtils.isNotEmpty(dto.getKeyword())) {
            wrapper.keyword(dto.getKeyword(), new SqlField("t1.`contractCode`"), new SqlField("t1.`userName`"));
        }
        if (StringUtils.isNotEmpty(dto.getOrderType())) {
            wrapper.eq("t1.orderType", dto.getOrderType());
        }
        if (StringUtils.isNotEmpty(dto.getQualityStatus())) {
            wrapper.eq("t1.qualityStatus", dto.getQualityStatus());
        }
        if (StringUtils.isNotEmpty(dto.getSummary())) {
            wrapper.eq("t1.summary", dto.getSummary());
        }
        Page<ContractProductVo> page = this.baseMapper.getEHSDPage(dto.getPage(), wrapper);
        List<ContractProductVo> list = page.getRecords();
//        //查出所有质检状态
//        List<Long> contractProductIds = list.stream().map(ContractProductVo::getId).collect(Collectors.toList());
//        List<EhsdQuality> qualityList = ehsdQualityService.list(Wrappers.<EhsdQuality>query().lambda().in(EhsdQuality::getBusinessId,contractProductIds));
//        Map<Long,Integer> qualityMap = qualityList.stream().distinct().collect(Collectors.toMap(EhsdQuality::getBusinessId,EhsdQuality::getStatus));
        if (CollectionUtils.isNotEmpty(list)) {
            // 赋值产品属性
            productInfoService.attributeAssign(list, ContractProductVo::getProductId, (item, product) -> {
                item.setProductCode(product.getCode());
                item.setProductUnit(product.getUnit());
                item.setProductType(product.getType());
//                item.setProductName(product.getName());
                item.setProductSpec(product.getSpec());
                item.setProductCategoryId(product.getProductClassifyId());
            });
            // 赋值产品分类名称
            productClassifyService.attributeAssign(list, ContractProductVo::getProductCategoryId, (item, productClassify) -> {
                item.setProductCategory(productClassify.getName());
            });
            // 赋值客户名称
            customerService.attributeAssign(list, ContractProductVo::getBuyCorporationId, (item, customer) -> {
                item.setCustomerName(customer.getName());
            });
            // 供应商名称
            corporationService.attributeAssign(list, ContractProductVo::getSellCorporationId, (item, supplier) -> {
                item.setSupplyName(supplier.getName());
                item.setSupplyId(item.getId());
            });
//            if(CollectionUtils.isNotEmpty(qualityMap)){
//                list.forEach(i -> i.setQualityStatus(qualityMap.getOrDefault(i.getId(),null)));
//            }
        }
        return page;
    }

    /**
     * 合同交接单--分页
     */
    @Override
    public Page<ContractProductVo> contractHandoverPage(ContractProductSelectDto dto) {
        IWrapper<ContractProduct> wrapper = getWrapper();
        wrapper.orderByDesc("t1.create_time");
        wrapper.eq("t2.is_delivery_file", 1);
        if (StringUtils.isNotEmpty(dto.getKeyword())) {
            DynamicDataSourceContextHolder.push(SourceConstant.BASE);
            List<SysUser> list = userService.list(Wrappers.<SysUser>lambdaQuery().like(SysUser::getUserName, dto.getKeyword()));
            DynamicDataSourceContextHolder.poll();
            List<Long> userIds = list.stream().map(SysUser::getUserId).collect(Collectors.toList());
            wrapper.and(q -> q
                    .like("t2.`code`", dto.getKeyword())
                    .or().like("t2.`user_name`", dto.getKeyword())
                    .or().in("t2.create_user", userIds)
            );
        }
        wrapper.eq("t2.`status`", 30);
        wrapper.gt("t1.expend_quantity", 0);
        //查询合同交接单的数据（只查询有添加交接单的数据）
        Page<ContractProductVo> page = this.baseMapper.contractHandoverPage(dto.getPage(), wrapper);

        List<ContractProductVo> list = page.getRecords();
        if (CollectionUtils.isNotEmpty(list)) {
            // 赋值产品属性
            productInfoService.attributeAssign(list, ContractProductVo::getProductId, (item, product) -> {
                item.setProductCode(product.getCode());
                item.setProductUnit(product.getUnit());
                item.setProductType(product.getType());
                item.setProductName(product.getName());
                item.setProductSpec(product.getSpec());
                item.setProductCategoryId(product.getProductClassifyId());
            });
            // 赋值客户名称
            customerService.attributeAssign(list, ContractProductVo::getBuyCorporationId, (item, corporation) -> {
                item.setBuyCorporationName(corporation.getName());
            });
            //赋值业务员名称
            UserUtil.assignmentNickName(list, ContractProductVo::getCreateUser, ContractProductVo::setUserName);

            //重新赋值待采购数量
            List<Long> contractProductIds = list.stream().map(ContractProduct::getId).collect(Collectors.toList());
            List<EhsdPurchaseProduct> purchaseProducts = ehsdPurchaseProductService.getPurchaseProductByContractProductIds(contractProductIds);
            if (ObjectUtil.isNotEmpty(purchaseProducts)) {
                Map<Long, List<EhsdPurchaseProduct>> collect = purchaseProducts.stream()
                        .filter(item -> ObjectUtil.isNotEmpty(item.getDataResourceId()))
                        .collect(Collectors.groupingBy(EhsdPurchaseProduct::getDataResourceId));
                for (ContractProduct contractProduct : list) {
                    List<EhsdPurchaseProduct> ehsdPurchaseProductList = collect.get(contractProduct.getId());
                    if (ObjectUtil.isEmpty(ehsdPurchaseProductList)) {
                        continue;
                    }
                    BigDecimal purchaseQuantity = ehsdPurchaseProductList.stream().map(EhsdPurchaseProduct::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
                    BigDecimal subtract = contractProduct.getQuantity().subtract(purchaseQuantity);
                    contractProduct.setExpendQuantity(subtract);
                }
            }
        }
        return page;
    }

    /**
     * 根据合同产品IDS查询合同产品
     *
     * @param ids
     * @return
     */
    @Override
    public List<ContractProductVo> getListDetail(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new ServiceException("参数异常");
        }
        IWrapper<ContractProduct> wrapper = getWrapper();
        wrapper.in("t1", ContractProduct::getId, ids);
        List<ContractProductVo> list = baseMapper.getListByIds(wrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            List<PurchaseDetailVo> vo = purchaseDetailService.getSumCountInDataResourceIds(ids);
            Map<Long, BigDecimal> voMap = vo.stream().collect(Collectors.toMap(PurchaseDetailVo::getDataResourceId, PurchaseDetailVo::getSumCount));
            for (ContractProductVo c : list) {
                if (MapUtils.isNotEmpty(voMap)) {
                    c.setSumPurchaseCount(voMap.getOrDefault(c.getId(), BigDecimal.ZERO));
                }
            }

            // 赋值产品属性
            productInfoService.attributeAssign(list, ContractProductVo::getProductId, (item, product) -> {
                item.setProductCode(product.getCode());
                item.setProductUnit(product.getUnit());
                item.setProductType(product.getType());
                item.setProductName(product.getName());
                item.setProductSpec(product.getSpec());
                item.setProductCategoryId(product.getProductClassifyId());
            });

            // 赋值产品分类名称
            productClassifyService.attributeAssign(list, ContractProductVo::getProductCategoryId, (item, productClassify) -> {
                item.setProductCategory(productClassify.getName());
            });


        }
        return list;
    }

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

    @Override
    public void add(ContractProductDto contractProductDto) {
        this.save(contractProductDto);
    }

    @Override
    public void edit(ContractProductDto contractProductDto) {
        this.updateById(contractProductDto);
    }

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

}
