package com.yuchen.saas.park.service.service.property.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.read.listener.ReadListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuchen.saas.integration.feign.api.util.PageConverterUtils;
import com.yuchen.saas.park.api.dto.property.PropertyCustomerArchivesDto;
import com.yuchen.saas.park.api.dto.property.PropertyCustomerArchivesDupNameListQueryDto;
import com.yuchen.saas.park.api.dto.property.PropertyCustomerArchivesMergeDto;
import com.yuchen.saas.park.api.dto.property.PropertyCustomerArchivesQueryDto;
import com.yuchen.saas.park.api.entity.park.PmgBatParkInfo;
import com.yuchen.saas.park.api.entity.property.*;
import com.yuchen.saas.park.api.enums.property.*;
import com.yuchen.saas.park.api.vo.property.*;
import com.yuchen.saas.park.service.mapper.property.PropertyCustomerArchivesMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.property.*;
import lombok.extern.slf4j.Slf4j;
import org.nest.springwrap.core.log.exception.ServiceException;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.mp.support.NestPage;
import org.nest.springwrap.core.secure.ContextUser;
import org.nest.springwrap.core.secure.utils.AuthUtil;
import org.nest.springwrap.core.tool.utils.BeanUtil;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author 蔡文强
 * @Date 2023/11/28 10:56
 * @Description 客户档案表 服务实现类
 */
@Slf4j
@Service
public class PropertyCustomerArchivesServiceImpl extends BaseServiceImpl<PropertyCustomerArchivesMapper, PropertyCustomerArchives> implements IPropertyCustomerArchivesService {

    @Resource
    private IPropertyCustomerArchivesMergeService customerArchivesMergeService;
    @Lazy
    @Resource
    private IPropertyHouseOwnerService houseOwnerService;
    @Lazy
    @Resource
    private IPropertyHouseEnterpriseService houseEnterpriseService;
    @Lazy
    @Resource
    private IPropertyEnterpriseMemberService enterpriseMemberService;
    @Lazy
    @Resource
    private IPropertyHouseResidentService houseResidentService;
    @Lazy
    @Resource
    private IPropertyUserHouseService userHouseService;
    @Lazy
    @Resource
    private IPropertyEnterpriseAddressService enterpriseAddressService;
    @Resource
    private PropertyHousesService housesService;
    @Resource
    private PmgBatParkInfoService parkInfoService;
    @Resource
    private IPropertyEnterpriseAddressService propertyEnterpriseAddressService;

    @Override
    public Boolean saveCustomerArchives(PropertyCustomerArchivesDto customerArchivesDto) {
        if (Func.isNotEmpty(customerArchivesDto.getIdNo())) {
            Integer count = this.lambdaQuery().eq(PropertyCustomerArchives::getIdNo, customerArchivesDto.getIdNo()).count();
            if (count > 0) {
                throw new ServiceException("该证件号码已存在，不能重复添加");
            }
        }
        if (customerArchivesDto.getCustomerType() == CustomerTypeEnum.PERSON.getValue() && Func.isNotEmpty(customerArchivesDto.getLinkPhoneOne())) {
            Integer count = this.lambdaQuery().eq(PropertyCustomerArchives::getCustomerType, CustomerTypeEnum.PERSON.getValue())
                    .eq(PropertyCustomerArchives::getLinkPhoneOne, customerArchivesDto.getLinkPhoneOne()).count();
            if (count > 0) {
                throw new ServiceException("个人类型客户该手机号已存在，不能重复添加");
            }
        }
        PropertyCustomerArchives customerArchives = BeanUtil.copyProperties(customerArchivesDto, PropertyCustomerArchives.class);
        ContextUser contextUser = AuthUtil.getUser();
        if (Func.isEmpty(contextUser)) {
            throw new ServiceException("用户不存在");
        }
        Long registerPeopleId = contextUser.getUserDetailId();
        customerArchives.setCreatePeopleId(registerPeopleId);
        customerArchives.setCreateType(CreateTypeEnum.BACK_ADD.getValue());
        return save(customerArchives);
    }

