package jnpf.personnels.utils;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jnpf.attendance.AttendanceGroupApi;
import jnpf.authority.utils.PermissionsUtils;
import jnpf.base.ActionResult;
import jnpf.base.UserInfo;
import jnpf.entity.StoreEntity;
import jnpf.model.attendance.vo.AttendanceGroupVo;
import jnpf.model.personnels.po.FtbPersonnelsStaffEmploymentApply;
import jnpf.model.personnels.po.FtbPersonnelsStaffRoster;
import jnpf.permission.ContractTypeApi;
import jnpf.permission.RoleApi;
import jnpf.permission.V2UserApi;
import jnpf.permission.dto.v2.user.QueryUserBoundDTO;
import jnpf.permission.model.role.RoleInfoVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.permission.vo.v2.user.api.OrganizeAndPositionAndGradeVO;
import jnpf.permission.vo.v2.user.api.OrganizeAndStoreTeamVO;
import jnpf.permission.vo.v2.user.api.OrganizeAndUserVO;
import jnpf.personnels.mapper.FtbPersonnelsStaffEmploymentApplyMapper;
import jnpf.personnels.mapper.FtbPersonnelsStaffRosterMapper;
import jnpf.store.service.StoreService;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Component
@Slf4j
public class CacheExcelUtils {

    @Autowired
    private ContractTypeApi contractTypeApi;

    @Autowired
    private FtbPersonnelsStaffRosterMapper ftbPersonnelsStaffRosterMapper;

    @Autowired
    private FtbPersonnelsStaffEmploymentApplyMapper ftbPersonnelsStaffEmploymentApplyMapper;

    @Autowired
    private StoreService storeService;

    @Autowired
    private RoleApi roleApi;

    @Autowired
    private AttendanceGroupApi attendanceGroupApi;

    @Autowired
    private PermissionsUtils permissionsUtils;

    @Autowired
    private V2UserApi v2UserApi;

    private static final ThreadLocal<Map<String, String>> a = new ThreadLocal<>();

    private static final ThreadLocal<Map<String, FtbPersonnelsStaffRoster>> b = new ThreadLocal<>();

    private static final ThreadLocal<Map<QueryUserBoundDTO, OrganizeAndPositionAndGradeVO>> c = new ThreadLocal<>();

    private static final ThreadLocal<Map<String, String>> d = new ThreadLocal<>();

    private static final ThreadLocal<Map<String, StoreEntity>> e = new ThreadLocal<>();

    private static final ThreadLocal<Map<String, OrganizeAndUserVO>> g = new ThreadLocal<>();

    private static final ThreadLocal<Map<String, String>> h = new ThreadLocal<>();

    private static final ThreadLocal<Map<String, List<String>>> i = new ThreadLocal<>();

    private static final ThreadLocal<Map<String, OrganizeAndStoreTeamVO>> j = new ThreadLocal<>();

    public void init() {
        a.set(new HashMap<>());
        b.set(new HashMap<>());
        c.set(new HashMap<>());
        d.set(new HashMap<>());
        e.set(new HashMap<>());
        g.set(new HashMap<>());
        h.set(new HashMap<>());
        i.set(new HashMap<>());
        j.set(new HashMap<>());
    }

    public void clear() {
        a.remove();
        b.remove();
        c.remove();
        d.remove();
        e.remove();
        g.remove();
        h.remove();
        i.remove();
        j.remove();
    }

    public OrganizeAndUserVO checkOrgNameAndUserId(String attributeValue, String userId) {
        Map<String, OrganizeAndUserVO> cache = g.get();
        String key = attributeValue + "#" + userId;
        if (cache.containsKey(key)) {
            return cache.get(key);
        }
        OrganizeAndUserVO nameAndUserId = v2UserApi.checkOrganizeNameBoundUserName(attributeValue, userId, UserProvider.getUser().getTenantId());
        cache.put(key, nameAndUserId);
        return nameAndUserId;
    }

