package com.yida.data.common.service;

import static com.yida.data.common.core.entity.constant.CachePrefixConstant.STAFF_DATA;

import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.net.URLEncoder;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.yida.data.common.core.entity.CurrentUser;
import com.yida.data.common.core.entity.Dict;
import com.yida.data.common.core.entity.constant.AppConstant;
import com.yida.data.common.core.entity.constant.CachePrefixConstant;
import com.yida.data.common.core.entity.constant.QywxServiceProviderConstant;
import com.yida.data.common.core.entity.constant.UPayConstant;
import com.yida.data.common.core.entity.consume.DeptConsumeTerminalCache;
import com.yida.data.common.core.entity.consume.EduConsumeConfig;
import com.yida.data.common.core.entity.school.EduDeptHomeApp;
import com.yida.data.common.core.entity.school.EduYidaAppAccount;
import com.yida.data.common.core.entity.system.BaiduApiConfig;
import com.yida.data.common.core.entity.system.ConstructionPayConfig;
import com.yida.data.common.core.entity.system.Dept;
import com.yida.data.common.core.entity.system.EduApp;
import com.yida.data.common.core.entity.system.EduAppTemplate;
import com.yida.data.common.core.entity.system.EduArea;
import com.yida.data.common.core.entity.system.EduDeptFunction;
import com.yida.data.common.core.entity.system.EduDeptPayType;
import com.yida.data.common.core.entity.system.EduDeptWxPublic;
import com.yida.data.common.core.entity.system.EduHoliday;
import com.yida.data.common.core.entity.system.EduPayWxConfig;
import com.yida.data.common.core.entity.system.EduQywxServiceProvider;
import com.yida.data.common.core.entity.system.EduQywxServiceProviderSchool;
import com.yida.data.common.core.entity.system.EduYidaApp;
import com.yida.data.common.core.entity.system.UPayConfig;
import com.yida.data.common.core.entity.system.UnionPayConfig;
import com.yida.data.common.core.entity.system.WhiteList;
import com.yida.data.common.core.entity.system.enums.RoleEnum;
import com.yida.data.common.core.entity.system.enums.SysFunctionEnum;
import com.yida.data.common.core.entity.user.EduStaff;
import com.yida.data.common.core.entity.user.EduStudent;
import com.yida.data.common.core.entity.user.EduUserDept;
import com.yida.data.common.core.entity.user.enums.UserDeptTypeEnum;
import com.yida.data.common.core.enums.BaiDuModuleEnum;
import com.yida.data.common.core.enums.school.DeptAppTypeEnum;
import com.yida.data.common.core.utils.FebsUtil;
import com.yida.data.common.core.utils.NumberUtil;
import com.yida.data.common.core.utils.RedisUtil;
import com.yida.data.common.core.utils.UPayUtil;
import com.yida.data.common.core.utils.WxServiceProviderUtil;
import com.yida.data.common.core.utils.WxUtil;
import com.yida.data.school.feign.index.RemoteDeptHomeIndexService;
import com.yida.data.system.feign.RemoteAppService;
import com.yida.data.system.feign.RemoteBaiDuApiConfigService;
import com.yida.data.system.feign.RemoteCommonService;
import com.yida.data.system.feign.RemoteConstructionPayConfigService;
import com.yida.data.system.feign.RemoteConsumeConfigService;
import com.yida.data.system.feign.RemoteDeptFunctionService;
import com.yida.data.system.feign.RemoteDeptService;
import com.yida.data.system.feign.RemoteDictService;
import com.yida.data.system.feign.RemoteHolidayService;
import com.yida.data.system.feign.RemotePayTypeService;
import com.yida.data.system.feign.RemotePayWxConfigService;
import com.yida.data.system.feign.RemoteQywxService;
import com.yida.data.system.feign.RemoteUPayConfigService;
import com.yida.data.system.feign.RemoteUnionPayConfigService;
import com.yida.data.system.feign.RemoteWhiteListService;
import com.yida.data.system.feign.RemoteYidaAppAccountService;
import com.yida.data.system.feign.RemoteYidaAppService;
import com.yida.data.user.feign.RemoteStaffService;
import com.yida.data.user.feign.RemoteStudentService;
import com.yida.data.user.feign.RemoteUserDeptService;
import com.yida.data.user.vo.TeacherDeptVO;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@RequiredArgsConstructor
public class CommonService {

