import { DataSource } from 'typeorm';
import { Role } from '../entities/role.entity';
import { ConcreteCrudService } from '@d8d/shared-crud';

export class RoleService extends ConcreteCrudService<Role> {
  constructor(_dataSource: DataSource) {
    super(Role, {
      userTracking: {
        // 禁用用户追踪
      }
    });
  }

  /**
   * 根据角色名获取角色
   */
  async getRoleByName(name: string): Promise<Role | null> {
    try {
      const where: any = { name };

      const roles = await this.repository.find({ where });
      return roles.length > 0 ? roles[0] ?? null : null;
    } catch (error) {
      console.error('Error getting role by name:', error);
      throw new Error('Failed to get role by name');
    }
  }

  /**
   * 检查角色是否拥有指定权限
   */
  async hasPermission(roleId: number, permission: string): Promise<boolean> {
    try {
      const role = await this.getById(roleId);
      if (!role) return false;

      return role.permissions.includes(permission);
    } catch (error) {
      console.error('Error checking permission:', error);
      throw new Error('Failed to check permission');
    }
  }

  /**
   * 获取所有角色
   */
  async getRoles(): Promise<Role[]> {
    try {
      const where: any = {};

      return await this.repository.find({ where });
    } catch (error) {
      console.error('Error getting roles:', error);
      throw new Error(`Failed to get roles: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  /**
   * 根据ID获取角色
   */
  override async getById(id: number, relations: string[] = []): Promise<Role | null> {
    try {
      const where: any = { id };

      return await this.repository.findOne({ where, relations });
    } catch (error) {
      console.error('Error getting role by id:', error);
      throw new Error('Failed to get role by id');
    }
  }

  /**
   * 更新角色
   */
  override async update(id: number, data: Partial<Role>, _userId?: string | number): Promise<Role | null> {
    try {
      // 首先验证角色是否存在
      const existingRole = await this.getById(id);
      if (!existingRole) return null;

      // 更新角色
      await this.repository.update(id, data);

      // 返回更新后的角色
      return await this.getById(id);
    } catch (error) {
      console.error('Error updating role:', error);
      throw new Error('Failed to update role');
    }
  }

  /**
   * 删除角色
   */
  override async delete(id: number, _userId?: string | number): Promise<boolean> {
    try {
      // 首先验证角色是否存在
      const existingRole = await this.getById(id);
      if (!existingRole) return false;

      // 删除角色
      const result = await this.repository.delete(id);
      return result.affected === 1;
    } catch (error) {
      console.error('Error deleting role:', error);
      throw new Error('Failed to delete role');
    }
  }
}