package com.jwipc.supplier.client.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.common.collect.Lists;
import com.jwipc.constant.FlagConst;
import com.jwipc.page.PageView;
import com.jwipc.supplier.clent.dto.*;
import com.jwipc.supplier.client.SupplierClient;
import com.jwipc.supplier.client.convert.SupplierClientConvertConvert;
import com.jwipc.supplier.constant.ModuleTemplateConst;
import com.jwipc.supplier.entity.*;
import com.jwipc.supplier.model.param.ChoseSupplierListParam;
import com.jwipc.supplier.service.*;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p> </p>
 *
 * @author ZhangJie
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@RequiredArgsConstructor
public class SupplierClientImpl implements SupplierClient {
    private final ISupplierService supplierService;
    private final SupplierClientConvertConvert supplierClientConvertConvert;
    private final ICustomerInfoService customerInfoService;
    private final ISupplierPurchaseCategoryService supplierPurchaseCategoryService;
    private final ISupplierInvitaionService supplierInvitationService;
    private final ISupplierBankService supplierBankService;
    private final ISupplierAvlService supplierAvlService;
    private final ISupplierContactsService supplierContactsService;
    private final IRelationBidService relationBidService;
    private final ISupplierTemplateService supplierTemplateService;

    /**
     * 查询供应商名称
     *
     * @param supplierId 供应商id
     * @return
     */
    public String getSupplierName(Long supplierId) {
        final Supplier byId = supplierService.getById(supplierId);
        if (Objects.nonNull(byId)) {
            return byId.getSupplierName();
        }
        return StrUtil.EMPTY;
    }

    /**
     * 初始化供应商账号，慎用
     *
     * @return
     */
    public SupplierDTO getSupplierById(Serializable id) {
        if (Objects.isNull(id)) {
            return null;
        }
        final Supplier list = supplierService.getById(id);
        return supplierClientConvertConvert.entity2DTO(list);
    }

    /**
     * 初始化供应商账号，慎用
     *
     * @return
     */
    public List<SupplierDTO> getSupplierByIds(Collection<? extends Serializable> idList) {
        if (CollUtil.isEmpty(idList)) {
            return CollUtil.newArrayList();
        }
        final List<Supplier> list = supplierService.listByIds(idList);
        return supplierClientConvertConvert.entity2DTOs(list);
    }

    /**
     * 通过供应编码获取供应商
     *
     * @return
     */
    public List<SupplierDTO> getSupplierByCodes(Collection<String> codes) {
        if (CollUtil.isEmpty(codes)) {
            return CollUtil.newArrayList();
        }
        final List<Supplier> list = supplierService.list(
                new LambdaQueryWrapper<Supplier>().in(Supplier::getSupplierCode, codes));
        return supplierClientConvertConvert.entity2DTOs(list);
    }

    /**
     * 通过供应编码获取供应商
     *
     * @return
     */
    public SupplierDTO getSupplierByCode(String code) {
        final Supplier list = supplierService.getOne(
                new LambdaQueryWrapper<Supplier>().eq(Supplier::getSupplierCode, code), false);
        return supplierClientConvertConvert.entity2DTO(list);
    }

    /**
     * 初始化供应商账号，慎用
     *
     * @return
     */
    public List<SupplierDTO> getAllSupplier() {
        final List<Supplier> list = supplierService.list();
        return supplierClientConvertConvert.entity2DTOs(list);
    }

    /**
     * 供应商品类和营业执照接口
     *
     * @param supplierCode 供应商编号
     * @param companyCode  公司编号
     * @return 数据
     */
    public Pair<String, SupplierPurchaseCategoryDTO> getSupplierPurchaseCategory(String supplierCode,
                                                                                 String companyCode)
    {
        final Supplier one = supplierService.getOne(
                new LambdaQueryWrapper<Supplier>().eq(Supplier::getSupplierCode, supplierCode), false);
        if (Objects.isNull(one)) {
            return Pair.of(StrUtil.EMPTY, null);
        }
        final SupplierPurchaseCategory purchaseCategory = supplierPurchaseCategoryService.getOne(
                new LambdaQueryWrapper<SupplierPurchaseCategory>().eq(SupplierPurchaseCategory::getSupplierId,
                                one.getId())
                        .eq(SupplierPurchaseCategory::getCompanyCode, companyCode), false);
        if (Objects.isNull(purchaseCategory)) {
            return Pair.of(one.getBusinessRegisterNo(), null);
        }
        return Pair.of(one.getBusinessRegisterNo(), supplierClientConvertConvert.entity2Dto(purchaseCategory));
    }