    private final RemoteAppService remoteAppService;
    private final RemoteQywxService remoteQywxService;
    private final RemoteDeptService remoteDeptService;
    private final RemoteDictService remoteDictService;
    private final RemoteCommonService remoteCommonService;
    private final RemoteYidaAppService remoteYidaAppService;
    private final RemoteHolidayService remoteHolidayService;
    private final RemotePayTypeService remotePayTypeService;
    private final RemoteUserDeptService remoteUserDeptService;
    private final RemoteWhiteListService remoteWhiteListService;
    private final RemoteUPayConfigService remoteUPayConfigService;
    private final RemotePayWxConfigService remotePayWxConfigService;
    private final RemoteDeptFunctionService remoteDeptFunctionService;
    private final RemoteConsumeConfigService remoteConsumeConfigService;
    private final RemoteUnionPayConfigService remoteUnionPayConfigService;
    private final RemoteYidaAppAccountService remoteYidaAppAccountService;
    private final RemoteBaiDuApiConfigService remoteBaiDuApiConfigService;
    private final RemoteConstructionPayConfigService remoteConstructionPayConfigService;
    private final RemoteStaffService remoteStaffService;
    private final RemoteStudentService remoteStudentService;
    private final RemoteDeptHomeIndexService remoteDeptHomeIndexService;


    private final WxUtil wxUtil;
    private final WxServiceProviderUtil wxServiceProviderUtil;

    private final RedisService redisService;

    public List<Dict> selectDict(String type) {
        if (ObjectUtil.isNull(type)) {
            return null;
        }
        return remoteDictService.selectDict(type).getData();
    }

    public Dict getDictByTypeAndValueOrLabel(String type, String value, String label) {
        if (ObjectUtil.isNull(type)) {
            return null;
        }
        return remoteDictService.getDictByTypeAndValueOrLabel(type, value, label).getData();
    }

    public Dept getDept(Long deptId) {
        if (deptId == null) {
            return null;
        }
        //查询学校信息
        Dept dept = (Dept) redisService.hget(CachePrefixConstant.SYS_DEPT_DATA, deptId.toString());
        if (dept == null) {
            dept = remoteDeptService.getInfoByIdNoPermission(deptId).getData();
            redisService.hset(CachePrefixConstant.SYS_DEPT_DATA, deptId.toString(), dept);
        }
        return dept;
    }

    /**
     * 查询家校部门信息
     *
     * @param deptId 家校部门id
     * @return com.yida.data.common.core.entity.user.EduUserDept
     * @author ZYJ
     * @date 2021/11/24 15:11
     */
    public EduUserDept getUserDept(Long deptId) {
        // 查询家校部门信息
        EduUserDept dept = (EduUserDept) redisService.hget(CachePrefixConstant.USER_DEPT_DATA, deptId.toString());
        if (dept == null) {
            dept = this.remoteUserDeptService.getByDeptId(deptId).getData();
            redisService.hset(CachePrefixConstant.USER_DEPT_DATA, deptId.toString(), dept);
        }
        return dept;
    }

    public Dept getSchoolByCorpId(String corpId) {
        Long deptId = redisService.hHasKey(CachePrefixConstant.SYS_SCHOOL_CORPID_ID, corpId)
            ? Long.valueOf(redisService.hget(CachePrefixConstant.SYS_SCHOOL_CORPID_ID, corpId).toString())
            : null;
        Dept school;
        if (deptId == null) {
            Dept dept = remoteDeptService.getSchoolByCorp(corpId).getData();
            school = dept;
            if (school != null) {
                redisService.hset(CachePrefixConstant.SYS_SCHOOL_CORPID_ID, corpId, dept.getDeptId());
            }
        } else {
            school = getDept(deptId);
        }
        return school;
    }

    /**
     * 根据微信公众号id获取部门
     */
    public Dept getSchoolByAppId(String appId) {
        Long deptId = redisService.hHasKey(CachePrefixConstant.SYS_SCHOOL_APPID_ID, appId)
            ? Long.valueOf(redisService.hget(CachePrefixConstant.SYS_SCHOOL_APPID_ID, appId).toString())
            : null;
        Dept school;
        if (deptId == null) {
            Dept dept = remoteDeptService.getSchoolByAppId(appId).getData();
            school = dept;
            if (school != null) {
                redisService.hset(CachePrefixConstant.SYS_SCHOOL_APPID_ID, appId, dept.getDeptId());
            }
        } else {
            school = getDept(deptId);
        }
        return school;
    }

    /**
     * 查询系统app信息
     *
     * @param code     应用代码
     * @param corpId   微信corpId
     * @param schoolId 学校id
     */
    public EduApp getAppByCodeAndSchool(String code, String corpId, Long schoolId) {
        if (schoolId == null && StrUtil.isNotBlank(corpId)) {
            Dept school = remoteDeptService.getSchoolByCorp(corpId).getData();
            schoolId = school.getDeptId();
        }
        EduApp app = redisService.hasKey(CachePrefixConstant.SYS_APP + schoolId)
            ? (EduApp) redisService.hget(CachePrefixConstant.SYS_APP + schoolId, code)
            : null;
        if (app == null) {
            app = remoteAppService.getAppBySchoolOrCorpIdAndCode(schoolId, null, code).getData();
            redisService.hset(CachePrefixConstant.SYS_APP + schoolId, code, app);
        }
        return app;
    }

