package com.qmth.distributed.print.business.service.impl;

import com.qmth.boot.tools.signature.SignatureEntity;
import com.qmth.boot.tools.signature.SignatureType;
import com.qmth.distributed.print.business.service.SsoService;
import com.qmth.teachcloud.common.config.DictionaryConfig;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicSchool;
import com.qmth.teachcloud.common.entity.SysOrg;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.OrgTypeEnum;
import com.qmth.teachcloud.common.enums.RoleTypeEnum;
import com.qmth.teachcloud.common.enums.userPush.SpecialPrivilegeEnum;
import com.qmth.teachcloud.common.service.CommonCacheService;
import com.qmth.teachcloud.common.service.SysOrgService;
import com.qmth.teachcloud.common.service.SysUserService;
import com.qmth.teachcloud.common.sync.CloudMarkingTaskUtils;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

/**
 * @Date: 2021/5/20.
 */
@Service
public class SsoServiceImpl implements SsoService {
    private final static Logger log = LoggerFactory.getLogger(SsoServiceImpl.class);

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    CloudMarkingTaskUtils stmmsUtils;

    @Resource
    DictionaryConfig dictionaryConfig;

    @Resource
    CommonCacheService commonCacheService;

    @Resource
    SysOrgService sysOrgService;

    @Override
    public Map<String, Object> markerLoginInfo() {
        try {
            SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
            SpecialPrivilegeEnum userSpecialPrivilege = sysUserService.findUserSpecialPrivilegeByUserId(sysUser.getId(), sysUser.getSchoolId());
            if (SpecialPrivilegeEnum.UNIDENTIFIED.equals(userSpecialPrivilege)
                    || SpecialPrivilegeEnum.SUBJECT_HEADER.equals(userSpecialPrivilege)) {
                throw ExceptionResultEnum.ERROR.exception("该用户没有评卷员角色，无法登录");
            }
            return stmmsUtils.markLogin(sysUser);
        } catch (Exception e) {
            throw ExceptionResultEnum.ERROR.exception(e.getMessage());
        }
    }

    @Override
    public Map<String, Object> markerLeaderLoginInfo() {
        try {
            SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
            SpecialPrivilegeEnum userSpecialPrivilege = sysUserService.findUserSpecialPrivilegeByUserId(sysUser.getId(), sysUser.getSchoolId());
            if (SpecialPrivilegeEnum.UNIDENTIFIED.equals(userSpecialPrivilege)
                    || SpecialPrivilegeEnum.MARKER.equals(userSpecialPrivilege)) {
                throw ExceptionResultEnum.ERROR.exception("该用户没有科组长角色，无法登录");
            }
            return stmmsUtils.markLeaderLogin(sysUser);
        } catch (Exception e) {
            throw ExceptionResultEnum.ERROR.exception(e.getMessage());
        }
    }

    /**
     * 教研分析单点登录
     *
     * @param loginName
     * @param role
     * @param orgName
     * @param realName
     * @param mobileNumber
     * @param enable
     * @param returnUrl
     * @return
     * @throws IOException
     */
    @Override
    public Map<String, Object> analysisLogin(String loginName, RoleTypeEnum role, String orgName, String realName, String mobileNumber, Boolean enable, String returnUrl) throws IOException {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        BasicSchool basicSchool = commonCacheService.schoolCache(sysUser.getSchoolId());
        if (role == RoleTypeEnum.PRESIDENT || role == RoleTypeEnum.TEACHER) {
            List<SysOrg> sysOrgList = sysOrgService.findByConnectByParentId(sysUser.getOrgId(), false, true);
            if (CollectionUtils.isEmpty(sysOrgList)) {
                throw ExceptionResultEnum.ERROR.exception("未找到学院信息");
            } else {
                List<SysOrg> sysOrgSchool = sysOrgList.stream().filter(s -> s.getType() == OrgTypeEnum.SCHOOL).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(sysOrgSchool)) {
                    for (SysOrg s : sysOrgList) {
                        if (Objects.nonNull(s.getParentId()) && s.getParentId().longValue() == sysOrgSchool.get(0).getId().longValue()) {
                            orgName = s.getName();
                            break;
                        }
                    }
                } else {
                    throw ExceptionResultEnum.ERROR.exception("未找到顶级学校信息");
                }
            }
        } else if (role == RoleTypeEnum.OFFICE_TEACHER && Objects.nonNull(sysUser.getOrgId())) {
            SysOrg sysOrg = commonCacheService.orgCache(sysUser.getOrgId());
            if (Objects.isNull(sysOrg)) {
                throw ExceptionResultEnum.ERROR.exception("未找到学校信息");
            } else if (Objects.nonNull(sysOrg) && sysOrg.getType() != OrgTypeEnum.SCHOOL) {
                throw ExceptionResultEnum.ERROR.exception("教务处老师应放在顶级机构");
            }
            orgName = sysOrg.getName();
        }

        Map<String, Object> map = new HashMap<>();
        map.computeIfAbsent("loginName", v -> loginName);
        map.computeIfAbsent("role", v -> role);
        map.put("orgName", orgName);
        map.computeIfAbsent("realName", v -> realName);
        map.computeIfAbsent("mobileNumber", v -> mobileNumber);
        map.computeIfAbsent("returnUrl", v -> returnUrl);

        Long timestamp = System.currentTimeMillis();
        String accessToken = SignatureEntity.build(SignatureType.SECRET, SystemConstant.METHOD, dictionaryConfig.reportOpenDomain().getSsoLoginApi(), timestamp, basicSchool.getAccessKey(), basicSchool.getAccessSecret());
        map.computeIfAbsent("time", v -> timestamp);
        map.computeIfAbsent("authorization", v -> accessToken);

        SystemConstant.getLocalFileHost(dictionaryConfig.reportOpenDomain().getHostUrl());
        String hostUrl = dictionaryConfig.reportOpenDomain().getHostUrl();
        Optional.ofNullable(hostUrl).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未配置教研分析host"));

        hostUrl = SystemConstant.getLocalFileHost(hostUrl);
        map.put("redirectUrl", hostUrl + dictionaryConfig.reportOpenDomain().getSsoLoginApi());
        return map;
    }
}