    /**
     * 供应商付款方式查询， 供应商代码+工厂+付款条件
     * @param supplierCode
     * @param companyCode
     * @param paymentTerms
     * @return
     */
    public Pair<String, SupplierPurchaseCategoryDTO> getSupplierPurchaseCategory(String supplierCode,
                                                                                 String companyCode, String paymentTerms)
    {
        final Supplier one = supplierService.getOne(
                new LambdaQueryWrapper<Supplier>().eq(Supplier::getSupplierCode, supplierCode), false);
        if (Objects.isNull(one)) {
            return Pair.of(StrUtil.EMPTY, null);
        }
        final SupplierPurchaseCategory purchaseCategory = supplierPurchaseCategoryService.getOne(
                new LambdaQueryWrapper<SupplierPurchaseCategory>().eq(SupplierPurchaseCategory::getSupplierId,
                                one.getId())
                        .eq(SupplierPurchaseCategory::getCompanyCode, companyCode).eq(SupplierPurchaseCategory::getPaymentTerms, paymentTerms), false);
        if (Objects.isNull(purchaseCategory)) {
            return Pair.of(one.getBusinessRegisterNo(), null);
        }
        return Pair.of(one.getBusinessRegisterNo(), supplierClientConvertConvert.entity2Dto(purchaseCategory));
    }


    public PageView getSupplierList(String param) {
        ChoseSupplierListParam choseSupplierListParam = JSON.parseObject(param, ChoseSupplierListParam.class);
        return supplierService.getSupplierList(choseSupplierListParam);
    }


    public List<SupplierBankDTO> supplierBankDate(String contractSupplierCode) {
        if(StringUtils.isNotEmpty(contractSupplierCode)){
          //通过供应商编号查询供应商主表的供应商id
            final Supplier one = supplierService.getOne(
                    new LambdaQueryWrapper<Supplier>().eq(Supplier::getSupplierCode, contractSupplierCode), false);
           if(!Objects.isNull(one)){
               List<SupplierBank> supplierBank = supplierBankService.list(
                       new LambdaQueryWrapper<SupplierBank>().eq(SupplierBank::getSupplierId,one.getId()));
               List<SupplierBankDTO> bankDTO = supplierClientConvertConvert.entity2DTO(supplierBank);
               return bankDTO;
           }

        }
        return null;
    }

    public SupplierCountDTO countSupplier() {
        final SupplierCountDTO.SupplierCountDTOBuilder builder = SupplierCountDTO.builder();
        final long count = supplierService.count();
        builder.totalSize(count);
        final long count1 = supplierPurchaseCategoryService.list(new LambdaQueryWrapper<SupplierPurchaseCategory>()
                        .eq(SupplierPurchaseCategory::getState, 2).groupBy(SupplierPurchaseCategory::getSupplierId)).stream()
                .count();
        builder.potentialSize(count1);
        final long count2 = supplierPurchaseCategoryService.list(new LambdaQueryWrapper<SupplierPurchaseCategory>()
                        .eq(SupplierPurchaseCategory::getState, 7).groupBy(SupplierPurchaseCategory::getSupplierId)).stream()
                .count();
        builder.smallbatchSize(count2);
        final long count3 = supplierPurchaseCategoryService.list(new LambdaQueryWrapper<SupplierPurchaseCategory>()
                        .eq(SupplierPurchaseCategory::getState, 6).groupBy(SupplierPurchaseCategory::getSupplierId)).stream()
                .count();
        builder.qualifiedSize(count3);
        return builder.build();
    }