    /**
     * 查询易达app
     */
    public EduYidaApp getYidaApp(Long schoolId) {
        Long yidaAppId = NumberUtil.object2Long(redisService.hget(CachePrefixConstant.SYS_SCHOOL_YIDA_APP,
            schoolId.toString()));
        EduYidaApp yidaApp = null;
        if (yidaAppId != null) {
            yidaApp = (EduYidaApp) redisService.hget(CachePrefixConstant.SYS_YIDA_APP, yidaAppId.toString());
        }
        if (yidaApp == null) {
            yidaApp = remoteYidaAppService.getAppBySchoolNoPermission(schoolId).getData();
            if (yidaApp != null) {
                redisService.hset(CachePrefixConstant.SYS_SCHOOL_YIDA_APP, schoolId.toString(), yidaApp.getId());
                redisService.hset(CachePrefixConstant.SYS_YIDA_APP, yidaApp.getId().toString(), yidaApp);
            }
        }
        return yidaApp;
    }

    /**
     * 查询易达订阅号
     *
     * @param type 0-家长，1-老师
     */
    public EduYidaAppAccount getYidaAppAccount(Long schoolId, Integer type) {
        EduYidaAppAccount account = (EduYidaAppAccount) redisService
            .hget(CachePrefixConstant.SYS_YIDA_APP_ACCOUNT + schoolId.toString(),
                type.toString());
        if (account == null) {
            account = remoteYidaAppAccountService.getAccountByTypeNoPermission(schoolId, type).getData();
            if (account != null) {
                redisService.hset(CachePrefixConstant.SYS_YIDA_APP_ACCOUNT + schoolId,
                    type.toString(), account);
            }
        }
        return account;
    }

    /**
     * 判断当前学校下是否有当前家校部门
     *
     * @param deptName 部门名称
     * @param deptType 部门类型 {@link UserDeptTypeEnum}
     * @param schoolId 学校id
     * @param str      某次导入的唯一标识
     * @param parentId 父级部门id
     * @return com.yida.data.common.core.entity.system.Dept
     * @author ZYJ
     * @date 2021/8/23 19:49
     */
    public EduUserDept getUserDeptBySchoolIdAndNameAndType(String deptName, Integer deptType, Long schoolId,
        String str, Long parentId) {
        // 查询部门信息
        return (EduUserDept) redisService.hget(RedisUtil.getDeptKey(str),
            RedisUtil.getDeptRedisKey(deptName, deptType, schoolId, parentId));
    }

    /**
     * 根据学校查询微信支付配置
     */
    public EduPayWxConfig getPayWxConfigBySchool(Long schoolId) {
        EduPayWxConfig config = redisService.hasKey(CachePrefixConstant.PAY_WX_CONFIG)
            ? (EduPayWxConfig) redisService.hget(CachePrefixConstant.PAY_WX_CONFIG, schoolId.toString())
            : null;
        if (config == null) {
            config = remotePayWxConfigService.getPayWxConfigBySchool(schoolId).getData();
            redisService.hset(CachePrefixConstant.PAY_WX_CONFIG, schoolId.toString(), config);
        }
        return config;
    }

    /**
     * 查询当天是否是工作日
     */
    public Boolean isWorkDay(LocalDate target) {
        List<Object> objects = redisService.lGet(CachePrefixConstant.HOLIDAY, 0L, -1L);
        if (CollUtil.isEmpty(objects)) {
            List<EduHoliday> data = remoteHolidayService.listAllHoliday().getData();
            if (CollUtil.isNotEmpty(data)) {
                redisService.llSet(CachePrefixConstant.HOLIDAY, data);
                for (EduHoliday holiday : data) {
                    // 节假日
                    if (target.equals(holiday.getDate())) {
                        return false;
                    }
                }
            }
        } else {
            for (Object o : objects) {
                // 节假日
                EduHoliday holiday = (EduHoliday) o;
                if (target.equals(holiday.getDate())) {
                    return false;
                }
            }
        }
        return true;
    }


    /**
     * 时间段内 节假日集合
     */
    public List<LocalDate> inHolidayDateList(LocalDate startDate, LocalDate endDate) {
        List<LocalDate> inHolidayList = new ArrayList<>();
        List<Object> objects = redisService.lGet(CachePrefixConstant.HOLIDAY, 0L, -1L);
        if (CollUtil.isEmpty(objects)) {
            List<EduHoliday> data = remoteHolidayService.listAllHoliday().getData();
            if (CollUtil.isNotEmpty(data)) {
                redisService.llSet(CachePrefixConstant.HOLIDAY, data);
                for (EduHoliday holiday : data) {
                    // 节假日
                    LocalDate date = holiday.getDate();
                    if ((date.isAfter(startDate) && date.isBefore(endDate)) || date.equals(startDate) || date.equals(endDate)) {
                        inHolidayList.add(date);
                    }
                }
            }
        } else {
            for (Object o : objects) {
                // 节假日
                EduHoliday holiday = (EduHoliday) o;
                LocalDate date = holiday.getDate();
                if ((date.isAfter(startDate) && date.isBefore(endDate)) || date.equals(startDate) || date.equals(endDate)) {
                    inHolidayList.add(date);
                }
            }
        }
        return inHolidayList;
    }