    /**
     * 获取已存在员工绑定的组织信息
     *
     * @param phone
     * @return {@link UserBoundVO }
     */
    public UserBoundVO doCheckPhoneExist(String phone) {
        QueryWrapper<FtbPersonnelsStaffRoster> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(FtbPersonnelsStaffRoster::getPhone, phone)
                .eq(FtbPersonnelsStaffRoster::getEnabledMark, 0)
                .last("limit 1");
        FtbPersonnelsStaffRoster ftbPersonnelsStaffRoster = ftbPersonnelsStaffRosterMapper.selectOne(wrapper);
        if (Objects.nonNull(ftbPersonnelsStaffRoster)) {
            ActionResult<List<UserBoundVO>> userPrimaryBoundBatch = v2UserApi.getUserPrimaryBoundBatch(List.of(ftbPersonnelsStaffRoster.getUserId()), null);
            if (userPrimaryBoundBatch != null && CollUtil.isNotEmpty(userPrimaryBoundBatch.getData())) {
                return userPrimaryBoundBatch.getData().get(0);
            }
        }
        return null;
    }

    public FtbPersonnelsStaffRoster doCheckPhoneStaffRosterExist(String phone) {
        QueryWrapper<FtbPersonnelsStaffRoster> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(FtbPersonnelsStaffRoster::getPhone, phone)
                .eq(FtbPersonnelsStaffRoster::getEnabledMark, 0)
                .last("limit 1");
        FtbPersonnelsStaffRoster ftbPersonnelsStaffRoster = ftbPersonnelsStaffRosterMapper.selectOne(wrapper);
        if (Objects.nonNull(ftbPersonnelsStaffRoster)) {
            return ftbPersonnelsStaffRoster;
        }
        return null;
    }

    /**
    * 校验是否在入职管理存在
    */
    public Boolean checkInOnboardingManagement(String phone) {
        QueryWrapper<FtbPersonnelsStaffEmploymentApply> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(FtbPersonnelsStaffEmploymentApply::getPhone, phone)
                .eq(FtbPersonnelsStaffEmploymentApply::getEnabledMark, 0)
                .last("limit 1");
        Long ftbPersonnelsStaffEmploymentApply = ftbPersonnelsStaffEmploymentApplyMapper.selectCount(wrapper);
        if (ftbPersonnelsStaffEmploymentApply > 0) {
            return true;
        }
        return false;
    }

    /**
     * 根据用户Id获取用户信息
     */
    public UserBoundVO doQueryDirectlyUnderTheSupervisor(String userId) {
        ActionResult<List<UserBoundVO>> userPrimaryBoundBatch = v2UserApi.getUserPrimaryBoundBatch(List.of(userId), null);
        if (userPrimaryBoundBatch != null && CollUtil.isNotEmpty(userPrimaryBoundBatch.getData())) {
            return userPrimaryBoundBatch.getData().get(0);
        }
        return null;
    }

    public StoreEntity doStoreEntity(String storename) {
        Map<String, StoreEntity> cache = e.get();
        if (cache.containsKey(storename)) {
            return cache.get(storename);
        }
        LambdaQueryWrapper<StoreEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(StoreEntity::getId);
        queryWrapper.eq(StoreEntity::getStorename, storename);
        queryWrapper.last("limit 1");
        StoreEntity storeEntity = storeService.getOne(queryWrapper);
        cache.put(storename, storeEntity);
        return storeEntity;
    }

    /**
     * 角色校验
     */
    public String doCheckRoleInfoVO(String orgName, String roleName) {
        Map<String, String> cache = d.get();
        String key = orgName + "##" + roleName;
        if (cache.containsKey(key)) {
            return cache.get(key);
        }
        String roleIds = "";
        //查询全局角色
        RoleInfoVO roleInfoByGlobalRoleName = roleApi.getRoleInfoByGlobalRoleName(roleName);
        if (null != roleInfoByGlobalRoleName) {
            roleIds = roleInfoByGlobalRoleName.getId();
        }
        //查询和组织相关的角色
        RoleInfoVO roleInfoByRoleName = roleApi.getRoleInfoByRoleNameAndOrgName(roleName, orgName);
        if (null != roleInfoByRoleName) {
            if (StringUtils.isNotEmpty(roleIds)) {
                roleIds = roleIds + "," + roleInfoByRoleName.getId();
            } else {
                roleIds = roleInfoByRoleName.getId();
            }
        }
        cache.put(key, roleIds);
        return roleIds;
    }

