package com.sundot.airport.web.core.utils;

import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.core.domain.entity.SysRole;
import com.sundot.airport.common.core.domain.model.LoginUser;
import com.sundot.airport.common.enums.RoleTypeEnum;
import com.sundot.airport.system.service.ISysDeptService;
import com.sundot.airport.common.enums.DataPermissionType;
import com.sundot.airport.common.core.domain.DataPermissionResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import com.sundot.airport.common.core.domain.BaseEntity;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 数据权限工具类
 *
 * @author ruoyi
 */
@Component
public class DataPermissionUtils {

    private static ISysDeptService sysDeptService;

    @Autowired
    public void setSysDeptService(ISysDeptService sysDeptService) {
        DataPermissionUtils.sysDeptService = sysDeptService;
    }

    /**
     * 获取数据权限结果
     *
     * @param userId    当前用户ID
     * @param deptId    当前用户部门ID
     * @param loginUser 当前登录用户信息
     * @return 数据权限结果
     */
    public static DataPermissionResult getDataPermission(Long userId, Long deptId, LoginUser loginUser) {
        // 管理员查看所有数据
        if (userId == 1) {
            return new DataPermissionResult(DataPermissionType.ALL, null);
        }

        // 获取用户角色列表
        List<SysRole> roles = loginUser.getUser().getRoles();

        // 如果没有角色，则只查看自己的数据
        if (CollectionUtils.isEmpty(roles)) {
            return new DataPermissionResult(DataPermissionType.SELF, userId);
        }

        // 提取用户的角色键值列表
        List<String> roleKeys = roles.stream().map(SysRole::getRoleKey).collect(Collectors.toList());

        // 检查是否包含特定角色
        boolean isAdminRole = roleKeys.contains(RoleTypeEnum.admin.getCode());
        boolean isStationRole = roleKeys.contains(RoleTypeEnum.test.getCode()) || roleKeys.contains(RoleTypeEnum.zhijianke.getCode());
        boolean isBrigadeRole = roleKeys.contains(RoleTypeEnum.jingli.getCode()) || roleKeys.contains(RoleTypeEnum.xingzheng.getCode());
        boolean isDepartmentRole = roleKeys.contains(RoleTypeEnum.kezhang.getCode());
        boolean isTeamRole = roleKeys.contains(RoleTypeEnum.banzuzhang.getCode());
        boolean isInspectorRole = roleKeys.contains(RoleTypeEnum.SecurityCheck.getCode());

        SysDept sysDept = sysDeptService.selectDeptById(deptId);

        // 管理员角色查看所有数据
        if (isAdminRole) {
            return new DataPermissionResult(DataPermissionType.ALL, null);
        }
        // 站级角色查看本站数据
        else if (isStationRole) {
            if (sysDept != null) {
                return new DataPermissionResult(DataPermissionType.STATION, sysDept.getDeptId());
            } else {
                return new DataPermissionResult(DataPermissionType.SELF, userId);
            }
        }
        // 大队级角色查看本站数据
        else if (isBrigadeRole) {
            if (sysDept != null) {
                return new DataPermissionResult(DataPermissionType.BRIGADE, sysDept.getDeptId());
            } else {
                return new DataPermissionResult(DataPermissionType.SELF, userId);
            }
        }
        // 科室角色查看本科室数据
        else if (isDepartmentRole) {
            if (sysDept != null) {
                return new DataPermissionResult(DataPermissionType.DEPARTMENT, sysDept.getDeptId());
            } else {
                return new DataPermissionResult(DataPermissionType.SELF, userId);
            }
        }
        // 班组角色查看本班组数据
        else if (isTeamRole) {
            if (sysDept != null) {
                return new DataPermissionResult(DataPermissionType.TEAM, sysDept.getDeptId());
            } else {
                return new DataPermissionResult(DataPermissionType.SELF, userId);
            }
        }
        // 安检员角色只查看自己的数据
        else if (isInspectorRole) {
            return new DataPermissionResult(DataPermissionType.SELF, userId);
        }
        // 默认情况只查看自己的数据
        else {
            return new DataPermissionResult(DataPermissionType.SELF, userId);
        }
    }

    /**
     * 判断用户是否具有管理员角色
     *
     * @param loginUser 当前登录用户
     * @return 是否是管理员
     */
    public static boolean isAdmin(LoginUser loginUser) {
        return hasRole(loginUser, RoleTypeEnum.admin.getCode());
    }

    /**
     * 判断用户是否具有站级角色（站长或质检科）
     *
     * @param loginUser 当前登录用户
     * @return 是否是站级角色
     */
    public static boolean isStationRole(LoginUser loginUser) {
        return hasRole(loginUser, RoleTypeEnum.test.getCode()) ||
                hasRole(loginUser, RoleTypeEnum.zhijianke.getCode());
    }

    /**
     * 判断用户是否具有大队级角色（经理或大队行政）
     *
     * @param loginUser 当前登录用户
     * @return 是否是站级角色
     */
    public static boolean isBrigadeRole(LoginUser loginUser) {
        return hasRole(loginUser, RoleTypeEnum.jingli.getCode()) ||
                hasRole(loginUser, RoleTypeEnum.xingzheng.getCode());
    }

    /**
     * 判断用户是否具有科室角色
     *
     * @param loginUser 当前登录用户
     * @return 是否是科室角色
     */
    public static boolean isDepartmentRole(LoginUser loginUser) {
        return hasRole(loginUser, RoleTypeEnum.kezhang.getCode());
    }

    /**
     * 判断用户是否具有班组角色
     *
     * @param loginUser 当前登录用户
     * @return 是否是班组角色
     */
    public static boolean isTeamRole(LoginUser loginUser) {
        return hasRole(loginUser, RoleTypeEnum.banzuzhang.getCode());
    }

    /**
     * 判断用户是否具有安检员角色
     *
     * @param loginUser 当前登录用户
     * @return 是否是安检员角色
     */
    public static boolean isInspectorRole(LoginUser loginUser) {
        return hasRole(loginUser, RoleTypeEnum.SecurityCheck.getCode());
    }

    /**
     * 判断用户是否具有指定角色
     *
     * @param loginUser 当前登录用户
     * @param roleKey   角色键值
     * @return 是否具有指定角色
     */
    private static boolean hasRole(LoginUser loginUser, String roleKey) {
        if (loginUser == null || loginUser.getUser() == null ||
                CollectionUtils.isEmpty(loginUser.getUser().getRoles())) {
            return false;
        }

        return loginUser.getUser().getRoles().stream()
                .anyMatch(role -> roleKey.equals(role.getRoleKey()));
    }
}