    /**
     * 查询当天的上一个工作日
     */
    public LocalDate findLastWorkDay(LocalDate target) {
        LocalDate yesterday = target.minusDays(1L);
        return isWorkDay(yesterday) ? yesterday : findLastWorkDay(yesterday);
    }

    /**
     * 获取系统微信公众号
     */
    public EduDeptWxPublic getWxPublic(Long deptId) {
        EduDeptWxPublic sysWxPublic = (EduDeptWxPublic) redisService
            .hget(CachePrefixConstant.SYS_DEPT_WX_PUBLIC, deptId.toString());
        if (sysWxPublic == null) {
            sysWxPublic = remoteCommonService.getDeptWxPublic(deptId).getData();
            if (sysWxPublic != null) {
                redisService.hset(CachePrefixConstant.SYS_DEPT_WX_PUBLIC, deptId.toString(), sysWxPublic);
            }
        }
        return sysWxPublic;
    }

    /**
     * 查询区域信息
     *
     * @param id
     * @return
     */
    public EduArea getArea(Long id) {
        EduArea area = (EduArea) redisService.get(CachePrefixConstant.AREA_DATA + id);
        if (area == null) {
            area = remoteCommonService.getArea(id).getData();
            redisService.set(CachePrefixConstant.AREA_DATA + id, area, 3600L);
        }
        return area;
    }

    /**
     * 根据部门id获取部门支付方式
     *
     * @param deptId 部门id
     * @return com.yida.data.common.core.entity.system.EduDeptPayType
     * @author ZYJ
     * @date 2022/6/22 14:05
     */
    public EduDeptPayType getDeptPayWay(Long deptId) {
        EduDeptPayType payType = redisService.hasKey(CachePrefixConstant.PAY_WAY_CONFIG)
            ? (EduDeptPayType) redisService.hget(CachePrefixConstant.PAY_WAY_CONFIG, deptId.toString())
            : null;
        if (Objects.isNull(payType)) {
            payType = remotePayTypeService.getPayTypeByDeptId(deptId).getData();
            if (Objects.nonNull(payType)) {
                redisService.hset(CachePrefixConstant.PAY_WAY_CONFIG, deptId.toString(), payType);
            }
        }
        return payType;
    }

    /**
     * 根据部门查询银联云闪付支付配置
     *
     * @param deptId 部门id
     * @return com.yida.data.common.core.entity.system.UnionPayConfig
     * @author ZYJ
     * @date 2022/6/23 16:45
     */
    public UnionPayConfig getUnionPayConfigByDept(Long deptId) {
        UnionPayConfig config = redisService.hasKey(CachePrefixConstant.UNION_PAY_CONFIG)
            ? (UnionPayConfig) redisService.hget(CachePrefixConstant.UNION_PAY_CONFIG, deptId.toString())
            : null;
        if (config == null) {
            config = remoteUnionPayConfigService.getUnionPayConfigByDept(deptId).getData();
            redisService.hset(CachePrefixConstant.UNION_PAY_CONFIG, deptId.toString(), config);
        }
        return config;
    }

    /**
     * 根据部门查询建行支付配置
     *
     * @param deptId 部门id
     * @return com.yida.data.common.core.entity.system.ConstructionPayConfig
     * @author ZYJ
     * @date 2023/6/19 16:50
     */
    public ConstructionPayConfig getConstructionPayConfigByDept(Long deptId) {
        ConstructionPayConfig config = redisService.hasKey(CachePrefixConstant.CONSTRUCTION_PAY_CONFIG)
            ? (ConstructionPayConfig) redisService.hget(CachePrefixConstant.CONSTRUCTION_PAY_CONFIG, deptId.toString())
            : null;
        if (config == null) {
            config = remoteConstructionPayConfigService.getConstructionPayConfigByDept(deptId).getData();
            redisService.hset(CachePrefixConstant.CONSTRUCTION_PAY_CONFIG, deptId.toString(), config);
        }
        return config;
    }

    /**
     * 根据部门查询收钱吧支付配置
     *
     * @param deptId 部门id
     * @return com.yida.data.common.core.entity.system.UPayConfig
     * @author ZYJ
     * @date 2023/3/21 10:42
     */
    public UPayConfig getUPayConfigByDept(Long deptId) {
        UPayConfig config = redisService.hasKey(CachePrefixConstant.U_PAY_CONFIG)
            ? (UPayConfig) redisService.hget(CachePrefixConstant.U_PAY_CONFIG, deptId.toString())
            : null;
        if (config == null) {
            config = remoteUPayConfigService.getUPayConfigByDept(deptId).getData();
            redisService.hset(CachePrefixConstant.U_PAY_CONFIG, deptId.toString(), config);
        }
        return config;
    }

