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

import com.qmth.distributed.print.business.entity.TBSyncTask;
import com.qmth.distributed.print.business.service.CloudUserPushService;
import com.qmth.distributed.print.business.service.CloudUserPushStatusService;
import com.qmth.distributed.print.business.service.TBSyncTaskService;
import com.qmth.teachcloud.common.bean.params.UserPushParam;
import com.qmth.teachcloud.common.bean.result.PushResult;
import com.qmth.teachcloud.common.contant.SpringContextHolder;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.RoleTypeEnum;
import com.qmth.teachcloud.common.enums.TaskResultEnum;
import com.qmth.teachcloud.common.enums.TaskStatusEnum;
import com.qmth.teachcloud.common.enums.userPush.SpecialPrivilegeEnum;
import com.qmth.teachcloud.common.enums.userPush.SyncStatusEnum;
import com.qmth.teachcloud.common.enums.userPush.UserPushResultEnum;
import com.qmth.teachcloud.common.service.SysRoleService;
import com.qmth.teachcloud.common.service.SysUserRoleService;
import com.qmth.teachcloud.common.service.SysUserService;
import com.qmth.teachcloud.common.sync.CloudMarkingTaskUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @Description: 云阅卷用户推送服务类
 * @Author: CaoZixuan
 * @Date: 2022-08-02
 */
@Service
public class CloudUserPushServiceImpl implements CloudUserPushService {
    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private SysUserService sysUserService;
    @Resource
    private CloudMarkingTaskUtils stmmsUtils;
    @Resource
    private TBSyncTaskService tbSyncTaskService;
    @Resource
    private CloudUserPushStatusService cloudUserPushStatusService;

    @Override
    public void pushCloudUser(Long userId, SysUser requestUser) throws IllegalAccessException {
        List<Long> userIdList = new ArrayList<>();
        userIdList.add(userId);
        this.pushCloudUser(userIdList, requestUser);
    }

    @Override
    public void pushCloudUser(List<Long> userIdList, SysUser requestUser) throws IllegalAccessException {
        Long schoolId = requestUser.getSchoolId();
        userIdList = userIdList.stream().distinct().collect(Collectors.toList());
        if (userIdList.size() > 0) {
            List<SysUser> sysUserList = sysUserService.listByIds(userIdList);
            // 构建用户推送map
            Map<Long, List<UserPushParam>> userPushMap = this.buildUserPushMap(sysUserList, schoolId);

            // 初始化推送任务
            tbSyncTaskService.initUserPushTasks(userPushMap, requestUser);
            // 执行推送异步任务
            CloudUserPushService cloudUserPushService = SpringContextHolder.getBean(CloudUserPushService.class);
            cloudUserPushService.asyncPushUser(userPushMap, requestUser);
        }
    }

    @Async
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void asyncPushUser(Map<Long, List<UserPushParam>> userPushMap, SysUser requestUser) {
        for (Long userId : userPushMap.keySet()) {
            String syncException = "";
            // 更新该用户推送任务进行中
            TBSyncTask tbSyncTask = tbSyncTaskService.runningUserPushTask(userId, requestUser);
            // 初始化数据
            UserPushResultEnum markerPush = null;
            UserPushResultEnum leaderPush = null;
            SyncStatusEnum syncStatus = null;
            try {
                List<UserPushParam> userPushParamList = userPushMap.get(userId);
                for (UserPushParam userPushParam : userPushParamList) {
                    SpecialPrivilegeEnum specialRole = userPushParam.getRole();
                    boolean bind = userPushParam.getEnable();
                    PushResult pushResult = stmmsUtils.syncUser(userPushParam);
                    boolean syncResult = pushResult.getSuccess();
                    String syncExceptionCell = null;

                    if (syncResult) {
                        // 推送成功
                        syncStatus = SyncStatusEnum.ALREADY_PUSH;
                        switch (specialRole) {
                            case MARKER:
                                markerPush = bind ? UserPushResultEnum.BIND_SUCCESS : UserPushResultEnum.UNBIND_SUCCESS;
                                break;
                            case SUBJECT_HEADER:
                                leaderPush = bind ? UserPushResultEnum.BIND_SUCCESS : UserPushResultEnum.UNBIND_SUCCESS;
                                break;
                            default:
                                break;
                        }
                    } else {
                        // 推送失败
                        syncStatus = SyncStatusEnum.NEED_PUSH_AGAIN;
                        String errorMessage = pushResult.getMessage();
                        switch (specialRole) {
                            case MARKER:
                                markerPush = bind ? UserPushResultEnum.BIND_FAILED : UserPushResultEnum.UNBIND_FAILED;
                                syncExceptionCell = "【" + RoleTypeEnum.MARKER.getDesc() + markerPush.getDesc() + "】" + errorMessage + "\n";
                                break;
                            case SUBJECT_HEADER:
                                leaderPush = bind ? UserPushResultEnum.BIND_FAILED : UserPushResultEnum.UNBIND_FAILED;
                                syncExceptionCell = "【" + RoleTypeEnum.MARKER_LEADER.getDesc() + leaderPush.getDesc() + "】" + errorMessage + "\n";
                                break;
                            default:
                                break;
                        }
                    }
                    if (SystemConstant.strNotNull(syncExceptionCell)) {
                        syncException = syncException + syncExceptionCell;
                    }
                }
            } catch (Exception e) {
                syncException = syncException + e.getMessage();
            } finally {
                // 更新或新增云阅卷用户推送表状态
                cloudUserPushStatusService.updateUserPushRecord(userId, markerPush, leaderPush, syncStatus, requestUser);
                // 更新't_b_sync_task'表
                if (SystemConstant.strNotNull(syncException)) {
                    tbSyncTask.setResult(TaskResultEnum.ERROR);
                    tbSyncTask.setErrorMessage("用户【" + sysUserService.getById(userId).getLoginName() + "】推送失败\n" + syncException);
                } else {
                    tbSyncTask.setResult(TaskResultEnum.SUCCESS);
                }
                tbSyncTask.setStatus(TaskStatusEnum.FINISH);
                tbSyncTask.updateInfo(requestUser.getId());
                tbSyncTaskService.saveOrUpdate(tbSyncTask);
            }
        }
    }

