package com.qmth.paper.library.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qmth.boot.core.solar.config.SolarProperties;
import com.qmth.boot.core.solar.model.AppInfo;
import com.qmth.boot.core.solar.model.OrgInfo;
import com.qmth.boot.core.solar.service.SolarService;
import com.qmth.paper.library.common.bean.dto.AuthOrgInfoDto;
import com.qmth.paper.library.common.entity.BasicSchool;
import com.qmth.paper.library.common.entity.SysOrg;
import com.qmth.paper.library.common.entity.TSAuth;
import com.qmth.paper.library.common.enums.AuthEnum;
import com.qmth.paper.library.common.enums.ExceptionResultEnum;
import com.qmth.paper.library.common.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @Description: 授权信息service
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2022/5/17
 */
@Service
public class AuthInfoServiceImpl implements AuthInfoService {
    private final static Logger log = LoggerFactory.getLogger(AuthInfoServiceImpl.class);

    @Resource
    private SolarProperties solarProperties;
    @Resource
    private SolarService solarService;
    @Resource
    private TSAuthService tsAuthService;
    @Resource
    private BasicSchoolService basicSchoolService;
    @Resource
    private AuthInfoService authInfoService;
    @Resource
    private SysOrgService sysOrgService;
    @Resource
    private LibraryCommonService libraryCommonService;
    @Resource
    private SystemFileTypeService systemFileTypeService;