    /**
     * 获取学校消费机服务器信息
     *
     * @param deptId 部门id
     * @return com.yida.data.common.core.entity.consume.EduConsumeConfig
     * @author ZYJ
     * @date 2023/4/6 17:46
     */
    public EduConsumeConfig getConsumeConfigByDept(Long deptId) {
        EduConsumeConfig config = redisService.hasKey(CachePrefixConstant.CONSUME_CONFIG)
            ? (EduConsumeConfig) redisService.hget(CachePrefixConstant.CONSUME_CONFIG, deptId.toString())
            : null;
        if (config == null) {
            config = remoteConsumeConfigService.getConsumeConfigByDept(deptId).getData();
            redisService.hset(CachePrefixConstant.CONSUME_CONFIG, deptId.toString(), config);
        }
        return config;
    }

    /**
     * 获取学校收钱吧终端信息
     *
     * @param deptId 学校id
     * @return com.yida.data.common.core.entity.consume.DeptConsumeTerminalCache
     * @author ZYJ
     * @date 2023/4/3 14:47
     */
    public DeptConsumeTerminalCache getDeptConsumeTerminal(Long deptId) {
        DeptConsumeTerminalCache cache = redisService.hasKey(CachePrefixConstant.DEPT_CONSUME_TERMINAL + deptId.toString())
            ? (DeptConsumeTerminalCache) redisService.get(CachePrefixConstant.DEPT_CONSUME_TERMINAL + deptId.toString())
            : null;
        if (cache == null) {
            cache = UPayUtil.active(getUPayConfigByDept(deptId), UPayConstant.ACTIVE_DEVICE_NAME);
            cache.setDeptId(deptId);
            redisService.set(CachePrefixConstant.DEPT_CONSUME_TERMINAL + deptId.toString(), cache);
        }
        return cache;
    }

    /**
     * 向下查询指定家校部门类型的家校部门id(可查询非直接子家校部门) 未毕业家校部门
     *
     * @param deptId 部门id
     * @param type   家校部门类型 {@link UserDeptTypeEnum}
     * @return java.util.List<com.yida.data.common.core.entity.user.EduUserDept>
     * @author ZYJ
     * @date 2022/7/11 16:10
     */
    public List<EduUserDept> findChildIdByParentAndType(Long deptId, Integer type) {
//        List<Object> listCache = redisService.lGet(CachePrefixConstant.USER_DEPT_TYPE_DATA + StringConstant.DASH +
//                deptId + StringConstant.DASH + type, 0L, -1L);
//        List<EduUserDept> list = listCache.stream().map(EduUserDept.class::cast).collect(Collectors.toList());
//
//        if (CollUtil.isEmpty(list)) {
//            list = remoteUserDeptService.findChildIdByParentAndTypeNoPermission(deptId, type).getData();
//            if (CollUtil.isNotEmpty(list)) {
//                redisService.lSet(CachePrefixConstant.USER_DEPT_TYPE_DATA + StringConstant.DASH +
//                        deptId + StringConstant.DASH + type, list);
//            }
//        }
//        return list;
        return remoteUserDeptService.findChildIdByParentAndTypeNoPermission(deptId, type).getData();
    }

    /**
     * 获取服务商信息
     *
     * @param serviceCorpId 服务商企业微信corpId
     * @return com.yida.data.common.core.entity.system.EduQywxServiceProvider
     * @author ZYJ
     * @date 2022/12/1 10:46
     */
    public EduQywxServiceProvider getServiceProvider(String serviceCorpId) {
        EduQywxServiceProvider serviceProvider = redisService.hasKey(CachePrefixConstant.SYS_SERVICE_PROVIDER)
            ? (EduQywxServiceProvider) redisService.hget(CachePrefixConstant.SYS_SERVICE_PROVIDER, serviceCorpId)
            : null;
        if (Objects.isNull(serviceProvider)) {
            serviceProvider = remoteAppService.getServiceProviderByServiceCorpId(serviceCorpId).getData();
            if (Objects.nonNull(serviceProvider)) {
                redisService.hset(CachePrefixConstant.SYS_SERVICE_PROVIDER, serviceCorpId, serviceProvider);
            }
        }
        return serviceProvider;
    }

    /**
     * 获取对应服务商模板信息
     *
     * @param templateId    模板id
     * @param serviceCorpId 服务商corpId
     * @return com.yida.data.common.core.entity.system.EduAppTemplate
     * @author ZYJ
     * @date 2022/12/1 9:27
     */
    public EduAppTemplate getAppTemplateByTemplateId(String templateId, String serviceCorpId) {
        EduAppTemplate eduAppTemplate = redisService.hasKey(CachePrefixConstant.SYS_APP_TEMPLATE)
            ? (EduAppTemplate) redisService.hget(CachePrefixConstant.SYS_APP_TEMPLATE, serviceCorpId + "." + templateId)
            : null;
        if (Objects.isNull(eduAppTemplate)) {
            eduAppTemplate = remoteAppService.getAppTemplateByTemplateId(templateId, serviceCorpId).getData();
            if (Objects.nonNull(eduAppTemplate)) {
                redisService.hset(CachePrefixConstant.SYS_APP_TEMPLATE, serviceCorpId + "." + templateId, eduAppTemplate);
            }
        }
        return eduAppTemplate;
    }