    /**
     * 根据供应商编码与物料编码查询供应商物料清单
     *
     * @param supplierCode
     * @param materialCode
     * @return
     */
    public SupplierAvlBaseDTO findSupplierAvlItem(String supplierCode, String materialCode) {
        final List<SupplierAvl> supplierAvls = supplierAvlService.list(
                new LambdaQueryWrapper<SupplierAvl>().eq(SupplierAvl::getSupplierCode, supplierCode)
                        .eq(SupplierAvl::getMaterialCode, materialCode));
        SupplierAvlBaseDTO supplierAvlBaseDTO = new SupplierAvlBaseDTO();
        if (CollectionUtils.isNotEmpty(supplierAvls)) {
            supplierAvlBaseDTO = supplierClientConvertConvert.avlToDto(supplierAvls.get(0));
        }
        return supplierAvlBaseDTO;
    }

    /**
     * 根据供应商编码与物料编码查询供应商物料清单
     *
     * @param supplierCode
     * @param materialCode
     * @return
     */
    public SupplierAvlBaseDTO getAvlForPrint(String supplierCode, String materialCode, String productName, String mpn) {
        final List<SupplierAvl> supplierAvls = supplierAvlService.list(
                new LambdaQueryWrapper<SupplierAvl>()
                        .eq(SupplierAvl::getSupplierCode, supplierCode)
                        .eq(SupplierAvl::getMaterialCode, materialCode)
                        .eq(SupplierAvl::getProductNameEn, productName)
                        .eq(SupplierAvl::getMpn, mpn));
        SupplierAvlBaseDTO supplierAvlBaseDTO = new SupplierAvlBaseDTO();
        if (CollectionUtils.isNotEmpty(supplierAvls)) {
            supplierAvlBaseDTO = supplierClientConvertConvert.avlToDto(supplierAvls.get(0));
        }
        return supplierAvlBaseDTO;
    }

    /**
     * 获取供应商联系人信息
     *
     * @param supplierCode 供应商编码
     * @param type         联系人类型 见字典 supplier_role_type
     * @return
     */
    public SupplierContactsDTO getDefaultContact(String supplierCode, String type) {
        final Supplier supplier = supplierService.getOne(
                new LambdaQueryWrapper<Supplier>().eq(Supplier::getSupplierCode, supplierCode));
        if (Objects.isNull(supplier)) {
            return null;
        }
        final LambdaQueryWrapper<SupplierContacts> queryWrapper = new LambdaQueryWrapper<SupplierContacts>().eq(
                SupplierContacts::getSupplierId, supplier.getId());
        if (StrUtil.isNotEmpty(type)) {
            queryWrapper.eq(SupplierContacts::getContactsType, type);
        }
        final SupplierContacts supplierContacts = supplierContactsService.getOne(queryWrapper, false);
        return supplierClientConvertConvert.contactEntity2DTO(supplierContacts);
    }

    @Override
    public List<SupplierContactsDTO> getContactBySupplierCodeAndType(String supplierCode, Integer type) {
        final List<SupplierContacts> supplierContacts = supplierContactsService.list(
                new LambdaQueryWrapper<>(SupplierContacts.class).eq(SupplierContacts::getSupplierCode, supplierCode)
                        .eq(SupplierContacts::getContactsType, type));
        return supplierClientConvertConvert.contactEntities2DTOs(supplierContacts);
    }

    /**
     * 获取供应商代理信息
     *
     * @param supplierCode 当前供应商编号
     * @return 是否是代理商
     */
    public Pair<Boolean, List<SupplierDTO>> getAgentList(String supplierCode) {
        final List<RelationBid> list = relationBidService.list(
                new LambdaQueryWrapper<RelationBid>().eq(RelationBid::getFaSupplier, supplierCode));
        if (CollUtil.isEmpty(list)) {
            return Pair.of(false, Lists.newArrayList());
        } else {
            final Set<String> supplierCodes = list.stream().map(RelationBid::getSupplierCode)
                    .collect(Collectors.toSet());
            final List<Supplier> suppliers = supplierService.list(
                    new LambdaQueryWrapper<Supplier>().in(Supplier::getSupplierCode, supplierCodes));
            return Pair.of(true, supplierClientConvertConvert.entity2DTOs(suppliers));
        }
    }

