package cn.iocoder.byzs.module.blockly.job;

import cn.iocoder.byzs.framework.quartz.core.handler.JobHandler;
import cn.iocoder.byzs.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.byzs.module.blockly.dal.dataobject.blocklyType.BlocklyTypeDO;
import cn.iocoder.byzs.module.blockly.service.blocklyType.BlocklyTypeService;
import cn.iocoder.byzs.module.system.dal.dataobject.permission.RoleDO;
import cn.iocoder.byzs.module.system.service.permission.RoleService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 每天开2节blockly课程 Job
 *
 * @author j-sentinel
 */
@Slf4j
@Component
public class JobBlockluAotoRoleJob implements JobHandler {

    @Resource
    private BlocklyTypeService blocklyTypeService;

    @Resource
    private RoleService roleService;

    // 定义常量
    private static final Integer autoCount = 2; // 自动分配的课程数量

    @Override
    @TenantIgnore
    public String execute(String roleIdParam) {
        log.info("开始执行自动分配blockly课程权限任务, 角色ID: {}", roleIdParam);
        Long roleId = Long.parseLong(roleIdParam);

        try {
            // 1. 获取指定租户下的角色信息
            RoleDO role = roleService.getRole(roleId);
            if (role == null) {
                log.warn("未找到指定角色, roleId: {}", roleId);
                return "未找到指定角色";
            }

            // 2. 获取角色当前的blockly权限
            Set<Long> existingBlocklyIds = role.getDataScopeBlocklyIds();
            if (existingBlocklyIds == null) {
                existingBlocklyIds = new HashSet<>();
            }

            // 3. 获取所有blockly主题列表（父级ID为0的类型）
            List<BlocklyTypeDO> themes = blocklyTypeService.getBlocklyTypeList(
                    new cn.iocoder.byzs.module.blockly.controller.admin.blocklyType.vo.BlocklyTypeListReqVO()
                            .setCtParentId(BlocklyTypeDO.CT_PARENT_ID_ROOT)
            );

            // 按排序字段升序排列主题
            themes.sort(Comparator.comparing(BlocklyTypeDO::getCtTypeSort, Comparator.nullsLast(Comparator.naturalOrder())));

            log.info("获取到 {} 个主题", themes.size());

            // 4. 收集需要新增的课程ID
            Set<Long> newBlocklyIds = new HashSet<>();

            // 5. 遍历主题，查找每个主题下的课程类型和课程
            for (BlocklyTypeDO theme : themes) {
                if (newBlocklyIds.size() >= autoCount) {
                    break; // 已经找到2个未配置的课程，跳出循环
                }

                // 获取当前主题下的所有课程类型
                List<BlocklyTypeDO> courseTypes = blocklyTypeService.getBlocklyTypeList(
                        new cn.iocoder.byzs.module.blockly.controller.admin.blocklyType.vo.BlocklyTypeListReqVO()
                                .setCtParentId(theme.getId())
                );

                // 按排序字段升序排列课程类型
                courseTypes.sort(Comparator.comparing(BlocklyTypeDO::getCtTypeSort, Comparator.nullsLast(Comparator.naturalOrder())));

                log.info("主题 {} 下有 {} 个课程类型", theme.getCtType(), courseTypes.size());

                // 遍历课程类型，获取课程
                for (BlocklyTypeDO courseType : courseTypes) {
                    if (newBlocklyIds.size() >= autoCount) {
                        break; // 已经找到2个未配置的课程，跳出循环
                    }

                    // 检查该课程是否已经配置了权限
                    if (!existingBlocklyIds.contains(courseType.getId())) {
                        newBlocklyIds.add(courseType.getId());
                        log.info("找到未配置权限的课程: ID={}, 名称={}", courseType.getId(), courseType.getCtType());
                    }
                }
            }

            // 6. 如果找到了新的课程ID，更新角色权限
            if (!newBlocklyIds.isEmpty()) {
                // 合并现有的权限和新权限
                Set<Long> updatedBlocklyIds = new HashSet<>(existingBlocklyIds);
                updatedBlocklyIds.addAll(newBlocklyIds);

                // 更新角色的blockly权限
                roleService.updateRoleBlocklyScope(roleId, updatedBlocklyIds);
                log.info("成功为角色 {} 添加了 {} 个新的blockly课程权限: {}", roleId, updatedBlocklyIds.size(), updatedBlocklyIds);
                return String.format("成功添加了 %d 个新的blockly课程权限", updatedBlocklyIds.size());
            } else {
                log.info("未找到需要新增的blockly课程权限");
                return "未找到需要新增的blockly课程权限";
            }
        } catch (Exception e) {
            log.error("执行自动分配blockly课程权限任务时发生错误", e);
            return "执行任务时发生错误: " + e.getMessage();
        }
    }
}