    /**
     * 根据学校对应的通讯录应用类型获取不同的access_token 创建、编辑、删除、获取部门ID列表、获取成员ID列表时使用
     *
     * @param schoolId 学校id
     * @return java.lang.String
     * @author ZYJ
     * @date 2022/12/1 9:46
     */
    public String getAddressListToken(Long schoolId) {
        String accessToken;
        // 获取学校通讯录应用
        EduApp app = getAppByCodeAndSchool(AppConstant.CONTACT, null, schoolId);

        if (Objects.isNull(app.getTemplateId())) {
            // 自建应用
            accessToken = wxUtil.getAccessToken(app.getWxCorpId(), app.getWxSecret());
        } else {
            // 服务商代开发应用
            // 获取对应模板信息
            EduAppTemplate appTemplate = getAppTemplateByTemplateId(app.getTemplateId(), app.getServiceCorpId());
            // 获取第三方应用凭证
            String suiteAccessToken = wxServiceProviderUtil.getSuiteAccessToken(appTemplate.getTemplateId(),
                appTemplate.getTemplateSecret(),
                String.valueOf(redisService.get(QywxServiceProviderConstant.SERVICE_SUITE_TICKET + appTemplate.getTemplateId())));
            // 获取企业微信信息缓存
//            EduQywxServiceProviderSchool providerSchool = (EduQywxServiceProviderSchool) redisService
//                    .hget(QywxServiceProviderConstant.PROVIDER_SCHOOL_CORP_ORIGINAL_DATA,
//                            app.getServiceCorpId() + "." + app.getWxCorpId());
            EduQywxServiceProviderSchool providerSchool = getCorpByOriginalData(app.getServiceCorpId(), app.getWxCorpId());
            accessToken = wxServiceProviderUtil
                .getCorpToken(providerSchool.getDeptEncryptionCorpId(), app.getWxSecret(), suiteAccessToken);
        }
        return accessToken;
    }

    /**
     * 服务商对应学校加密corpId数据(原始值为key)
     *
     * @param providerCorpId     服务商corpId
     * @param deptOriginalCorpId 部门原始corpId
     * @return com.yida.data.common.core.common.ResultBean<com.yida.data.common.core.entity.system.EduQywxServiceProviderSchool>
     * @author ZYJ
     * @date 2023/9/25 17:48
     */
    public EduQywxServiceProviderSchool getCorpByOriginalData(String providerCorpId, String deptOriginalCorpId) {
        EduQywxServiceProviderSchool providerSchool =
            redisService.hasKey(QywxServiceProviderConstant.PROVIDER_SCHOOL_CORP_ORIGINAL_DATA)
                ? (EduQywxServiceProviderSchool) redisService.hget(QywxServiceProviderConstant.PROVIDER_SCHOOL_CORP_ORIGINAL_DATA,
                providerCorpId + "." + deptOriginalCorpId)
                : null;
        if (providerSchool == null) {
            providerSchool = remoteQywxService.getCorpByOriginalData(providerCorpId, deptOriginalCorpId).getData();
            redisService
                .hset(QywxServiceProviderConstant.PROVIDER_SCHOOL_CORP_ORIGINAL_DATA, providerCorpId + "." + deptOriginalCorpId,
                    providerSchool);
        }
        return providerSchool;
    }

    /**
     * 服务商对应学校加密corpId数据(加密值为key)
     *
     * @param providerCorpId       服务商corpId
     * @param deptEncryptionCorpId 部门加密corpId
     * @return com.yida.data.common.core.common.ResultBean<com.yida.data.common.core.entity.system.EduQywxServiceProviderSchool>
     * @author ZYJ
     * @date 2023/9/25 17:48
     */
    public EduQywxServiceProviderSchool getCorpByEncryptionData(String providerCorpId, String deptEncryptionCorpId) {
        EduQywxServiceProviderSchool providerSchool = redisService.hasKey(QywxServiceProviderConstant.PROVIDER_SCHOOL_CORP_DATA)
            ? (EduQywxServiceProviderSchool) redisService.hget(QywxServiceProviderConstant.PROVIDER_SCHOOL_CORP_DATA,
            providerCorpId + "." + deptEncryptionCorpId)
            : null;
        if (providerSchool == null) {
            providerSchool = remoteQywxService.getCorpByEncryptionData(providerCorpId, deptEncryptionCorpId).getData();
            redisService.hset(QywxServiceProviderConstant.PROVIDER_SCHOOL_CORP_DATA, providerCorpId + "." + deptEncryptionCorpId,
                providerSchool);
        }
        return providerSchool;
    }

