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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yuchen.saas.manage.system.api.entity.NestOrgUser;
import com.yuchen.saas.manage.system.api.feign.IOrgUserClient;
import com.yuchen.saas.park.api.dto.people.PropertySpecialPeopleInfoSaveDTO;
import com.yuchen.saas.park.api.dto.people.PropertySpecialPeopleInfoUpdateDTO;
import com.yuchen.saas.park.api.dto.people.SpecialPeopleInfoPageDTO;
import com.yuchen.saas.park.api.entity.park.PmgBatParkInfo;
import com.yuchen.saas.park.api.entity.park.people.SaasParkSpecialPeopleInfo;
import com.yuchen.saas.park.api.entity.property.PropertyCustomerArchives;
import com.yuchen.saas.park.api.entity.property.PropertyHouses;
import com.yuchen.saas.park.api.enums.property.CreateTypeEnum;
import com.yuchen.saas.park.api.enums.property.CustomerCategoryEnum;
import com.yuchen.saas.park.api.enums.property.CustomerTypeEnum;
import com.yuchen.saas.park.api.enums.property.YesOrNoEnum;
import com.yuchen.saas.park.api.vo.people.SpecialPeopleInfoVO;
import com.yuchen.saas.park.api.vo.people.SpecialPeoplePageVO;
import com.yuchen.saas.park.service.mapper.people.SaasParkSpecialPeopleInfoMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.people.ISaasParkSpecialPeopleInfoService;
import com.yuchen.saas.park.service.service.property.IPropertyCustomerArchivesService;
import com.yuchen.saas.park.service.service.property.PropertyHousesService;
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.utils.AuthUtil;
import org.nest.springwrap.core.tool.api.R;
import org.nest.springwrap.core.tool.utils.Func;
import org.nest.springwrap.core.tool.utils.SpringUtil;
import org.nest.springwrap.core.tool.validator.ValidatorUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 特殊人员信息表 服务实现类
 * </p>
 *
 * @author linyb
 * @since 2024-12-02
 */
@Service
public class SaasParkSpecialPeopleInfoServiceImpl extends BaseServiceImpl<SaasParkSpecialPeopleInfoMapper, SaasParkSpecialPeopleInfo> implements ISaasParkSpecialPeopleInfoService {
    @Resource
    private PropertyHousesService housesService;


    @Resource
    private PmgBatParkInfoService parkInfoService;

    @Resource
    private IPropertyCustomerArchivesService iPropertyCustomerArchivesService;


    @Resource
    private IOrgUserClient orgUserClient;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(PropertySpecialPeopleInfoSaveDTO dto) {
        LambdaQueryWrapper<SaasParkSpecialPeopleInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaasParkSpecialPeopleInfo::getPhone, dto.getPhone());

        int one = this.count(queryWrapper);
        if (one > 0) {
            throw new ServiceException("该手机号已存在人员信息中");
        }

        if (Func.isNotEmpty(dto.getIdCard())) {
            LambdaQueryWrapper<SaasParkSpecialPeopleInfo> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(SaasParkSpecialPeopleInfo::getIdCard, dto.getIdCard());
            int one1 = this.count(queryWrapper);
            if (one1 > 0) {
                throw new ServiceException("该证件号已存在人员信息中");
            }
        }
        SaasParkSpecialPeopleInfo peopleInfo = new SaasParkSpecialPeopleInfo();
        Func.copy(dto, peopleInfo);
        if (Func.isNotEmpty(AuthUtil.getUser()) && Func.isNotEmpty(AuthUtil.getUser().getOrgUserId())) {
            peopleInfo.setUpdateOrgUser(AuthUtil.getUser().getOrgUserId());
            peopleInfo.setCreateOrgUser(AuthUtil.getUser().getOrgUserId());
        }
        peopleInfo.setEnableStatus(0);
        boolean save = this.save(peopleInfo);
        if (save) {
            SaasParkSpecialPeopleInfoServiceImpl bean = SpringUtil.getBean(SaasParkSpecialPeopleInfoServiceImpl.class);
            bean.sysPropertyCustomerArchives(peopleInfo);
        }
        return save;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(PropertySpecialPeopleInfoUpdateDTO dto) {
        SaasParkSpecialPeopleInfo specialPeopleInfo = this.getById(dto.getId());
        if (Func.isEmpty(specialPeopleInfo)) {
            throw new ServiceException("数据不存在");
        }
        LambdaQueryWrapper<SaasParkSpecialPeopleInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaasParkSpecialPeopleInfo::getPhone, dto.getPhone());
        queryWrapper.ne(SaasParkSpecialPeopleInfo::getId, dto.getFaceImgSrc());

