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

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuchen.saas.manage.dict.api.feign.IDictClient;
import com.yuchen.saas.manage.system.api.entity.Dept;
import com.yuchen.saas.manage.system.api.feign.DeptFeignServer;
import com.yuchen.saas.park.api.dto.property.PropertyEnterpriseRegisterAuditDto;
import com.yuchen.saas.park.api.dto.property.PropertyEnterpriseRegisterDto;
import com.yuchen.saas.park.api.dto.property.PropertyEnterpriseRegisterQueryDto;
import com.yuchen.saas.park.api.dto.property.PropertyEnterpriseRegisterUpdateDto;
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.PropertyEnterpriseRegisterMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.property.IPropertyCustomerArchivesService;
import com.yuchen.saas.park.service.service.property.IPropertyEnterpriseAddressService;
import com.yuchen.saas.park.service.service.property.IPropertyEnterpriseRegisterService;
import com.yuchen.saas.park.service.service.property.IPropertyHouseEnterpriseService;
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.Condition;
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
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 PropertyEnterpriseRegisterServiceImpl extends BaseServiceImpl<PropertyEnterpriseRegisterMapper, PropertyEnterpriseRegister> implements IPropertyEnterpriseRegisterService {

    @Resource
    private PmgBatParkInfoService parkInfoService;
    @Resource
    private IPropertyCustomerArchivesService customerArchivesService;
    @Resource
    private IPropertyHouseEnterpriseService enterpriseService;
    @Resource
    private IPropertyEnterpriseAddressService enterpriseAddressService;
    @Resource
    private DeptFeignServer deptFeignServer;
    @Resource
    private IDictClient dictClient;

    @Override
    public PropertyEnterpriseRegisterResultVo register(PropertyEnterpriseRegisterDto enterpriseRegisterDto) {
        PropertyEnterpriseRegister select = this.lambdaQuery().eq(PropertyEnterpriseRegister::getEnterpriseId, enterpriseRegisterDto.getEnterpriseId())
                .eq(PropertyEnterpriseRegister::getParkId, enterpriseRegisterDto.getParkId()).eq(PropertyEnterpriseRegister::getReviewStatus, 1).one();
        if(Func.isNotEmpty(select))  {
            throw new ServiceException("已提交该园区入驻登记，请勿重复提交");
        }

        log.info("enterpriseId: {}", enterpriseRegisterDto.getEnterpriseId());
        Dept dept = deptFeignServer.getDept(enterpriseRegisterDto.getEnterpriseId()).getData();
        if (Func.isEmpty(dept)) {
            throw new ServiceException("组织不存在");
        }
        if (dept.getCerStatus() == 0) {
            throw new ServiceException("请先完成企业认证");
        }
        if (Func.isEmpty(dept.getCreditCode())) {
            throw new ServiceException("统一信用代码为空");
        }
        log.info("dept: {}", dept);
        LambdaQueryWrapper<PropertyCustomerArchives> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PropertyCustomerArchives::getOrganType, dept.getOrganType());
        queryWrapper.eq(PropertyCustomerArchives::getOrganIndustry, dept.getOrganTrade());
        queryWrapper.eq(PropertyCustomerArchives::getIdType, IdTypeEnum.BUSINESS_LICENSE.getValue());
        queryWrapper.eq(PropertyCustomerArchives::getIdNo, dept.getCreditCode());
        List<PropertyCustomerArchives> list = customerArchivesService.list(queryWrapper);
        PropertyEnterpriseRegister enterpriseRegister = BeanUtil.copyProperties(enterpriseRegisterDto, PropertyEnterpriseRegister.class);
        PropertyEnterpriseRegisterResultVo resultVo = new PropertyEnterpriseRegisterResultVo();
        resultVo.setResult(1);
        if (Func.isEmpty(list)) {
            enterpriseRegister.setOrganType(dept.getOrganType());
            enterpriseRegister.setOrganIndustry(dept.getOrganTrade());
            enterpriseRegister.setOrganScale(dept.getOrganScope());
            enterpriseRegister.setIdType(IdTypeEnum.BUSINESS_LICENSE.getValue());
            enterpriseRegister.setIdNo(dept.getCreditCode());
            save(enterpriseRegister);
            resultVo.setResult(2);
        } else {
            List<Long> idList = list.stream().map(PropertyCustomerArchives::getId).collect(Collectors.toList());
            List<PropertyHouseEnterprise> enterpriseList = enterpriseService.lambdaQuery().in(PropertyHouseEnterprise::getCustomerArchivesId, idList).list();
            if (Func.isEmpty(enterpriseList)) {
                enterpriseRegister.setOrganType(dept.getOrganType());
                enterpriseRegister.setOrganIndustry(dept.getOrganTrade());
                enterpriseRegister.setOrganScale(dept.getOrganScope());
                enterpriseRegister.setIdType(IdTypeEnum.BUSINESS_LICENSE.getValue());
                enterpriseRegister.setIdNo(dept.getCreditCode());
                save(enterpriseRegister);
                resultVo.setResult(2);
            } else {
                enterpriseList.forEach(enterprise -> {
                    LambdaQueryWrapper<PropertyEnterpriseAddress> query = Wrappers.lambdaQuery();
                    query.eq(PropertyEnterpriseAddress::getDeptId, enterpriseRegisterDto.getEnterpriseId());
                    query.eq(PropertyEnterpriseAddress::getHouseId, enterprise.getHouseId());
                    query.eq(PropertyEnterpriseAddress::getLinkId, enterprise.getId());
                    PropertyEnterpriseAddress address = enterpriseAddressService.getOne(query);
                    if (Func.isNotEmpty(address)) {
                        address.setIsValid(0);
                        enterpriseAddressService.updateById(address);
                    } else {
                        PropertyEnterpriseAddress enterpriseAddress = new PropertyEnterpriseAddress();
                        enterpriseAddress.setParkId(enterprise.getParkId());
                        enterpriseAddress.setDeptId(enterpriseRegisterDto.getEnterpriseId());
                        enterpriseAddress.setHouseId(enterprise.getHouseId());
                        enterpriseAddress.setIsValid(0);
                        enterpriseAddress.setLinkId(enterprise.getId());
                        enterpriseAddressService.save(enterpriseAddress);
                    }
                    enterprise.setRegisterMark(1);
                    enterprise.setRegisterStatus(RegisterStatusEnum.REGISTERED.getValue());
                    enterpriseService.updateById(enterprise);
                });
            }
        }
        return resultVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean audit(PropertyEnterpriseRegisterAuditDto auditDto) {
        PropertyEnterpriseRegister enterpriseRegister = getById(auditDto.getId());
        enterpriseRegister.setReviewStatus(auditDto.getReviewStatus());
        if (auditDto.getReviewStatus() == AuditStatusEnum.PASS.getValue()) {
            //同步客户档案
            PropertyCustomerArchives customerArchives = BeanUtil.copyProperties(enterpriseRegister, PropertyCustomerArchives.class);
            customerArchives.setCustomerType(CustomerTypeEnum.ORGAN.getValue());
            customerArchives.setCustomerCategory(CustomerCategoryEnum.HOUSE_TENANT.getValue());
            customerArchives.setCustomerName(enterpriseRegister.getEnterpriseName());
            customerArchives.setLinkManOne(enterpriseRegister.getLinkMan());
            customerArchives.setLinkPhoneOne(enterpriseRegister.getLinkPhone());
            customerArchives.setCreateType(CreateTypeEnum.AUTO_SYNC.getValue());
            ContextUser contextUser = AuthUtil.getUser();
            if (Func.isEmpty(contextUser)) {
                throw new ServiceException("用户不存在");
            }
            Long createPeopleId = contextUser.getUserDetailId();
            customerArchives.setCreatePeopleId(createPeopleId);
            customerArchives.setIsLink(YesOrNoEnum.YES.getValue());
            customerArchivesService.save(customerArchives);
            //同步园区入驻企业
            List<Long> houseIdList = Func.toLongList(enterpriseRegister.getHouseIds());
            for (Long houseId : houseIdList) {
                PropertyHouseEnterprise enterprise = BeanUtil.copyProperties(enterpriseRegister, PropertyHouseEnterprise.class);
                enterprise.setId(null);
                enterprise.setCustomerArchivesId(customerArchives.getId());
                enterprise.setSettleInType(2);
                enterprise.setHouseId(houseId);
                enterprise.setStartDate(enterpriseRegister.getEntryDate());
                enterprise.setEntryStatus(EntryStatusEnum.ENTRY.getValue());
                enterprise.setCreateType(CreateTypeEnum.AUTO_SYNC.getValue());
                enterprise.setCreatePeopleId(createPeopleId);
                enterprise.setRegisterStatus(RegisterStatusEnum.REGISTERED.getValue());
                enterpriseService.save(enterprise);

                LambdaQueryWrapper<PropertyEnterpriseAddress> query = Wrappers.lambdaQuery();
                query.eq(PropertyEnterpriseAddress::getDeptId, enterpriseRegister.getEnterpriseId());
                query.eq(PropertyEnterpriseAddress::getHouseId, enterprise.getHouseId());
                query.eq(PropertyEnterpriseAddress::getLinkId, enterprise.getId());
                PropertyEnterpriseAddress address = enterpriseAddressService.getOne(query);
                if (Func.isNotEmpty(address)) {
                    address.setIsValid(0);
                    enterpriseAddressService.updateById(address);
                } else {
                    PropertyEnterpriseAddress enterpriseAddress = new PropertyEnterpriseAddress();
                    enterpriseAddress.setParkId(enterprise.getParkId());
                    enterpriseAddress.setDeptId(enterpriseRegister.getEnterpriseId());
                    enterpriseAddress.setHouseId(enterprise.getHouseId());
                    enterpriseAddress.setIsValid(0);
                    enterpriseAddress.setLinkId(enterprise.getId());
                    enterpriseAddressService.save(enterpriseAddress);
                }
            }

        }
        return updateById(enterpriseRegister);
    }

    @Override
    public Boolean updateStatus(PropertyEnterpriseRegisterUpdateDto updateDto) {
        PropertyEnterpriseRegister enterpriseRegister = getById(updateDto.getId());
        enterpriseRegister.setStatus(updateDto.getStatus());
        return updateById(enterpriseRegister);
    }

    @Override
    public NestPage<PropertyEnterpriseRegisterListVo> getEnterpriseRegisterList(PropertyEnterpriseRegisterQueryDto queryDto) {
        LambdaQueryWrapper<PropertyEnterpriseRegister> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Func.isNotEmpty(queryDto.getParkId()), PropertyEnterpriseRegister::getParkId, queryDto.getParkId());
        queryWrapper.like(Func.isNotEmpty(queryDto.getHouseName()), PropertyEnterpriseRegister::getHouseNames, queryDto.getHouseName());
        queryWrapper.eq(Func.isNotEmpty(queryDto.getEnterpriseId()), PropertyEnterpriseRegister::getEnterpriseId, queryDto.getEnterpriseId());
        queryWrapper.like(Func.isNotEmpty(queryDto.getEnterpriseName()), PropertyEnterpriseRegister::getEnterpriseName, queryDto.getEnterpriseName());
        queryWrapper.eq(Func.isNotEmpty(queryDto.getOrganType()), PropertyEnterpriseRegister::getOrganType, queryDto.getOrganType());
        queryWrapper.like(Func.isNotEmpty(queryDto.getLinkPhone()), PropertyEnterpriseRegister::getLinkPhone, queryDto.getLinkPhone());
        queryWrapper.eq(Func.isNotEmpty(queryDto.getIdType()), PropertyEnterpriseRegister::getIdType, queryDto.getIdType());
        queryWrapper.like(Func.isNotEmpty(queryDto.getIdNo()), PropertyEnterpriseRegister::getIdNo, queryDto.getIdNo());
        queryWrapper.ge(Func.isNotEmpty(queryDto.getRegisterStartTime()), PropertyEnterpriseRegister::getCreateTime, queryDto.getRegisterStartTime());
        queryWrapper.le(Func.isNotEmpty(queryDto.getRegisterEndTime()), PropertyEnterpriseRegister::getCreateTime, queryDto.getRegisterEndTime());
        queryWrapper.eq(Func.isNotEmpty(queryDto.getReviewStatus()), PropertyEnterpriseRegister::getReviewStatus, queryDto.getReviewStatus());
        IPage<PropertyEnterpriseRegister> page = this.page(Condition.getPage(queryDto), queryWrapper);
        List<PropertyEnterpriseRegisterListVo> list = BeanUtil.copyProperties(page.getRecords(), PropertyEnterpriseRegisterListVo.class);
        Map<Long, String> parkMap = getParkMap();
        for (PropertyEnterpriseRegisterListVo vo : list) {
            vo.setParkName(parkMap.get(vo.getParkId()));
        }
        IPage<PropertyEnterpriseRegisterListVo> result = new Page<>(queryDto.getCurrent(), queryDto.getSize(), page.getTotal());
        result.setRecords(list);
        return NestPage.of(result);
    }

    @Override
    public void exportEnterpriseRegister(PropertyEnterpriseRegisterQueryDto queryDto, HttpServletResponse response) {
        LambdaQueryWrapper<PropertyEnterpriseRegister> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Func.isNotEmpty(queryDto.getParkId()), PropertyEnterpriseRegister::getParkId, queryDto.getParkId());
        queryWrapper.like(Func.isNotEmpty(queryDto.getHouseName()), PropertyEnterpriseRegister::getHouseNames, queryDto.getHouseName());
        queryWrapper.like(Func.isNotEmpty(queryDto.getEnterpriseName()), PropertyEnterpriseRegister::getEnterpriseName, queryDto.getEnterpriseName());
        queryWrapper.eq(Func.isNotEmpty(queryDto.getOrganType()), PropertyEnterpriseRegister::getOrganType, queryDto.getOrganType());
        queryWrapper.like(Func.isNotEmpty(queryDto.getLinkPhone()), PropertyEnterpriseRegister::getLinkPhone, queryDto.getLinkPhone());
        queryWrapper.eq(Func.isNotEmpty(queryDto.getIdType()), PropertyEnterpriseRegister::getIdType, queryDto.getIdType());
        queryWrapper.like(Func.isNotEmpty(queryDto.getIdNo()), PropertyEnterpriseRegister::getIdNo, queryDto.getIdNo());
        queryWrapper.ge(Func.isNotEmpty(queryDto.getRegisterStartTime()), PropertyEnterpriseRegister::getCreateTime, queryDto.getRegisterStartTime());
        queryWrapper.le(Func.isNotEmpty(queryDto.getRegisterEndTime()), PropertyEnterpriseRegister::getCreateTime, queryDto.getRegisterEndTime());
        queryWrapper.eq(Func.isNotEmpty(queryDto.getReviewStatus()), PropertyEnterpriseRegister::getReviewStatus, queryDto.getReviewStatus());
        List<PropertyEnterpriseRegister> registerList = this.list(queryWrapper);
        List<PropertyEnterpriseRegisterExcelVo> resultList = BeanUtil.copyProperties(registerList, PropertyEnterpriseRegisterExcelVo.class);
        Map<Long, String> parkMap = getParkMap();
        for (PropertyEnterpriseRegisterExcelVo vo : resultList) {
            vo.setParkName(parkMap.get(vo.getParkId()));
            String organType = dictClient.getValue("organ_type", vo.getOrganType()).getData();
            vo.setOrganType(organType);
            String organIndustry = dictClient.getValue("company_trade", vo.getOrganIndustry()).getData();
            vo.setOrganIndustry(organIndustry);
            vo.setIdTypeName(IdTypeEnum.getDescByCode(vo.getIdType()));
            vo.setReviewStatusName(AuditStatusEnum.getDescByCode(vo.getReviewStatus()));
        }
        try {
            String fileName = URLEncoder.encode("企业入驻登记表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), PropertyEnterpriseRegisterExcelVo.class)
                    .sheet("企业入驻登记表")
                    .doWrite(resultList); //最终处理好的数据结果集list
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

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

}