    /**
     * 获取企业凭证
     *
     * @param app 通讯录应用信息
     * @return java.lang.String
     * @author ZYJ
     * @date 2022/12/1 11:24
     */
    public String getCorpToken(EduApp app) {
        // 获取对应模板信息
        EduAppTemplate appTemplate = getAppTemplateByTemplateId(app.getTemplateId(), app.getServiceCorpId());
        // 获取第三方应用凭证
        String suiteAccessToken = wxServiceProviderUtil.getSuiteAccessToken(appTemplate.getTemplateId(),
            appTemplate.getTemplateSecret(),
            String.valueOf(redisService.get(QywxServiceProviderConstant.SERVICE_SUITE_TICKET + appTemplate.getTemplateId())));
        // 获取企业微信信息缓存
//        EduQywxServiceProviderSchool providerSchool = (EduQywxServiceProviderSchool) redisService
//                .hget(QywxServiceProviderConstant.PROVIDER_SCHOOL_CORP_ORIGINAL_DATA,
//                        app.getServiceCorpId() + "." + app.getWxCorpId());
        EduQywxServiceProviderSchool providerSchool = getCorpByOriginalData(app.getServiceCorpId(), app.getWxCorpId());
        return wxServiceProviderUtil.getCorpToken(providerSchool.getDeptEncryptionCorpId(), app.getWxSecret(), suiteAccessToken);
    }

    /**
     * 设置职工授权url
     *
     * @param corpId      企业的CorpID
     * @param redirectUrl 授权后重定向的回调链接地址，请使用urlencode对链接进行处理
     * @param agentId     应用agentid，snsapi_privateinfo时必填
     * @return java.lang.String
     * @author ZYJ
     * @date 2022/11/25 15:11
     */
    public String setAuthUrl(String corpId, String redirectUrl, String agentId) {
        return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + corpId
            + "&redirect_uri=" + URLEncoder.createDefault().encode(redirectUrl, CharsetUtil.CHARSET_UTF_8)
            + "&response_type=code&scope=snsapi_privateinfo&state=STATE"
            + "&agentid=" + agentId + "#wechat_redirect";
    }

    /**
     * 根据通讯录应用情况获取对应用户明文id 如果不是通讯录模板授权则返回本身userId
     *
     * @param userId   企业微信userId
     * @param schoolId 学校id
     * @param eduApp   通讯录app
     * @return java.lang.String
     * @author ZYJ
     * @date 2023/2/2 10:41
     */
    public String getPlainUserId(String userId, Long schoolId, EduApp eduApp) {
        // 获取学校通讯录应用
        EduApp app = getAppByCodeAndSchool(AppConstant.CONTACT, null, schoolId);

        // 本身就是明文id
        if (Objects.isNull(app.getTemplateId())) {
            return userId;
        } else {
            // 企业自建应用或基础应用的调用接口凭证
            EduApp appContactSchool = getAppByCodeAndSchool(AppConstant.CONTACT_SCHOOL, null, schoolId);
            String accessToken = wxUtil.getAccessToken(appContactSchool.getWxCorpId(), appContactSchool.getWxSecret());
            // 密文转换成明文id
            return wxServiceProviderUtil.convertUserIdToPlain(accessToken, userId, eduApp.getWxAgentId());
        }
    }

    /**
     * 根据通讯录应用情况获取对应用户密文id 如果不是通讯录模板授权则返回本身userId
     *
     * @param userId   企业微信userId
     * @param schoolId 学校id
     * @return java.lang.String
     * @author ZYJ
     * @date 2023/2/2 14:45
     */
    public String getSecretUserId(String userId, Long schoolId) {
        // 获取学校通讯录应用
        EduApp app = getAppByCodeAndSchool(AppConstant.CONTACT, null, schoolId);

        // 本身就是明文id
        if (Objects.isNull(app.getTemplateId())) {
            return userId;
        } else {
            EduApp eduApp = getAppByCodeAndSchool(AppConstant.CONTACT_SELECT, null, schoolId);
            // 明文转换成密文id
            return wxServiceProviderUtil.convertUserIdToSecret(
                wxUtil.getAccessToken(eduApp.getWxCorpId(), eduApp.getWxSecret()), userId);
        }
    }

    /**
     * 查询学校用于查询的通讯录应用
     *
     * @param schoolId 学校id
     * @return com.yida.data.common.core.entity.system.EduApp
     * @author ZYJ
     * @date 2023/4/23 20:25
     */
    public EduApp getAppContactUsedBySelect(Long schoolId) {
        // 获取学校通讯录应用
        EduApp app = getAppByCodeAndSchool(AppConstant.CONTACT, null, schoolId);
        // 本身就是明文id
        if (Objects.isNull(app.getTemplateId())) {
            return app;
        } else {
            return getAppByCodeAndSchool(AppConstant.CONTACT_SELECT, null, schoolId);
        }
    }

    /**
     * 根据学校名称查找机构信息
     *
     * @param schoolName 学校名称
     * @return com.yida.data.common.core.entity.system.Dept
     * @author ZYJ
     * @date 2023/2/2 11:03
     */
    public Dept getSchoolByName(String schoolName) {
        return remoteDeptService.getSchoolByName(schoolName).getData();
    }