    /**
     * 授权信息初始化
     *
     * @return
     */
    @Override
    public AppInfo appInfoInit() {
        AppInfo appInfo = null;
        try {
            appInfo = solarService.getAppInfo();
            if (Objects.nonNull(appInfo) && Objects.nonNull(solarProperties)) {
                if (Objects.nonNull(solarProperties.getAccessKey())
                        && !Objects.equals(solarProperties.getAccessKey().trim(), "")
                        && Objects.nonNull(solarProperties.getAccessSecret())
                        && !Objects.equals(solarProperties.getAccessSecret().trim(), "")) {//在线激活
                    authInfoService.saveAuthInfo(appInfo, AuthEnum.ON_LINE, null);
                } else if (Objects.nonNull(solarProperties.getLicense())
                        && !Objects.equals(solarProperties.getLicense().trim(), "")) {//离线激活
                    authInfoService.saveAuthInfo(appInfo, AuthEnum.OFF_LINE, null);
                }
            } else {
                QueryWrapper<TSAuth> tsAuthQueryWrapper = new QueryWrapper<>();
                tsAuthQueryWrapper.lambda().isNotNull(TSAuth::getFile);
                List<TSAuth> tsAuthList = tsAuthService.list(tsAuthQueryWrapper);
                if (!CollectionUtils.isEmpty(tsAuthList)) {
                    for (TSAuth t : tsAuthList) {
                        appInfo = solarService.update(t.getFile());
                        authInfoService.saveAuthInfo(appInfo, AuthEnum.OFF_LINE, t.getFile());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return appInfo;
    }

    /**
     * app是否过期
     *
     * @param code
     * @return
     */
    @Override
    public void appHasExpired(String code) {
        if (Objects.nonNull(code)) {
            AuthOrgInfoDto authOrgInfoDto = libraryCommonService.authInfoCache(code);
            if (Objects.isNull(authOrgInfoDto) || (Objects.nonNull(authOrgInfoDto) && authOrgInfoDto.getControl().hasExpired())) {
                throw ExceptionResultEnum.AUTH_INFO_ERROR.exception();
            }
        }
    }

    /**
     * 离线激活
     *
     * @param licenseData
     */
    @Override
    public void updateLicense(byte[] licenseData) throws Exception {
        AppInfo appInfo = solarService.update(licenseData);
        if (Objects.isNull(appInfo)) {
            throw ExceptionResultEnum.ERROR.exception("激活失败");
        }
        authInfoService.saveAuthInfo(appInfo, AuthEnum.OFF_LINE, licenseData);
    }

    /**
     * 查询授权信息
     *
     * @return
     */
    @Override
    public Long selectAuthInfo() {
        Long expireTime = null;
        AppInfo appInfo = solarService.getAppInfo();
        if (Objects.nonNull(appInfo) && Objects.nonNull(appInfo.getControl())) {
            expireTime = Objects.nonNull(appInfo.getControl().getExpireTime()) ? appInfo.getControl().getExpireTime() : -1;
        }
        return expireTime;
    }

    /**
     * 保存鉴权信息
     *
     * @param appInfo
     * @param authEnum
     * @param file
     * @throws Exception
     */
    @Override
    @Transactional
    public void saveAuthInfo(AppInfo appInfo, AuthEnum authEnum, byte[] file) throws Exception {
        List<OrgInfo> orgInfoList = solarService.getOrgList();
        if (CollectionUtils.isEmpty(orgInfoList)) {
            throw ExceptionResultEnum.ERROR.exception("没有可授权机构信息");
        }
        List<TSAuth> tsAuthList = null;
        Set<Long> orgIdsSet = null;
        Set<BasicSchool> basicSchoolSet = null;
        Set<SysOrg> sysOrgSet = null;
        if (!CollectionUtils.isEmpty(orgInfoList)) {
            tsAuthList = new ArrayList<>();
            orgIdsSet = new HashSet<>();
            basicSchoolSet = new HashSet<>();
            sysOrgSet = new HashSet<>();
        }
        for (OrgInfo o : orgInfoList) {
            orgIdsSet.add(o.getId());
            if (authEnum == AuthEnum.OFF_LINE) {
                if (Objects.isNull(file)) {
                    tsAuthList.add(new TSAuth(o.getId(), solarProperties.getLicense(), authEnum, appInfo.getControl().getExpireTime()));
                } else {
                    tsAuthList.add(new TSAuth(o.getId(), file, authEnum, appInfo.getControl().getExpireTime()));
                }
            } else {
                tsAuthList.add(new TSAuth(o.getId(), solarProperties.getAccessKey(), solarProperties.getAccessSecret(), authEnum, appInfo.getControl().getExpireTime()));
            }

            QueryWrapper<BasicSchool> basicSchoolQueryWrapper = new QueryWrapper<>();
            basicSchoolQueryWrapper.lambda().eq(BasicSchool::getCode, o.getCode());
            BasicSchool basicSchool = basicSchoolService.getOne(basicSchoolQueryWrapper);
            if (Objects.isNull(basicSchool)) {
                //不存在则创建学校
                basicSchool = new BasicSchool(o.getId(), o.getCode(), o.getName(), o.getAccessKey(), o.getAccessSecret());
                basicSchool.setLogo(o.getLogo());
                basicSchoolSet.add(basicSchool);
            }
            QueryWrapper<SysOrg> sysOrgQueryWrapper = new QueryWrapper<>();
            sysOrgQueryWrapper.lambda().eq(SysOrg::getSchoolId, basicSchool.getId());
            int count = sysOrgService.count(sysOrgQueryWrapper);
            if (count == 0) {
                sysOrgSet.add(new SysOrg(basicSchool.getId(), basicSchool.getName()));
            }
        }

        if (!CollectionUtils.isEmpty(tsAuthList) && !CollectionUtils.isEmpty(orgIdsSet)) {
            QueryWrapper<TSAuth> tsAuthQueryWrapper = new QueryWrapper<>();
            tsAuthQueryWrapper.lambda().in(TSAuth::getSchoolId, orgIdsSet);
            tsAuthService.remove(tsAuthQueryWrapper);
            tsAuthService.saveOrUpdateBatch(tsAuthList);

            if (!CollectionUtils.isEmpty(basicSchoolSet)) {
                basicSchoolService.saveBatch(basicSchoolSet);
                //初始化学校的文件类型
                for (BasicSchool basicSchool : basicSchoolSet) {
                    systemFileTypeService.saveSystemFileType(basicSchool.getId());
                }
            }

            if (!CollectionUtils.isEmpty(sysOrgSet)) {
                sysOrgService.saveBatch(sysOrgSet);
            }
        }
    }
}