    /**
     * 考勤组校验
     */
    public String doCheckAttendanceGroup(String orgName, String attendanceName) {
        Map<String, String> cache = h.get();
        String key = orgName + "##" + attendanceName;
        if (cache.containsKey(key)) {
            return cache.get(key);
        }
        String attendanceId = "";
        // 查询和组织相关的考勤组
        ActionResult<AttendanceGroupVo> attendanceGroupByName = attendanceGroupApi.getAttendanceGroupByName(orgName, attendanceName);
        if (attendanceGroupByName.getCode() == 200 && Objects.nonNull(attendanceGroupByName.getData())) {
            attendanceId = attendanceGroupByName.getData().getId();
        }
        cache.put(key, attendanceId);
        return attendanceId;
    }

    /**
     * 所属组织-岗位-职等校验
     */
    public OrganizeAndPositionAndGradeVO doCheckOrgPositionGradesBoundDTO(QueryUserBoundDTO dto) {
        Map<QueryUserBoundDTO, OrganizeAndPositionAndGradeVO> cache = c.get();
        if (cache.containsKey(dto)) {
            return cache.get(dto);
        }
        OrganizeAndPositionAndGradeVO result = v2UserApi.checkOrganizeNameBoundPositionNameGradeName(dto.getOrganizeName(),
                dto.getPositionName(),
                dto.getGradeName(),
                UserProvider.getUser().getTenantId());
        cache.put(dto, result);
        return result;
    }

    /**
     * 直属主管校验
     *
     * @param systemWokerId
     * @return
     */
    public FtbPersonnelsStaffRoster doVerificationByDirectSupervisor(String systemWokerId) {
        Map<String, FtbPersonnelsStaffRoster> cache = b.get();
        if (cache.containsKey(systemWokerId)) {
            return cache.get(systemWokerId);
        }
        LambdaQueryWrapper<FtbPersonnelsStaffRoster> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.select(FtbPersonnelsStaffRoster::getUserId, FtbPersonnelsStaffRoster::getPhone, FtbPersonnelsStaffRoster::getWorkerStatus);
        lambdaQueryWrapper.eq(FtbPersonnelsStaffRoster::getSystemWokerId, systemWokerId);
        lambdaQueryWrapper.eq(FtbPersonnelsStaffRoster::getEnabledMark, 0);
        lambdaQueryWrapper.last("limit 1");
        FtbPersonnelsStaffRoster ftbPersonnelsStaffRoster = ftbPersonnelsStaffRosterMapper.selectOne(lambdaQueryWrapper);
        cache.put(systemWokerId, ftbPersonnelsStaffRoster);
        return ftbPersonnelsStaffRoster;

    }

    /**
     * 合同校验
     *
     * @param contractName
     * @return
     */
    public String doContractTypeName(String contractName) {
        Map<String, String> cache = a.get();
        if (cache.containsKey(contractName)) {
            return cache.get(contractName);
        }
        String contractTypeName = contractTypeApi.checkContractTypeName(contractName);
        cache.put(contractName, contractTypeName);
        return contractTypeName;
    }

    /**
     * 用户组织权限校验
     *
     * @return
     */
    public List<String> doPersonnelOrganizationIdDataPermissions() {
        UserInfo userInfo = UserProvider.getUser();
        Map<String, List<String>> cache = i.get();
        if (cache.containsKey(userInfo.getUserId())) {
            return cache.get(userInfo.getUserId());
        }
        if (userInfo.getIsAdministrator()) {
            cache.put(userInfo.getUserId(), null);
            return null;
        }
        List<String> results = permissionsUtils.obtainPersonnelOrganizationIdDataPermissions(userInfo.getUserId());
        cache.put(userInfo.getUserId(), results);
        return results;
    }

    /**
     * 组织班组校验
     *
     * @return
     */
    public OrganizeAndStoreTeamVO doOrganizeTeamVerification(String orgName, String teamName) {
        Map<String, OrganizeAndStoreTeamVO> cache = j.get();
        String key = orgName + "##" + teamName;
        if (cache.containsKey(key)) {
            return cache.get(key);
        }
        OrganizeAndStoreTeamVO organizeAndStoreTeamVO = v2UserApi.checkOrganizeNameBoundStoreTeamName(orgName, teamName, UserProvider.getUser().getTenantId());
        cache.put(key, organizeAndStoreTeamVO);
        return organizeAndStoreTeamVO;
    }

}
