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.manage.user.api.entity.User;
import com.yuchen.saas.manage.user.api.feign.IUserClient;
import com.yuchen.saas.park.api.dto.people.PropertyPeopleInfoSaveDTO;
import com.yuchen.saas.park.api.dto.people.PropertyPeopleRegisterApproveDTO;
import com.yuchen.saas.park.api.dto.people.PropertyPeopleRegisterDTO;
import com.yuchen.saas.park.api.dto.people.PropertyPeopleRegisterPageDTO;
import com.yuchen.saas.park.api.entity.park.PmgBatParkInfo;
import com.yuchen.saas.park.api.entity.park.people.SaasParkPropertyPeopleInfo;
import com.yuchen.saas.park.api.entity.park.people.SaasParkPropertyPeopleRegister;
import com.yuchen.saas.park.api.enums.PeopleRegisterEnum;
import com.yuchen.saas.park.api.vo.people.PropertyPeopleRegisterPageVO;
import com.yuchen.saas.park.service.mapper.people.SaasParkPropertyPeopleRegisterMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.people.ISaasParkPropertyPeopleInfoService;
import com.yuchen.saas.park.service.service.people.ISaasParkPropertyPeopleRegisterService;
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.validator.ValidatorUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 物业人员登记信息表 服务实现类
 * </p>
 *
 * @author linyb
 * @since 2024-11-30
 */
@Service
public class SaasParkPropertyPeopleRegisterServiceImpl extends BaseServiceImpl<SaasParkPropertyPeopleRegisterMapper, SaasParkPropertyPeopleRegister> implements ISaasParkPropertyPeopleRegisterService {

    @Resource
    private IUserClient userClient;

    @Resource
    private IOrgUserClient orgUserClient;

    @Resource
    private PmgBatParkInfoService parkInfoService;
    @Resource
    @Lazy
    private  ISaasParkPropertyPeopleInfoService peopleInfoService;

    @Override
    public Boolean save(PropertyPeopleRegisterDTO dto) {
        SaasParkPropertyPeopleRegister saasParkPropertyPeopleRegister = new SaasParkPropertyPeopleRegister();
        Func.copy(dto,saasParkPropertyPeopleRegister);
        saasParkPropertyPeopleRegister.setCertificationTime(new Date());
        return this.save(saasParkPropertyPeopleRegister);
    }

    @Override
    public NestPage<PropertyPeopleRegisterPageVO> getPage(PropertyPeopleRegisterPageDTO dto) {

        ValidatorUtils.validateEntity(dto);
        LambdaQueryWrapper<SaasParkPropertyPeopleRegister> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SaasParkPropertyPeopleRegister::getProjectId,dto.getProjectId());
        lambdaQueryWrapper.eq(Func.isNotEmpty(dto.getSex()),SaasParkPropertyPeopleRegister::getSex,dto.getSex());
        lambdaQueryWrapper.eq(Func.isNotEmpty(dto.getPeopleType()),SaasParkPropertyPeopleRegister::getPeopleType,dto.getPeopleType());
        lambdaQueryWrapper.like(Func.isNotEmpty(dto.getPhone()),SaasParkPropertyPeopleRegister::getPhone,dto.getPhone());
        lambdaQueryWrapper.like(Func.isNotEmpty(dto.getIdCard()),SaasParkPropertyPeopleRegister::getIdCard,dto.getIdCard());
        lambdaQueryWrapper.like(Func.isNotEmpty(dto.getUserName()),SaasParkPropertyPeopleRegister::getUserName,dto.getUserName());
        lambdaQueryWrapper.eq(Func.isNotEmpty(dto.getCertificationStatus()),SaasParkPropertyPeopleRegister::getCertificationStatus,dto.getCertificationStatus());
        IPage<SaasParkPropertyPeopleRegister> page = Condition.getPage(dto);
        IPage<SaasParkPropertyPeopleRegister> iPage = this.page(page, lambdaQueryWrapper);
        NestPage<PropertyPeopleRegisterPageVO> nestPage = new NestPage<>();
        nestPage.setSize(dto.getSize());
        nestPage.setCurrent(dto.getCurrent());
        List<SaasParkPropertyPeopleRegister> records = iPage.getRecords();
        if (Func.isEmpty(records)){
            return nestPage;
        }
        nestPage.setTotal(iPage.getTotal());
        List<Long> registerUserList = records.stream()
                                            .map(SaasParkPropertyPeopleRegister::getRegisterUserId)
                                            .filter(Func::isNotEmpty)
                                            .distinct()
                                            .collect(Collectors.toList());
        Map<Long, String> userMap =new HashMap<>(2);
        R<List<User>> userListR = userClient.findUserListByUserIds(registerUserList);
        if (R.isSuccess(userListR)&&Func.isNotEmpty(userListR.getData())){
            userMap= userListR.getData().stream()
                    .collect(Collectors.toMap(User::getId, User::getName));
        }

