package jnpf.personnels.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.tencentcloudapi.faceid.v20180301.models.IdCardVerificationResponse;
import jnpf.base.ActionResult;
import jnpf.base.entity.SuperBaseEntity;
import jnpf.base.vo.PageListVO;
import jnpf.base.vo.PaginationVO;
import jnpf.cultivate.mapper.FtbCultivateFileMapper;
import jnpf.model.cultivate.CultivatePage;
import jnpf.model.cultivate.event.JnpfApplicationEvent;
import jnpf.model.cultivate.event.dto.file.FileEventDTO;
import jnpf.model.cultivate.po.FtbCultivateFile;
import jnpf.model.personnels.dto.uchisuike.DeleteRecommendedPersonnelDTO;
import jnpf.model.personnels.dto.uchisuike.FtbRecommendationPoolOrgDTO;
import jnpf.model.personnels.dto.uchisuike.FtbinternalRecommendationPoolListDTO;
import jnpf.model.personnels.dto.uchisuike.app.FtbRecommendationInvitationAppDTO;
import jnpf.model.personnels.po.FtbPersonnelsStaffEmploymentApply;
import jnpf.model.personnels.po.FtbPersonnelsStaffRoster;
import jnpf.model.personnels.po.FtbPersonnelsUchisuikePond;
import jnpf.model.personnels.po.FtbPersonnelsUchisuikePondOrg;
import jnpf.model.personnels.vo.uchisuike.FtbinternalRecommendationPoolVO;
import jnpf.permission.V2OrganizeApi;
import jnpf.permission.V2UserApi;
import jnpf.permission.eum.v2.OrganizeCategoryEnums;
import jnpf.permission.vo.v2.organzie.OrganizeGeneralDetailVO;
import jnpf.personnels.mapper.FtbPersonnelsStaffEmploymentApplyMapper;
import jnpf.personnels.mapper.FtbPersonnelsUchisuikePondMapper;
import jnpf.personnels.mapper.FtbPersonnelsUchisuikePondOrgMapper;
import jnpf.personnels.service.FtbPersonnelsStaffRosterService;
import jnpf.personnels.service.FtbPersonnelsUchisuikePondService;
import jnpf.personnels.utils.PersonnelIdCardVerificationUtils;
import jnpf.util.TenantUtil;
import jnpf.util.context.SpringContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class FtbPersonnelsUchisuikePondServiceImpl extends ServiceImpl<FtbPersonnelsUchisuikePondMapper, FtbPersonnelsUchisuikePond> implements FtbPersonnelsUchisuikePondService {

    @Resource
    private FtbCultivateFileMapper ftbCultivateFileMapper;

    @Resource
    private TenantUtil tenantUtil;

    @Resource
    private FtbPersonnelsStaffRosterService ftbPersonnelsStaffRosterService;

    @Autowired
    private V2UserApi v2UserApi;

    @Autowired
    private V2OrganizeApi v2OrganizeApi;

    @Resource
    private FtbPersonnelsUchisuikePondOrgMapper ftbPersonnelsUchisuikePondOrgMapper;

    @Resource
    private FtbPersonnelsStaffEmploymentApplyMapper applyMapper;
    @Resource
    private PersonnelIdCardVerificationUtils personnelIdCardVerificationUtils;

    @Override
    public List<FtbCultivateFile> viewResume(String id) {
        LambdaQueryWrapper<FtbCultivateFile> ftbCultivateFileLambdaQueryWrapper = Wrappers.lambdaQuery();
        ftbCultivateFileLambdaQueryWrapper.eq(FtbCultivateFile::getBusinessId, id);
        ftbCultivateFileLambdaQueryWrapper.eq(FtbCultivateFile::getEnabledMark, 0);
        ftbCultivateFileLambdaQueryWrapper.eq(FtbCultivateFile::getType, FileEventDTO.FileType.INTERNAL_RECOMMENDATION_POOL_RESUME.getType());
        return ftbCultivateFileMapper.selectList(ftbCultivateFileLambdaQueryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRecommendedPersonnel(DeleteRecommendedPersonnelDTO dto) {
        LambdaUpdateWrapper<FtbPersonnelsUchisuikePond> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.in(SuperBaseEntity.SuperIBaseEntity::getId, dto.getIds());
        updateWrapper.set(FtbPersonnelsUchisuikePond::getEnableMark, 1);
        this.update(new FtbPersonnelsUchisuikePond(), updateWrapper);
    }

    @Override
    public FtbinternalRecommendationPoolVO internalRecommendationDetails(String id) {
        FtbPersonnelsUchisuikePond ftbPersonnelsUchisuikePond = this.baseMapper.selectById(id);
        return FtbinternalRecommendationPoolVO.convert(ftbPersonnelsUchisuikePond);
    }

    @Override
    public PageListVO<FtbinternalRecommendationPoolVO> internalRecommendationPoolListQuery(CultivatePage cultivatePage, FtbinternalRecommendationPoolListDTO ftbinternalRecommendationPoolListDTO) {
        PageListVO<FtbinternalRecommendationPoolVO> pageListVO = new PageListVO<>();
        Page<FtbPersonnelsUchisuikePond> page = cultivatePage.coverCultivatePage();
        LambdaQueryWrapper<FtbPersonnelsUchisuikePond> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.orderByDesc(SuperBaseEntity.SuperCBaseEntity::getId);
        queryWrapper.eq(FtbPersonnelsUchisuikePond::getEnableMark, 0);
        // 工作状态
        if (Objects.nonNull(ftbinternalRecommendationPoolListDTO.getWorkState())) {
            if (ftbinternalRecommendationPoolListDTO.getWorkState() == 0) {
                queryWrapper.eq(FtbPersonnelsUchisuikePond::getState, 0);
            } else if (ftbinternalRecommendationPoolListDTO.getWorkState() == 1) {
                queryWrapper.gt(FtbPersonnelsUchisuikePond::getState, 0);
            }
        }
        // 来源
        queryWrapper.eq(Objects.nonNull(ftbinternalRecommendationPoolListDTO.getSource()), FtbPersonnelsUchisuikePond::getSource, ftbinternalRecommendationPoolListDTO.getSource());
        // 时间
        queryWrapper.between(Objects.nonNull(ftbinternalRecommendationPoolListDTO.getBeginTime()) && Objects.nonNull(ftbinternalRecommendationPoolListDTO.getEndTime()),
                SuperBaseEntity.SuperCBaseEntity::getCreatorTime, ftbinternalRecommendationPoolListDTO.getBeginTime(), ftbinternalRecommendationPoolListDTO.getEndTime());
        // 关键字
        queryWrapper.and(StringUtils.isNotBlank(ftbinternalRecommendationPoolListDTO.getKeyword()), t -> {
            t.like(FtbPersonnelsUchisuikePond::getUserName, ftbinternalRecommendationPoolListDTO.getKeyword());
            t.or();
            t.like(FtbPersonnelsUchisuikePond::getPhone, ftbinternalRecommendationPoolListDTO.getKeyword());
            t.or();
            t.like(FtbPersonnelsUchisuikePond::getIdCard, ftbinternalRecommendationPoolListDTO.getKeyword());
            t.or();
            t.like(FtbPersonnelsUchisuikePond::getOrgName, ftbinternalRecommendationPoolListDTO.getKeyword())
            ;
        });
        Page<FtbPersonnelsUchisuikePond> ftbPersonnelsUchisuikePondPage = this.baseMapper.selectPage(page, queryWrapper);
        // 返回结果
        PaginationVO pagination = new PaginationVO();
        pagination.setCurrentPage(ftbPersonnelsUchisuikePondPage.getCurrent());
        pagination.setPageSize(ftbPersonnelsUchisuikePondPage.getSize());
        long total = ftbPersonnelsUchisuikePondPage.getTotal();
        pagination.setTotal(Math.toIntExact(total));
        pageListVO.setPagination(pagination);
        List<FtbinternalRecommendationPoolVO> ftbinternalRecommendationPoolVOS = ftbPersonnelsUchisuikePondPage.getRecords()
                .stream().map(FtbinternalRecommendationPoolVO::convert)
                .peek(ftbinternalRecommendationPoolVO -> {
                    ftbinternalRecommendationPoolVO.setPushUserName(
                            StrUtil.isNotBlank(ftbinternalRecommendationPoolVO.getPushUserId()) ?
                                    v2UserApi.getUsersBound(ftbinternalRecommendationPoolVO.getPushUserId(), null).getData().getUserName() : null
                    );
                    if (ftbinternalRecommendationPoolVO.getState() > 0) {
                        ftbinternalRecommendationPoolVO.setIsSubmitForm(1);
                    } else {
                        // 登记表状态
                        LambdaQueryWrapper<FtbPersonnelsStaffEmploymentApply> applyQueryWrapper = Wrappers.lambdaQuery();
                        applyQueryWrapper.eq(FtbPersonnelsStaffEmploymentApply::getPhone, ftbinternalRecommendationPoolVO.getPhone());
                        applyQueryWrapper.last("limit 1");
                        FtbPersonnelsStaffEmploymentApply apply = applyMapper.selectOne(applyQueryWrapper);
                        if (Objects.nonNull(apply)) {
                            ftbinternalRecommendationPoolVO.setIsSubmitForm(apply.getIsSubmitForm());
                        } else {
                            LambdaQueryWrapper<FtbPersonnelsStaffRoster> rosterQueryWrapper = Wrappers.lambdaQuery();
                            rosterQueryWrapper.eq(FtbPersonnelsStaffRoster::getPhone, ftbinternalRecommendationPoolVO.getPhone());
                            rosterQueryWrapper.last("limit 1");
                            rosterQueryWrapper.eq(FtbPersonnelsStaffRoster::getEnabledMark, 0);
                            FtbPersonnelsStaffRoster roster = ftbPersonnelsStaffRosterService.getOne(rosterQueryWrapper);
                            if (Objects.nonNull(roster)) {
                                ftbinternalRecommendationPoolVO.setIsSubmitForm(1);
                            } else {
                                ftbinternalRecommendationPoolVO.setIsSubmitForm(0);
                            }
                        }
                    }
                })
                .collect(Collectors.toList());
        pageListVO.setList(ftbinternalRecommendationPoolVOS);
        return pageListVO;
    }

    @Override
    @DSTransactional
    public void internalRecommendationInvitationAdded(FtbRecommendationInvitationAppDTO ftbRecommendationInvitationAppDTO) {
        tenantUtil.switchTenant(ftbRecommendationInvitationAppDTO.getTenantId());
        // 校验手机号是否重复
        var queryWrapper = this.lambdaQuery()
                .eq(FtbPersonnelsUchisuikePond::getPhone, ftbRecommendationInvitationAppDTO.getPhone())
                .eq(FtbPersonnelsUchisuikePond::getEnableMark, 0)
                .count();
        if (queryWrapper > 0) {
            throw new RuntimeException("此手机号已存在于系统中，请勿重复添加");
        }
        // 校验身份证+姓名是否合法
        IdCardVerificationResponse idCardVerificationResponse = personnelIdCardVerificationUtils.idCardVerification(ftbRecommendationInvitationAppDTO.getIdCard(), ftbRecommendationInvitationAppDTO.getUserName(), ftbRecommendationInvitationAppDTO.getTenantId());
        personnelIdCardVerificationUtils.checkIdCardVerification(idCardVerificationResponse);
        // 校验身份证号是否存在
        var queryWrapper1 = this.lambdaQuery()
                .eq(FtbPersonnelsUchisuikePond::getIdCard, ftbRecommendationInvitationAppDTO.getIdCard())
                .eq(FtbPersonnelsUchisuikePond::getEnableMark, 0)
                .count();
        if (queryWrapper1 > 0) {
            throw new RuntimeException("此身份证号已存在于系统中，请勿重复添加");
        }
        if (ftbPersonnelsStaffRosterService.checkPhoneExistForRoster(ftbRecommendationInvitationAppDTO.getPhone())) {
            throw new RuntimeException("此手机号已存在于系统中，请勿重复添加");
        }
        FtbPersonnelsUchisuikePond ftbPersonnelsUchisuikePond = ftbRecommendationInvitationAppDTO.convertFtbPersonnelsUchisuikePond(ftbRecommendationInvitationAppDTO);
        // 来源0员工内推,1门店/组织内推
        if (ftbRecommendationInvitationAppDTO.getSource() == 1) {
            ActionResult<OrganizeGeneralDetailVO> organizeGeneralDetailVOActionResult = v2OrganizeApi.organizeInfoByIdNoToken(null, ftbPersonnelsUchisuikePond.getPushOrgId(), ftbRecommendationInvitationAppDTO.getTenantId());
            if (organizeGeneralDetailVOActionResult.getData() != null) {
                if (OrganizeCategoryEnums.STORE.equals(organizeGeneralDetailVOActionResult.getData().getOrganizeCategoryEnums())) {
                    ftbPersonnelsUchisuikePond.setSource(2L);
                } else {
                    ftbPersonnelsUchisuikePond.setSource(3L);
                }
            }
        } else {
            ftbPersonnelsUchisuikePond.setSource(1L);
        }
        this.baseMapper.insert(ftbPersonnelsUchisuikePond);
        // 简历附件
        SpringContext.getApplicationContext().publishEvent(new JnpfApplicationEvent<>(FileEventDTO.builder()
                .files(ftbRecommendationInvitationAppDTO.getFiles())
                .businessTypeID(ftbPersonnelsUchisuikePond.getId())
                .type(FileEventDTO.FileType.INTERNAL_RECOMMENDATION_POOL_RESUME)
                .build()));
    }

    @Override
    public void updateWorkStatus(String state, String phone) {
        if (StrUtil.isBlank(state) || StrUtil.isBlank(phone)) {
            return;
        }
        LambdaUpdateWrapper<FtbPersonnelsUchisuikePond> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(FtbPersonnelsUchisuikePond::getPhone, phone);
        updateWrapper.set(FtbPersonnelsUchisuikePond::getState, workingStatusCalculation(state));
        this.baseMapper.update(new FtbPersonnelsUchisuikePond(), updateWrapper);
    }

    @Override
    @Transactional
    public void referralPoolOrganizationChange(FtbRecommendationPoolOrgDTO ftbRecommendationPoolOrgDTO) {
        List<FtbPersonnelsUchisuikePondOrg> ftbPersonnelsUchisuikePondOrgs = ftbRecommendationPoolOrgDTO.getOrgIds()
                .stream()
                .map(a -> {
                    FtbPersonnelsUchisuikePondOrg ftbPersonnelsUchisuikePondOrg = new FtbPersonnelsUchisuikePondOrg();
                    ftbPersonnelsUchisuikePondOrg.setPushOrgId(a);
                    return ftbPersonnelsUchisuikePondOrg;
                }).collect(Collectors.toList());
        ftbPersonnelsUchisuikePondOrgMapper.delete(null);
        String sqlStatement = SqlHelper.getSqlStatement(FtbPersonnelsUchisuikePondOrgMapper.class, SqlMethod.INSERT_ONE);
        SqlHelper.executeBatch(FtbPersonnelsUchisuikePondOrg.class,
                this.log,
                ftbPersonnelsUchisuikePondOrgs,
                ftbPersonnelsUchisuikePondOrgs.size(),
                (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
    }

    @Override
    public List<String> internalReferralPoolOrganizationQuery() {
        return ftbPersonnelsUchisuikePondOrgMapper.selectList(null)
                .stream()
                .map(FtbPersonnelsUchisuikePondOrg::getPushOrgId)
                .collect(Collectors.toList());
    }

    private Long workingStatusCalculation(String state) {
        // 301、预入职  302、试用 303、正式  304、待离职  305 离职 306 试岗
        // 工作状态0未办理入职1预入职2已入职(试用)3已入职(正式)4已入职(待离职)5已入职(已离职)
        switch (state) {
            case "301":
            case "302":
                return 1L;
            case "306":
                return 2L;
            case "303":
                return 3L;
            case "304":
                return 4L;
            case "305":
                return 5L;
            default:
                return 0L;
        }
    }
}