    /**
     * 获取系统白名单信息
     *
     * @param functionName 功能名称 {@link SysFunctionEnum}
     * @return com.yida.data.common.core.entity.system.WhiteList
     * @author ZYJ
     * @date 2023/2/20 18:00
     */
    public WhiteList getWhiteList(String functionName) {
        WhiteList whiteList = redisService.hasKey(CachePrefixConstant.SYS_WHITE_LIST)
            ? (WhiteList) redisService.hget(CachePrefixConstant.SYS_WHITE_LIST, functionName)
            : null;
        if (whiteList == null) {
            whiteList = remoteWhiteListService.getWhiteList(functionName).getData();
            redisService.hset(CachePrefixConstant.SYS_WHITE_LIST, functionName, whiteList);
        }
        return whiteList;
    }

    /**
     * 获取部门是否开通当前功能
     *
     * @param functionName 功能名称
     * @param schoolId     部门id
     * @return com.yida.data.common.core.entity.system.EduDeptFunction
     * @author ZYJ
     * @date 2023/2/21 16:08
     */
    public EduDeptFunction getDeptFunction(String functionName, Long schoolId) {
        EduDeptFunction eduDeptFunction = redisService.hasKey(CachePrefixConstant.SYS_DEPT_FUNCTION + schoolId)
            ? (EduDeptFunction) redisService.hget(CachePrefixConstant.SYS_DEPT_FUNCTION + schoolId, functionName)
            : null;
        if (eduDeptFunction == null) {
            eduDeptFunction = remoteDeptFunctionService.getDeptFunction(functionName, schoolId).getData();
            redisService.hset(CachePrefixConstant.SYS_DEPT_FUNCTION + schoolId, functionName, eduDeptFunction);
        }
        return eduDeptFunction;
    }

    /**
     * 根据学校id查询百度api配置
     *
     * @param deptId     学校id
     * @param moduleName 百度模块名称 {@link BaiDuModuleEnum}
     * @return com.yida.data.common.core.entity.system.BaiduApiConfig
     * @author ZYJ
     * @date 2023/6/20 20:57
     */
    public BaiduApiConfig getBaiDuApiConfigByDept(Long deptId, String moduleName) {
        BaiduApiConfig config = redisService.hasKey(CachePrefixConstant.BAI_DU_API_CONFIG + deptId)
            ? (BaiduApiConfig) redisService.hget(CachePrefixConstant.BAI_DU_API_CONFIG + deptId, moduleName)
            : null;
        if (config == null) {
            config = remoteBaiDuApiConfigService.getBaiDuApiConfigByDept(deptId, moduleName).getData();
            redisService.hset(CachePrefixConstant.BAI_DU_API_CONFIG + deptId.toString(), moduleName, config);
        }
        return config;
    }

    public EduStaff getStaffById(Long staffId) {
        EduStaff staff = (EduStaff) redisService.hget(STAFF_DATA, staffId.toString());
        if (ObjectUtil.isNull(staff)) {
            staff = remoteStaffService.getStaff(staffId).getData();
            if (ObjectUtil.isNotNull(staff)) {
                redisService.hset(STAFF_DATA, staffId.toString(), staff);
            }
        }
        return staff;
    }

    public EduStudent getStudentById(Long id) {
        EduStudent student = (EduStudent) redisService
            .hget(CachePrefixConstant.STUDENT_DATA, id.toString());
        if (ObjectUtil.isNull(student)) {
            student = remoteStudentService.getStudentNoPermission(id).getData();
            if (student == null) {
                log.error("学生不存在,id:[{}]", id);
                return null;
            } else {
                redisService.hset(CachePrefixConstant.STUDENT_DATA, id.toString(), student);
            }
        }
        return student;
    }


    /**
     * 清除 人员匹配考勤规则
     */
    public void clearAttendanceRuleData() {
        redisService.del(CachePrefixConstant.ATTENDANCE_STUDENT_RULE);
    }


    public void delUserGenerateUrlLinkCache(Long schoolId, Long userId, Integer userType) {
        //查询所有的微信小程序app
        List<EduDeptHomeApp> eduDeptHomeAppList = remoteDeptHomeIndexService.getDeptAppList(schoolId).getData();
        List<EduDeptHomeApp> wxAppList = eduDeptHomeAppList.stream()
            .filter(e -> DeptAppTypeEnum.WX.getType().equals(e.getAppType()))
            .collect(Collectors.toList());
        for (EduDeptHomeApp homeApp : wxAppList) {
            redisService.del(CachePrefixConstant.USER_GENERATE_URL_LINK + userId + "" + userType + "" + homeApp.getId());
        }
    }

    public List<Long> findStaffMangerClassIdList() {
        List<Long> ClassIdList = new ArrayList<>();
        CurrentUser currentUser = FebsUtil.getCurrentUser();
        String rolePerms = FebsUtil.getCurrentUser().getRolePerms();
        return null;
    }
}