        List<Long> confirmOrgUserList = records.stream()
                .map(SaasParkPropertyPeopleRegister::getConfirmOrgUser)
                .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= confirmOrgUserListR.getData().stream()
                    .collect(Collectors.toMap(NestOrgUser::getId, NestOrgUser::getName));
        }
        List<Long> parkIdList = records.stream()
                .map(SaasParkPropertyPeopleRegister::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<PropertyPeopleRegisterPageVO> registerPageVOList =new ArrayList<>();
        for (SaasParkPropertyPeopleRegister e : records) {
            PropertyPeopleRegisterPageVO pageVO = new PropertyPeopleRegisterPageVO();
            pageVO.setId(e.getId());
            pageVO.setUserName(e.getUserName());
            pageVO.setIdCard(e.getIdCard());
            pageVO.setCertificationTime(e.getCertificationTime());
            pageVO.setCertificationStatus(e.getCertificationStatus());
            pageVO.setConfirmTime(e.getConfirmTime());
            pageVO.setCustomerId(e.getCustomerId());
            pageVO.setPhone(e.getPhone());
            pageVO.setSex(e.getSex());
            pageVO.setRegisterUserId(e.getRegisterUserId());
            if(Func.isNotEmpty(e.getRegisterUserId())){
                String userName = userMap.get(e.getRegisterUserId());
                pageVO.setRegisterUserName(userName);
            }
            pageVO.setIdCard(e.getIdCard());
            pageVO.setProjectId(e.getProjectId());
            if(Func.isNotEmpty(e.getProjectId())){
                String parkName = parkMap.get(e.getProjectId());
                pageVO.setProjectName(parkName);
            }
            pageVO.setPeopleType(e.getPeopleType());
            pageVO.setConfirmOrgUser(e.getConfirmOrgUser());
            if(Func.isNotEmpty(e.getConfirmOrgUser())){
                String orgUserName = confirmOrgUserMap.get(e.getConfirmOrgUser());
                pageVO.setConfirmOrgUserName(orgUserName);
            }
            pageVO.setFaceImgSrc(e.getFaceImgSrc());
            pageVO.setIdCardBackImgSrc(e.getIdCardBackImgSrc());
            pageVO.setIdCardFrontImgSrc(e.getIdCardFrontImgSrc());
            registerPageVOList.add(pageVO);
        }

        nestPage.setRecords(registerPageVOList);
        return nestPage;
    }

    @Override
    public PropertyPeopleRegisterPageVO info(Long id) {
        SaasParkPropertyPeopleRegister register = this.getById(id);
        if (Func.isEmpty(register)){
            throw new ServiceException("数据不存在！");
        }

        PropertyPeopleRegisterPageVO pageVO = new PropertyPeopleRegisterPageVO();
        pageVO.setId(register.getId());
        pageVO.setUserName(register.getUserName());
        pageVO.setIdCard(register.getIdCard());
        pageVO.setCertificationTime(register.getCertificationTime());
        pageVO.setCertificationStatus(register.getCertificationStatus());
        pageVO.setConfirmTime(register.getConfirmTime());
        pageVO.setCustomerId(register.getCustomerId());
        pageVO.setPhone(register.getPhone());
        pageVO.setSex(register.getSex());
        pageVO.setRegisterUserId(register.getRegisterUserId());
        if(Func.isNotEmpty(register.getRegisterUserId())){
            R<User> user = userClient.getUserById(register.getRegisterUserId());
            if (R.isSuccess(user)&&Func.isNotEmpty(user.getData())){
                String userName = user.getData().getName();
                pageVO.setRegisterUserName(userName);
            }
        }
        pageVO.setIdCard(register.getIdCard());
        pageVO.setProjectId(register.getProjectId());
        if(Func.isNotEmpty(register.getProjectId())){
            PmgBatParkInfo parkInfo = parkInfoService.getById(register.getProjectId());
            if (Func.isNotEmpty(parkInfo)){
                String parkName = parkInfo.getParkName();
                pageVO.setProjectName(parkName);
            }

        }
        pageVO.setPeopleType(register.getPeopleType());
        pageVO.setConfirmOrgUser(register.getConfirmOrgUser());
        if(Func.isNotEmpty(register.getConfirmOrgUser())){
            R<NestOrgUser> user = orgUserClient.detail(register.getRegisterUserId());
            if (R.isSuccess(user)&&Func.isNotEmpty(user.getData())){
                String orgUserName = user.getData().getName();
                pageVO.setConfirmOrgUserName(orgUserName);
            }
        }
        pageVO.setFaceImgSrc(register.getFaceImgSrc());
        pageVO.setIdCardBackImgSrc(register.getIdCardBackImgSrc());
        pageVO.setIdCardFrontImgSrc(register.getIdCardFrontImgSrc());
        return pageVO;
    }

    @Override
    public Boolean cancel(String id) {
        SaasParkPropertyPeopleRegister register = this.getById(Long.valueOf(id));
        if (Func.isEmpty(register)){
            throw new ServiceException("数据不存在！");
        }
        Long userId = AuthUtil.getUser().getUserId();
       if (!Func.equalsSafe(userId,register.getRegisterUserId())){
           throw new ServiceException("仅可取消自己的申请！");
       }
        if (!Func.equalsSafe(PeopleRegisterEnum.UNCONFIRMED.getCode(),register.getCertificationStatus())){
            throw new ServiceException("非待确认的记录无法取消！");
        }
        register.setCertificationStatus(PeopleRegisterEnum.CANCLE.getCode());
        return this.updateById(register);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean approve(PropertyPeopleRegisterApproveDTO dto) {
        SaasParkPropertyPeopleRegister register = this.getById(dto.getId());
        if (Func.isEmpty(register)){
            throw new ServiceException("数据不存在！");
        }
        if(dto.getApproveStatus()==2){
            register.setCertificationStatus(PeopleRegisterEnum.REJECTED.getCode());
            register.setConfirmTime(new Date());
            register.setConfirmOrgUser(AuthUtil.getUser().getOrgUserId());
            register.setUpdateOrgUser(AuthUtil.getUser().getOrgUserId());
            register.setApproveRemark(dto.getApproveRemark());
            return this.updateById(register);
        }
        if(dto.getApproveStatus()==1){
            register.setCertificationStatus(PeopleRegisterEnum.CONFIRMED.getCode());
            register.setConfirmTime(new Date());
            register.setConfirmOrgUser(AuthUtil.getUser().getOrgUserId());
            register.setUpdateOrgUser(AuthUtil.getUser().getOrgUserId());
            register.setApproveRemark(dto.getApproveRemark());
            boolean updateById = this.updateById(register);
            if(updateById){
                LambdaQueryWrapper<SaasParkPropertyPeopleInfo> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(SaasParkPropertyPeopleInfo::getIdCard,register.getIdCard());
                SaasParkPropertyPeopleInfo one = peopleInfoService.getOne(queryWrapper);
                if (Func.isNotEmpty(one)){
                    one.setBindStatus(1);
                    one.setBindAccount(register.getRegisterUserId());
                    one.setIdPhoto(register.getIdCardBackImgSrc()+","+register.getIdCardFrontImgSrc());
                    one.setFaceImgSrc(register.getFaceImgSrc());
                    one.setPhone(register.getPhone());
                    one.setUserName(register.getUserName());
                    one.setSex(register.getSex());
                    peopleInfoService.updateById(one);
                }else {
                    PropertyPeopleInfoSaveDTO saveDTO =new PropertyPeopleInfoSaveDTO();
                    Func.copy(register,saveDTO);
                    saveDTO.setBindStatus(1);
                    saveDTO.setBindAccount(register.getRegisterUserId());
                    saveDTO.setAddSource(3);
                    saveDTO.setIdPhoto(register.getIdCardBackImgSrc()+","+register.getIdCardFrontImgSrc());
                    peopleInfoService.save(saveDTO);
                }
            }
            return updateById;
        }
        return false;
    }



}