    /**
     * 构建用户推送map
     *
     * @param sysUserList 用户集合
     * @param schoolId    学校id
     * @return k -> userId v-> List<UserPushParam> 有且只有两条记录
     */
    private Map<Long, List<UserPushParam>> buildUserPushMap(List<SysUser> sysUserList, Long schoolId) {
        Map<Long, List<UserPushParam>> userPushMap = new HashMap<>();

        for (SysUser sysUser : sysUserList) {
            // 用户基础信息
            Long userId = sysUser.getId();
            String loginName = sysUser.getLoginName();
            String realName = sysUser.getRealName();
            String password = "123456";

            // 用户推送相关信息
            boolean enable = sysUser.getEnable();
            SyncStatusEnum syncStatus = cloudUserPushStatusService.findRecordByUserId(userId, schoolId).getSyncStatus();
            boolean isMarker = sysUserService.includeSysRole(userId, RoleTypeEnum.MARKER);
            boolean isLeader = sysUserService.includeSysRole(userId, RoleTypeEnum.MARKER_LEADER);

            // 初始化推送对象
            List<UserPushParam> userPushParamList = new ArrayList<>();
            UserPushParam marker = new UserPushParam();
            marker.setUserId(userId);
            marker.setSchoolId(schoolId);
            marker.setName(realName);
            marker.setPassword(password);
            marker.setRole(SpecialPrivilegeEnum.MARKER);
            marker.setAccount(SpecialPrivilegeEnum.MARKER.getPrefix() + loginName);
            marker.setEnable(false); // 给默认状态关闭

            UserPushParam leader = new UserPushParam();
            leader.setUserId(userId);
            leader.setSchoolId(schoolId);
            leader.setName(realName);
            leader.setPassword(password);
            leader.setRole(SpecialPrivilegeEnum.SUBJECT_HEADER);
            leader.setAccount(SpecialPrivilegeEnum.SUBJECT_HEADER.getPrefix() + loginName);
            leader.setEnable(false); // 给默认状态关闭

            // 如果当前用户有评卷员角色
            if (isMarker) {
                // 如果用户是启用状态就绑定，禁用就解绑
                marker.setEnable(enable);
            }
            // 如果当前用户有科组长角色
            if (isLeader) {
                // 如果用户是启用状态就绑定，禁用就解绑
                leader.setEnable(enable);
            }
            // 如果当前用户既不是评卷员，也不是科组长，根据用户推送状态判断
            if (!isMarker && !isLeader) {
                // 如果该用户曾经推送过，则推送评卷员和科组长的解绑。
                if (SyncStatusEnum.ALREADY_PUSH.equals(syncStatus) || SyncStatusEnum.NEED_PUSH_AGAIN.equals(syncStatus)) {
                    // 评卷员解绑
                    marker.setEnable(false);

                    // 科组长解绑
                    leader.setEnable(false);
                } else {
                    // 该用户曾经就不包含云阅卷特殊角色，现在也不包含云阅卷特殊角色
                    marker = null;
                    leader = null;
                }
            }
            if (Objects.nonNull(marker)) {
                userPushParamList.add(marker);
                userPushParamList.add(leader);
                userPushMap.put(userId, userPushParamList);
            }
        }
        return userPushMap;
    }
}