        int one = this.count(queryWrapper);
        if (one > 0) {
            throw new ServiceException("该手机号已存在人员信息中");
        }

        if (Func.isNotEmpty(dto.getIdCard())) {
            LambdaQueryWrapper<SaasParkSpecialPeopleInfo> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(SaasParkSpecialPeopleInfo::getIdCard, dto.getIdCard());
            queryWrapper1.ne(SaasParkSpecialPeopleInfo::getId, dto.getFaceImgSrc());

            int one1 = this.count(queryWrapper);
            if (one1 > 0) {
                throw new ServiceException("该证件号已存在人员信息中");
            }
        }

        Func.copy(dto, specialPeopleInfo);
        if (Func.isNotEmpty(AuthUtil.getUser()) && Func.isNotEmpty(AuthUtil.getUser().getOrgUserId())) {
            specialPeopleInfo.setUpdateOrgUser(AuthUtil.getUser().getOrgUserId());
        }
        boolean update = this.updateById(specialPeopleInfo);

        return update;
    }

    @Override
    public SpecialPeopleInfoVO info(Long id) {
        SaasParkSpecialPeopleInfo specialPeopleInfo = this.getById(id);
        if (Func.isEmpty(specialPeopleInfo)) {
            throw new ServiceException("数据不存在");
        }
        SpecialPeopleInfoVO peopleInfoVO = new SpecialPeopleInfoVO();
        Func.copy(specialPeopleInfo, peopleInfoVO);

        Optional.ofNullable(peopleInfoVO.getHouseId()).ifPresent(houseId -> {
            String houseName = Optional.ofNullable(housesService.getById(houseId))
                    .map(PropertyHouses::getHouseName)
                    .orElse(null);
            peopleInfoVO.setHouseName(houseName);
        });
        Optional.ofNullable(peopleInfoVO.getRegisterOrgUser())
                .flatMap(registerOrgUser -> Optional.ofNullable(orgUserClient.detail(registerOrgUser))
                        .filter(e -> R.isSuccess(e))
                        .map(R::getData)
                        .filter(Func::isNotEmpty)
                        .map(NestOrgUser::getName))
                .ifPresent(peopleInfoVO::setRegisterOrgUserName);

        Optional.ofNullable(peopleInfoVO.getProjectId()).ifPresent(projectId -> {
            String parkName = Optional.ofNullable(parkInfoService.getById(projectId))
                    .map(PmgBatParkInfo::getParkName)
                    .orElse(null);
            peopleInfoVO.setProjectName(parkName);
        });
        return peopleInfoVO;
    }

    @Override
    public NestPage<SpecialPeoplePageVO> getPage(SpecialPeopleInfoPageDTO dto) {
        ValidatorUtils.validateEntity(dto);
        LambdaQueryWrapper<SaasParkSpecialPeopleInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SaasParkSpecialPeopleInfo::getProjectId, dto.getProjectId());
        lambdaQueryWrapper.like(Func.isNotEmpty(dto.getUserName()), SaasParkSpecialPeopleInfo::getUserName, dto.getUserName());
        lambdaQueryWrapper.eq(Func.isNotEmpty(dto.getSex()), SaasParkSpecialPeopleInfo::getSex, dto.getSex());
        lambdaQueryWrapper.like(Func.isNotEmpty(dto.getPhone()), SaasParkSpecialPeopleInfo::getPhone, dto.getPhone());
        lambdaQueryWrapper.like(Func.isNotEmpty(dto.getIdCard()), SaasParkSpecialPeopleInfo::getIdCard, dto.getIdCard());
        lambdaQueryWrapper.eq(Func.isNotEmpty(dto.getIdType()), SaasParkSpecialPeopleInfo::getIdType, dto.getIdType());
        lambdaQueryWrapper.eq(Func.isNotEmpty(dto.getEnableStatus()), SaasParkSpecialPeopleInfo::getEnableStatus, dto.getEnableStatus());
        lambdaQueryWrapper.ge(Func.isNotEmpty(dto.getRegisterStartTime()), SaasParkSpecialPeopleInfo::getRegisterTime, dto.getRegisterStartTime());
        lambdaQueryWrapper.le(Func.isNotEmpty(dto.getRegisterEndTime()), SaasParkSpecialPeopleInfo::getRegisterTime, dto.getRegisterEndTime());
        lambdaQueryWrapper.eq(Func.isNotEmpty(dto.getPeopleType()), SaasParkSpecialPeopleInfo::getPeopleType, dto.getPeopleType());
        lambdaQueryWrapper.in(SaasParkSpecialPeopleInfo::getPeopleType, 17, 18);
        IPage<SaasParkSpecialPeopleInfo> page = Condition.getPage(dto);
        IPage<SaasParkSpecialPeopleInfo> iPage = this.page(page, lambdaQueryWrapper);
        NestPage<SpecialPeoplePageVO> nestPage = new NestPage<>();
        nestPage.setSize(dto.getSize());
        nestPage.setCurrent(dto.getCurrent());
        List<SaasParkSpecialPeopleInfo> records = iPage.getRecords();
        if (Func.isEmpty(records)) {
            return nestPage;
        }
        nestPage.setTotal(iPage.getTotal());


        List<Long> confirmOrgUserList = records.stream()
                .map(SaasParkSpecialPeopleInfo::getRegisterOrgUser)
                .filter(Func::isNotEmpty)
                .distinct()
                .collect(Collectors.toList());
        Map<Long, String> confirmOrgUserMap = new HashMap<>(2);
        R<List<NestOrgUser>> confirmOrgUserListR = orgUserClient.findOrgUserListByIds(confirmOrgUserList);
        if (R.isSuccess(confirmOrgUserListR) && Func.isNotEmpty(confirmOrgUserListR.getData())) {
            confirmOrgUserMap.putAll(confirmOrgUserListR.getData().stream()
                    .collect(Collectors.toMap(NestOrgUser::getId, NestOrgUser::getName)));
        }

        List<Long> parkIdList = records.stream()
                .map(SaasParkSpecialPeopleInfo::getProjectId)
                .filter(Func::isNotEmpty)
                .distinct()
                .collect(Collectors.toList());
        List<PmgBatParkInfo> parkInfoList = parkInfoService.listByIds(parkIdList);
        Map<Long, String> parkMap = parkInfoList.stream()
                .collect(Collectors.toMap(PmgBatParkInfo::getId, PmgBatParkInfo::getParkName));
        List<SpecialPeoplePageVO> infoPageVOS = records.stream()
                .map(e -> {
                    SpecialPeoplePageVO pageVO = new SpecialPeoplePageVO();
                    Func.copy(e, pageVO);

                    if (Func.isNotEmpty(e.getProjectId())) {
                        String parkName = parkMap.get(e.getProjectId());
                        pageVO.setProjectName(parkName);
                    }
                    pageVO.setPeopleType(e.getPeopleType());
                    if (Func.isNotEmpty(e.getRegisterOrgUser())) {
                        String orgUserName = confirmOrgUserMap.get(e.getRegisterOrgUser());
                        pageVO.setRegisterOrgUserName(orgUserName);
                    }

                    return pageVO;
                }).collect(Collectors.toList());
        nestPage.setRecords(infoPageVOS);
        return nestPage;
    }

    @Async
    //todo 同步人员档案 后期需求
    public void sysPropertyCustomerArchives(SaasParkSpecialPeopleInfo peopleInfo) {
        if (Func.isNotEmpty(peopleInfo.getIdCard())) {
            Integer count = iPropertyCustomerArchivesService.lambdaQuery().eq(PropertyCustomerArchives::getIdNo, peopleInfo.getIdCard()).count();
            if (count > 0) {
                return;
            }
        }
        PropertyCustomerArchives createCustomerArchives = new PropertyCustomerArchives();
        createCustomerArchives.setParkId(peopleInfo.getProjectId());
        createCustomerArchives.setCustomerType(CustomerTypeEnum.PERSON.getValue());
        createCustomerArchives.setCustomerCategory(CustomerCategoryEnum.OTHER.getValue());
        createCustomerArchives.setCustomerName(peopleInfo.getUserName());
        createCustomerArchives.setIdNo(peopleInfo.getIdCard());
        createCustomerArchives.setIdType(Integer.valueOf(peopleInfo.getIdType()));
        createCustomerArchives.setLinkManOne(peopleInfo.getUserName());
        createCustomerArchives.setLinkPhoneOne(peopleInfo.getPhone());
        createCustomerArchives.setFacePhoto(peopleInfo.getFaceImgSrc());
        createCustomerArchives.setSex(Integer.valueOf(peopleInfo.getSex()));
        createCustomerArchives.setCreateType(CreateTypeEnum.AUTO_SYNC.getValue());
        createCustomerArchives.setCreatePeopleId(AuthUtil.getUser().getUserDetailId());
        createCustomerArchives.setIsLink(YesOrNoEnum.YES.getValue());
        iPropertyCustomerArchivesService.save(createCustomerArchives);

    }
}