    @Override
    public Boolean updateCustomerArchives(PropertyCustomerArchivesDto customerArchivesDto) {
        PropertyCustomerArchives customerArchives = BeanUtil.copyProperties(customerArchivesDto, PropertyCustomerArchives.class);
        PropertyCustomerArchives select = this.getById(customerArchivesDto.getId());
        if (!select.getLinkPhoneOne().equals(customerArchives.getLinkPhoneOne())) {
            List<PropertyHouseOwner> houseOwnerList = houseOwnerService.lambdaQuery()
                    .eq(PropertyHouseOwner::getCustomerArchivesId, customerArchivesDto.getId())
                    .eq(PropertyHouseOwner::getRegisterStatus, RegisterStatusEnum.REGISTERED.getValue()).list();
            if (Func.isNotEmpty(houseOwnerList)) {
                houseOwnerList.forEach(houseOwner -> {
                    houseOwner.setRegisterStatus(RegisterStatusEnum.NO.getValue());
                    houseOwnerService.updateById(houseOwner);
                    LambdaUpdateWrapper<PropertyUserHouse> ownerUpdateWrapper = Wrappers.lambdaUpdate();
                    ownerUpdateWrapper.eq(PropertyUserHouse::getLinkId, houseOwner.getId());
                    ownerUpdateWrapper.set(PropertyUserHouse::getIsInvalid, 1);
                    userHouseService.update(ownerUpdateWrapper);
                });
            }

            List<PropertyHouseResident> houseResidentList = houseResidentService.lambdaQuery()
                    .eq(PropertyHouseResident::getCustomerArchivesId, customerArchivesDto.getId())
                    .eq(PropertyHouseResident::getRegisterStatus, RegisterStatusEnum.REGISTERED.getValue()).list();
            if (Func.isNotEmpty(houseResidentList)) {
                houseResidentList.forEach(houseResident -> {
                    houseResident.setRegisterStatus(RegisterStatusEnum.NO.getValue());
                    houseResidentService.updateById(houseResident);
                    LambdaUpdateWrapper<PropertyUserHouse> residentUpdateWrapper = Wrappers.lambdaUpdate();
                    residentUpdateWrapper.eq(PropertyUserHouse::getLinkId, houseResident.getId());
                    residentUpdateWrapper.set(PropertyUserHouse::getIsInvalid, 1);
                    userHouseService.update(residentUpdateWrapper);
                });
            }

            List<PropertyHouseEnterprise> houseEnterpriseList = houseEnterpriseService.lambdaQuery()
                    .eq(PropertyHouseEnterprise::getCustomerArchivesId, customerArchivesDto.getId())
                    .eq(PropertyHouseEnterprise::getRegisterStatus, RegisterStatusEnum.REGISTERED.getValue()).list();
            if (Func.isNotEmpty(houseEnterpriseList)) {
                houseEnterpriseList.forEach(houseEnterprise -> {
                    houseEnterprise.setRegisterStatus(RegisterStatusEnum.NO.getValue());
                    houseEnterpriseService.updateById(houseEnterprise);
                    LambdaUpdateWrapper<PropertyEnterpriseAddress> enterpriseAddressUpdateWrapper = Wrappers.lambdaUpdate();
                    enterpriseAddressUpdateWrapper.eq(PropertyEnterpriseAddress::getLinkId, houseEnterprise.getId());
                    enterpriseAddressUpdateWrapper.set(PropertyEnterpriseAddress::getIsValid, 1);
                    enterpriseAddressService.update(enterpriseAddressUpdateWrapper);
                });
            }
            List<PropertyEnterpriseMember> enterpriseMemberList = enterpriseMemberService.lambdaQuery()
                    .eq(PropertyEnterpriseMember::getCustomerArchivesId, customerArchivesDto.getId())
                    .eq(PropertyEnterpriseMember::getRegisterStatus, RegisterStatusEnum.REGISTERED.getValue()).list();
            if (Func.isNotEmpty(enterpriseMemberList)) {
                enterpriseMemberList.forEach(enterpriseMember -> {
                    enterpriseMember.setRegisterStatus(RegisterStatusEnum.NO.getValue());
                    enterpriseMemberService.updateById(enterpriseMember);
                });
            }

        }
        return updateById(customerArchives);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean mergeCustomerArchives(List<PropertyCustomerArchivesMergeDto> mergeDtoList) {
        for (PropertyCustomerArchivesMergeDto mergeDto : mergeDtoList) {
            for (Long removeId : mergeDto.getRemoveIdList()) {
                PropertyCustomerArchivesMerge merge = new PropertyCustomerArchivesMerge();
                merge.setCustomerArchivesRemoveId(removeId);
                merge.setCustomerArchivesReserveId(mergeDto.getReserveId());
                customerArchivesMergeService.save(merge);
                customerArchivesMergeService.lambdaUpdate().eq(PropertyCustomerArchivesMerge::getCustomerArchivesReserveId, removeId)
                        .set(PropertyCustomerArchivesMerge::getCustomerArchivesReserveId, mergeDto.getReserveId())
                        .update();
                removeById(removeId);
            }
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean deleteCustomerArchives(Long id) {
        PropertyCustomerArchives customerArchives = this.getById(id);
        if (customerArchives.getIsLink() == YesOrNoEnum.YES.getValue()) {
            throw new ServiceException("该客户已存在关联数据，不支持删除");
        }
        removeById(id);
        return Boolean.TRUE;
    }

    @Override
    public PropertyCustomerArchivesVo getCustomerArchivesById(Long id) {
        PropertyCustomerArchives customerArchives = getById(id);
        if (Func.isEmpty(customerArchives)) {
            PropertyCustomerArchivesMerge archivesMerge = customerArchivesMergeService.lambdaQuery().eq(PropertyCustomerArchivesMerge::getCustomerArchivesRemoveId, id).one();
            customerArchives = getById(archivesMerge.getCustomerArchivesReserveId());
            if (Func.isEmpty(customerArchives)) {
                throw new ServiceException("客户档案不存在");
            }
        }
        PropertyCustomerArchivesVo customerArchivesVo = BeanUtil.copyProperties(customerArchives, PropertyCustomerArchivesVo.class);
        PmgBatParkInfo pmgBatParkInfo = parkInfoService.getById(customerArchivesVo.getParkId());
        customerArchivesVo.setParkName(pmgBatParkInfo.getParkName());
        return customerArchivesVo;
    }

    @Override
    public NestPage<PropertyCustomerArchivesListVo> getCustomerArchivesPageList(PropertyCustomerArchivesQueryDto queryDto) {
        // 分页获取数据
        Page<PropertyCustomerArchivesListVo> page = new Page<>(queryDto.getCurrent(), queryDto.getSize());
        page = baseMapper.getCustomerArchivesPageList(page, queryDto);
        return PageConverterUtils.convert(page);
    }

    @Override
    public List<PropertyCustomerArchivesVo> getCustomerArchivesList(PropertyCustomerArchivesQueryDto queryDto) {
        List<PropertyCustomerArchives> list = this.lambdaQuery()
                .like(Func.isNotEmpty(queryDto.getCustomerName()), PropertyCustomerArchives::getCustomerName, queryDto.getCustomerName())
                .orderByDesc(PropertyCustomerArchives::getCreateTime).list();
        return BeanUtil.copyProperties(list, PropertyCustomerArchivesVo.class);
    }

    @Override
    public List<PropertyCustomerArchivesDupNameListVo> getDupNameList(PropertyCustomerArchivesDupNameListQueryDto queryDto) {
        if (Func.isEmpty(queryDto.getParkId())) {
            throw new ServiceException("请选择园区");
        }
        return baseMapper.getDupNameList(queryDto);
    }

    @Override
    public PropertyCustomerArchivesImportResVo importCustomerArchives(Integer type, MultipartFile file) {
        if (!(file.getOriginalFilename().endsWith(".xlsx") || file.getOriginalFilename().endsWith(".xls"))) {
            throw new ServiceException("请选择正确的excel文件");
        }
        PropertyCustomerArchivesImportResVo vo = new PropertyCustomerArchivesImportResVo();
        vo.setImportSize(0);
        vo.setFailSize(0);
        vo.setSuccessSize(0);
        List<String> msg = new ArrayList<>();
        vo.setMsg(msg);
        List<PmgBatParkInfo> list = parkInfoService.list();
        Map<String, PmgBatParkInfo> parkMap = list.stream().collect(Collectors.toMap(PmgBatParkInfo::getParkName, a -> a));
        try {
            EasyExcel.read(file.getInputStream(),
                    type == 1 ? PropertyCustomerArchivesOrgImportExcelVo.class : PropertyCustomerArchivesPerImportExcelVo.class, new ReadListener() {

                        @Override
                        public void onException(Exception exception, AnalysisContext context) throws Exception {
                            log.error("导出异常", exception);
                            log.info("context", context);
                            vo.setFailSize(vo.getFailSize() + 1);
                            Integer rowIndex = context.readRowHolder().getRowIndex() - 1;
                            vo.getMsg().add(String.format("第%s条导入失败,失败原因:%s;", rowIndex, exception.getMessage()));
                        }

                        @Override
                        public void invokeHead(Map headMap, AnalysisContext context) {
                            log.info("context", context);
                            log.info("headMap", headMap);
                        }

                        @Override
                        public void invoke(Object o, AnalysisContext analysisContext) {
                            if (type == 1) {
                                vo.setImportSize(vo.getImportSize() + 1);
                                PropertyCustomerArchivesOrgImportExcelVo orgImportVo = (PropertyCustomerArchivesOrgImportExcelVo) o;
                                saveOrgImport(orgImportVo, parkMap);
                            }
                            if (type == 2) {
                                vo.setImportSize(vo.getImportSize() + 1);
                                PropertyCustomerArchivesPerImportExcelVo perImportVo = (PropertyCustomerArchivesPerImportExcelVo) o;
                                savePerImport(perImportVo, parkMap);
                            }
                        }

                        @Override
                        public void extra(CellExtra extra, AnalysisContext context) {
                            log.info("extra", context);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                            log.info("analysisContext", analysisContext);
                        }

                        @Override
                        public boolean hasNext(AnalysisContext context) {
                            return true;
                        }
                    }).sheet().doRead();
        } catch (IOException e) {
            log.info("导入异常", e);
        }

        return vo;
    }


    @Transactional(rollbackFor = Exception.class)
    public void saveOrgImport(PropertyCustomerArchivesOrgImportExcelVo orgImportVo, Map<String, PmgBatParkInfo> parkMap) {
        PropertyCustomerArchives customerArchives = new PropertyCustomerArchives();
        BeanUtils.copyProperties(orgImportVo, customerArchives);
        if (Func.isBlank(orgImportVo.getParkName())) {
            throw new ServiceException("园区不能为空");
        }
        if (Func.isBlank(orgImportVo.getCustomerTypeName())) {
            throw new ServiceException("客户类型不能为空");
        }
        if (Func.isBlank(orgImportVo.getCustomerCategoryName())) {
            throw new ServiceException("客户类别不能为空");
        }
        if (Func.isBlank(orgImportVo.getCustomerName())) {
            throw new ServiceException("客户名称不能为空");
        }

        String parkName = orgImportVo.getParkName().replaceAll("\\s*", "");
        if (parkMap.containsKey(parkName)) {
            PmgBatParkInfo parkInfo = parkMap.get(parkName);
            customerArchives.setParkId(parkInfo.getId());
        } else {
            throw new ServiceException("园区名称不存在");
        }

        String customerTypeName = orgImportVo.getCustomerTypeName().replaceAll("\\s*", "");

        if (customerTypeName.equals(CustomerTypeEnum.getDescByCode(CustomerTypeEnum.ORGAN.getValue()))) {
            customerArchives.setCustomerType(CustomerTypeEnum.ORGAN.getValue());
        } else {
            throw new ServiceException("客户类型不存在");
        }

        String customerCategoryName = orgImportVo.getCustomerCategoryName().replaceAll("\\s*", "");
        if (Func.isEmpty(getCustomerCategory(customerCategoryName))) {
            throw new ServiceException("客户类别不存在");
        }
        customerArchives.setCustomerCategory(getCustomerCategory(customerCategoryName));

        String idTypeName = orgImportVo.getIdTypeName().replaceAll("\\s*", "");
        if (Func.isNotEmpty(idTypeName)) {
            if (idTypeName.equals(IdTypeEnum.getDescByCode(IdTypeEnum.BUSINESS_LICENSE.getValue()))) {
                customerArchives.setIdType(IdTypeEnum.BUSINESS_LICENSE.getValue());
            } else {
                throw new ServiceException("证件类型不存在");
            }
        }

        customerArchives.setCreateType(CreateTypeEnum.BACK_ADD.getValue());
        ContextUser contextUser = AuthUtil.getUser();
        if (Func.isEmpty(contextUser)) {
            throw new ServiceException("用户不存在");
        }
        customerArchives.setCreatePeopleId(contextUser.getUserDetailId());
        //判断客户档案是否存在
        if (customerArchives.getCustomerType() == CustomerTypeEnum.ORGAN.getValue()) {
            LambdaQueryWrapper<PropertyCustomerArchives> isExitQuery = Wrappers.lambdaQuery();
            isExitQuery.eq(PropertyCustomerArchives::getIdNo, customerArchives.getIdNo());
            PropertyCustomerArchives isExit = this.getOne(isExitQuery);
            if (Func.isNotEmpty(isExit)) {
                removeById(isExit.getId());
            }
        }
        this.save(customerArchives);
    }

    @Transactional(rollbackFor = Exception.class)
    public void savePerImport(PropertyCustomerArchivesPerImportExcelVo perImportVo, Map<String, PmgBatParkInfo> parkMap) {
        PropertyCustomerArchives customerArchives = new PropertyCustomerArchives();
        BeanUtils.copyProperties(perImportVo, customerArchives);

        if (Func.isBlank(perImportVo.getParkName())) {
            throw new ServiceException("园区不能为空");
        }
        if (Func.isBlank(perImportVo.getCustomerTypeName())) {
            throw new ServiceException("客户类型不能为空");
        }
        if (Func.isBlank(perImportVo.getCustomerCategoryName())) {
            throw new ServiceException("客户类别不能为空");
        }
        if (Func.isBlank(perImportVo.getCustomerName())) {
            throw new ServiceException("客户名称不能为空");
        }
        if (Func.isBlank(perImportVo.getSexName())) {
            throw new ServiceException("性别不能为空");
        }

        String parkName = perImportVo.getParkName().replaceAll("\\s*", "");
        if (parkMap.containsKey(parkName)) {
            PmgBatParkInfo parkInfo = parkMap.get(parkName);
            customerArchives.setParkId(parkInfo.getId());
        } else {
            throw new ServiceException("园区名称不存在");
        }
        String customerTypeName = perImportVo.getCustomerTypeName().replaceAll("\\s*", "");
        ;
        if (customerTypeName.equals(CustomerTypeEnum.getDescByCode(CustomerTypeEnum.PERSON.getValue()))) {
            customerArchives.setCustomerType(CustomerTypeEnum.PERSON.getValue());
        } else {
            throw new ServiceException("客户类型不存在");
        }

        String customerCategoryName = perImportVo.getCustomerCategoryName().replaceAll("\\s*", "");
        if (Func.isEmpty(getCustomerCategory(customerCategoryName))) {
            throw new ServiceException("客户类别不存在");
        }
        customerArchives.setCustomerCategory(getCustomerCategory(customerCategoryName));

        String sexName = perImportVo.getSexName().replaceAll("\\s*", "");
        if (sexName.equals(SexEnum.getDescByCode(SexEnum.MALE.getValue()))) {
            customerArchives.setSex(SexEnum.MALE.getValue());
        } else if (sexName.equals(SexEnum.getDescByCode(SexEnum.FEMALE.getValue()))) {
            customerArchives.setSex(SexEnum.FEMALE.getValue());
        } else {
            throw new ServiceException("性别不存在");
        }
        String idTypeName = perImportVo.getIdTypeName().replaceAll("\\s*", "");
        if (Func.isNotEmpty(idTypeName)) {
            if (idTypeName.equals(IdTypeEnum.getDescByCode(IdTypeEnum.ID_CARD.getValue()))) {
                customerArchives.setIdType(IdTypeEnum.ID_CARD.getValue());
            } else {
                throw new ServiceException("证件类型不存在");
            }
        }
        customerArchives.setCreateType(CreateTypeEnum.BACK_ADD.getValue());
        ContextUser contextUser = AuthUtil.getUser();
        if (Func.isEmpty(contextUser)) {
            throw new ServiceException("用户不存在");
        }
        customerArchives.setCreatePeopleId(contextUser.getUserDetailId());
        if (customerArchives.getCustomerType() == CustomerTypeEnum.PERSON.getValue()) {
            LambdaQueryWrapper<PropertyCustomerArchives> isExitQuery = Wrappers.lambdaQuery();
            isExitQuery.eq(PropertyCustomerArchives::getLinkPhoneOne, customerArchives.getLinkPhoneOne());
            PropertyCustomerArchives isExit = this.getOne(isExitQuery);
            if (Func.isNotEmpty(isExit)) {
                removeById(isExit.getId());
            }
        }
        this.save(customerArchives);
    }

    public Integer getCustomerCategory(String customerCategoryName) {
        if (customerCategoryName.equals(CustomerCategoryEnum.getDescByCode(CustomerCategoryEnum.HOUSE_OWNER.getValue()))) {
            return CustomerCategoryEnum.HOUSE_OWNER.getValue();
        } else if (customerCategoryName.equals(CustomerCategoryEnum.getDescByCode(CustomerCategoryEnum.OWNER_MEMBER.getValue()))) {
            return CustomerCategoryEnum.OWNER_MEMBER.getValue();
        } else if (customerCategoryName.equals(CustomerCategoryEnum.getDescByCode(CustomerCategoryEnum.HOUSE_TENANT.getValue()))) {
            return CustomerCategoryEnum.HOUSE_TENANT.getValue();
        } else if (customerCategoryName.equals(CustomerCategoryEnum.getDescByCode(CustomerCategoryEnum.TENANT_MEMBER.getValue()))) {
            return CustomerCategoryEnum.TENANT_MEMBER.getValue();
        } else if (customerCategoryName.equals(CustomerCategoryEnum.getDescByCode(CustomerCategoryEnum.OPENER.getValue()))) {
            return CustomerCategoryEnum.OPENER.getValue();
        } else if (customerCategoryName.equals(CustomerCategoryEnum.getDescByCode(CustomerCategoryEnum.SERVICE.getValue()))) {
            return CustomerCategoryEnum.SERVICE.getValue();
        } else if (customerCategoryName.equals(CustomerCategoryEnum.getDescByCode(CustomerCategoryEnum.OTHER.getValue()))) {
            return CustomerCategoryEnum.OTHER.getValue();
        } else {
            return null;
        }
    }

    @Override
    public void exportCustomerArchives(PropertyCustomerArchivesQueryDto queryDto, HttpServletResponse response) {
        LambdaQueryWrapper<PropertyCustomerArchives> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Func.isNotEmpty(queryDto.getParkId()), PropertyCustomerArchives::getParkId, queryDto.getParkId());
        queryWrapper.eq(Func.isNotEmpty(queryDto.getCustomerType()), PropertyCustomerArchives::getCustomerType, queryDto.getCustomerType());
        queryWrapper.eq(Func.isNotEmpty(queryDto.getCustomerCategory()), PropertyCustomerArchives::getCustomerCategory, queryDto.getCustomerCategory());
        queryWrapper.like(Func.isNotEmpty(queryDto.getCustomerName()), PropertyCustomerArchives::getCustomerName, queryDto.getCustomerName());
        queryWrapper.like(Func.isNotEmpty(queryDto.getLinkPhoneOne()), PropertyCustomerArchives::getLinkPhoneOne, queryDto.getLinkPhoneOne());
        queryWrapper.like(Func.isNotEmpty(queryDto.getLinkPhoneOne()), PropertyCustomerArchives::getLinkPhoneTwo, queryDto.getLinkPhoneOne());
        queryWrapper.eq(Func.isNotEmpty(queryDto.getIdType()), PropertyCustomerArchives::getIdType, queryDto.getIdType());
        queryWrapper.like(Func.isNotEmpty(queryDto.getIdNo()), PropertyCustomerArchives::getIdNo, queryDto.getIdNo());
        List<PropertyCustomerArchives> list = this.list(queryWrapper);
        List<PropertyCustomerArchivesExcelVo> excelVoList = BeanUtil.copyProperties(list, PropertyCustomerArchivesExcelVo.class);
        Map<Long, String> parkMap = getParkMap();
        excelVoList.forEach(excelVo -> {
            excelVo.setParkName(parkMap.get(excelVo.getParkId()));
            excelVo.setCustomerTypeName(CustomerTypeEnum.getDescByCode(excelVo.getCustomerType()));
            excelVo.setCustomerCategoryName(CustomerCategoryEnum.getDescByCode(excelVo.getCustomerCategory()));
            excelVo.setIdTypeName(IdTypeEnum.getDescByCode(excelVo.getIdType()));
            excelVo.setCreateTypeName(CreateTypeEnum.getDescByCode(excelVo.getCreateType()));
        });
        try {
            String fileName = URLEncoder.encode("客户档案表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), PropertyCustomerArchivesExcelVo.class)
                    .sheet("客户档案表")
                    .doWrite(excelVoList); //最终处理好的数据结果集list
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public List<PropertyCustomerArchivesVo> getCustomerArchivesByIdList(List<Long> idList) {
        if (Func.isEmpty(idList)) {
            return new ArrayList<>();
        }
        List<PropertyCustomerArchivesMerge> mergeList = customerArchivesMergeService.lambdaQuery().in(PropertyCustomerArchivesMerge::getCustomerArchivesRemoveId, idList).list();
        if (Func.isNotEmpty(mergeList)) {
            List<Long> addIdList = mergeList.stream().map(PropertyCustomerArchivesMerge::getCustomerArchivesReserveId).collect(Collectors.toList());
            idList.addAll(addIdList);
        }
        List<PropertyCustomerArchives> list = this.lambdaQuery().in(PropertyCustomerArchives::getId, idList).list();
        return BeanUtil.copyProperties(list, PropertyCustomerArchivesVo.class);
    }

    @Override
    public List<PropertyHousesVo> getBindHousesByCustomerArchivesId(Long id) {
        PropertyCustomerArchives customerArchives = getCustomerArchivesById(id);
        List<Long> idList = null;
        if (customerArchives.getCustomerCategory() == CustomerCategoryEnum.HOUSE_OWNER.getValue()) {
            List<PropertyHouseOwner> ownerList = houseOwnerService.lambdaQuery().eq(PropertyHouseOwner::getCustomerArchivesId, customerArchives.getId()).list();
            if (Func.isNotEmpty(ownerList)) {
                idList = ownerList.stream().map(PropertyHouseOwner::getHouseId).collect(Collectors.toList());
            }

        } else if (customerArchives.getCustomerCategory() == CustomerCategoryEnum.HOUSE_TENANT.getValue()) {
            List<PropertyHouseEnterprise> enterpriseList = houseEnterpriseService.lambdaQuery().eq(PropertyHouseEnterprise::getCustomerArchivesId, customerArchives.getId()).list();
            if (Func.isNotEmpty(enterpriseList)) {
                idList = enterpriseList.stream().map(PropertyHouseEnterprise::getHouseId).collect(Collectors.toList());
            }
        } else if (customerArchives.getCustomerCategory() == CustomerCategoryEnum.OWNER_MEMBER.getValue()) {
            List<PropertyHouseResident> residentList = houseResidentService.lambdaQuery().eq(PropertyHouseResident::getCustomerArchivesId, customerArchives.getId()).list();
            if (Func.isNotEmpty(residentList)) {
                idList = residentList.stream().map(PropertyHouseResident::getHouseId).collect(Collectors.toList());
            }
        }
        if (Func.isEmpty(idList)) {
            return new ArrayList<>();
        }

        List<PropertyHouses> housesList = housesService.lambdaQuery().in(PropertyHouses::getId, idList).list();
        return BeanUtil.copyProperties(housesList, PropertyHousesVo.class);
    }

    @Override
    public PropertyCustomerArchivesVo getCustomerInfoByHouseId(Long houseId) {
        Long customerArchivesId;
        // todo 返回租客信息？过虑无效，租客过期数据？
        PropertyHouseResident houseResident = houseResidentService.lambdaQuery().eq(PropertyHouseResident::getHouseId, houseId).orderByDesc(PropertyHouseResident::getCreateTime).last("LIMIT 1").one();
        if (Func.isNotEmpty(houseResident)) {
            customerArchivesId = houseResident.getCustomerArchivesId();

        } else {
            PropertyHouseOwner houseOwner = houseOwnerService.lambdaQuery().eq(PropertyHouseOwner::getHouseId, houseId).orderByDesc(PropertyHouseOwner::getCreateTime).last("LIMIT 1").one();
            if (Func.isEmpty(houseOwner)) {
                return null;
            }
            customerArchivesId = houseOwner.getCustomerArchivesId();
        }
        PropertyCustomerArchivesVo customerArchivesVo = getCustomerArchivesById(customerArchivesId);
        Date entryDate = Func.isNotEmpty(houseResident) ? houseResident.getStartDate() : null;
        customerArchivesVo.setEntryDate(entryDate);
        return customerArchivesVo;
    }

    @Override
    public List<PropertyCustomerArchivesVo> getCustomerListByHouseId(Long houseId) {
        List<Long> customerArchivesIdList = new ArrayList<>();
        List<PropertyHouseResident> houseResidentList = houseResidentService.lambdaQuery().eq(PropertyHouseResident::getHouseId, houseId).orderByDesc(PropertyHouseResident::getCreateTime).list();
        if (Func.isNotEmpty(houseResidentList)) {
            customerArchivesIdList = houseResidentList.stream().map(PropertyHouseResident::getCustomerArchivesId).collect(Collectors.toList());
        } else {
            List<PropertyHouseOwner> houseOwnerList = houseOwnerService.lambdaQuery().eq(PropertyHouseOwner::getHouseId, houseId).orderByDesc(PropertyHouseOwner::getCreateTime).list();
            if (Func.isEmpty(houseOwnerList)) {
                return null;
            }
            customerArchivesIdList = houseOwnerList.stream().map(PropertyHouseOwner::getCustomerArchivesId).collect(Collectors.toList());
        }
        List<PropertyCustomerArchives> customerArchivesList = this.lambdaQuery().in(PropertyCustomerArchives::getId, customerArchivesIdList).list();
        return BeanUtil.copyProperties(customerArchivesList, PropertyCustomerArchivesVo.class);
    }

    /**
     * @description 获取园区信息列表Map
     */
    private Map<Long, String> getParkMap() {
        List<PmgBatParkInfo> parkList = parkInfoService.getAllPark();
        return parkList.stream().collect(Collectors.toMap(PmgBatParkInfo::getId, PmgBatParkInfo::getParkName));
    }

    @Override
    public Long getPersonalCustomerArchivesId(String phone) {
        if (Func.isEmpty(phone)) {
            return null;
        }
        List<PropertyCustomerArchives> res = this.lambdaQuery().eq(PropertyCustomerArchives::getLinkPhoneOne, phone)
                .eq(PropertyCustomerArchives::getCustomerType, CustomerTypeEnum.PERSON.getValue()).list();
        if (Func.isEmpty(res)) {
            return null;
        } else if (res.size() > 1) {
            throw new ServiceException("手机号" + phone + "查询个人客户id失败，请联系技术人员");
        }
        return res.get(0).getId();
    }

    @Override
    public Long getOrgCustomerArchivesId(long deptId) {
        PropertyEnterpriseAddress enterpriseAddress = propertyEnterpriseAddressService
                .lambdaQuery().eq(PropertyEnterpriseAddress::getDeptId, deptId)
                .eq(PropertyEnterpriseAddress::getIsValid, 0).last("limit 1").one();
        if (enterpriseAddress == null) {
            return null;
        }
        PropertyHouseEnterprise houseEnterprise = houseEnterpriseService.getById(enterpriseAddress.getLinkId());
        if (houseEnterprise == null) {
            return null;
        }
        return houseEnterprise.getCustomerArchivesId();
    }


}