    public List<SupplierContactsDTO> getContactList(Collection<? extends Serializable> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return Lists.newArrayList();
        }
        final List<SupplierContacts> supplierContacts = supplierContactsService.listByIds(idList);
        return supplierClientConvertConvert.contactEntities2DTOs(supplierContacts);
    }

    @Override
    public SupplierTemplateDTO getSupplierDefaultTemplate() {
        final LambdaQueryWrapper<SupplierTemplate> queryWrapper = new LambdaQueryWrapper<SupplierTemplate>().eq(
                SupplierTemplate::getTemplateCode, ModuleTemplateConst.DEFAULT_CODE.getCode());
        final SupplierTemplate one = supplierTemplateService.getOne(queryWrapper);
        return supplierClientConvertConvert.convert2(one);
    }

    @Override
    public List<SupplierPurchaseCategoryDTO> getList(String supplierId) {
        List<SupplierPurchaseCategory> list = supplierPurchaseCategoryService.list(
                new LambdaQueryWrapper<>(SupplierPurchaseCategory.class).eq(SupplierPurchaseCategory::getSupplierId,
                        supplierId));
        List<SupplierPurchaseCategoryDTO> supplierPurchaseCategoryDTOS = supplierClientConvertConvert.dto2Entities(
                list);
        supplierPurchaseCategoryDTOS.forEach(supplierPurchaseCategoryDTO -> {
            final Supplier supplier = supplierService.getById(
                    supplierPurchaseCategoryDTO.getSupplierId());
            supplierPurchaseCategoryDTO.setPurchaseGroupCode(supplier.getPurchaseGroupCode());
        });
        return supplierPurchaseCategoryDTOS;
    }

    @Override
    public CustomerInfoClientDTO getCustomerInfoByCode(String code) {
        CustomerInfo customerInfo = customerInfoService.getCustomerInfoByCode(code);
        return supplierClientConvertConvert.customerInfoEntity2ClientDTO(customerInfo);
    }

    @Override
    public List<SupplierPurchaseCategoryDTO> getListBySupplierIds(Collection<? extends Serializable> supplierIds) {
        if (CollUtil.isEmpty(supplierIds)) {
            return List.of();
        }
        List<SupplierPurchaseCategory> list = supplierPurchaseCategoryService.list(
                new LambdaQueryWrapper<>(SupplierPurchaseCategory.class).in(SupplierPurchaseCategory::getSupplierId,
                        supplierIds));
        return supplierClientConvertConvert.dto2Entities(list);
    }

    @Override
    public List<SupplierPurchaseCategoryDTO> getListBySupplierIdsAndCompanyCode(
            Collection<? extends Serializable> supplierIds, String companyCode)
    {
        if (CollUtil.isEmpty(supplierIds)) {
            return List.of();
        }
        List<SupplierPurchaseCategory> list = supplierPurchaseCategoryService.list(
                new LambdaQueryWrapper<>(SupplierPurchaseCategory.class).in(SupplierPurchaseCategory::getSupplierId,
                        supplierIds).eq(SupplierPurchaseCategory::getCompanyCode, companyCode));
        return supplierClientConvertConvert.dto2Entities(list);
    }

    @Override
    public List<SupplierPurchaseCategoryDTO> getFirstListBySupplierIds(Collection<? extends Serializable> supplierIds) {
        if (CollUtil.isEmpty(supplierIds)) {
            return List.of();
        }
        List<SupplierPurchaseCategory> list = supplierPurchaseCategoryService.list(
                new LambdaQueryWrapper<>(SupplierPurchaseCategory.class).in(SupplierPurchaseCategory::getSupplierId,
                                supplierIds)
                        .eq(SupplierPurchaseCategory::getFirstFlag, FlagConst.Y.getCode()));
        return supplierClientConvertConvert.dto2Entities(list);
    }

    @Override
    public SupplierInvitaionDTO getRecommander(Long supplierId) {
        final LambdaQueryWrapper<SupplierInvitaion> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq( SupplierInvitaion::getSupplierId, supplierId);
        SupplierInvitaion supplierInvitaion = supplierInvitationService.getOne(queryWrapper);
        return supplierClientConvertConvert.coEntity2DTO(supplierInvitaion);
    }
}
