import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Repository } from 'typeorm';
import { Permission } from './permission.entity';

export interface PermissionGroup {
  group: string;
  permissions: Permission[];
}

@Injectable()
export class PermissionsService {
  constructor(
    @InjectRepository(Permission) private readonly repo: Repository<Permission>,
  ) {}

  findAll(): Promise<Permission[]> {
    return this.repo.find({ order: { name: 'ASC' } });
  }

  /** Groups by the prefix before the dot, e.g. `module.create` -> `module`. */
  async findGrouped(): Promise<PermissionGroup[]> {
    const permissions = await this.findAll();
    const groups = new Map<string, Permission[]>();

    for (const permission of permissions) {
      const group = permission.name.split('.')[0];
      const bucket = groups.get(group);
      if (bucket) {
        bucket.push(permission);
      } else {
        groups.set(group, [permission]);
      }
    }

    return Array.from(groups.entries()).map(([group, items]) => ({
      group,
      permissions: items,
    }));
  }

  create(data: Partial<Permission>): Promise<Permission> {
    return this.repo.save(this.repo.create(data));
  }

  findByIds(ids: number[]): Promise<Permission[]> {
    if (!ids?.length) return Promise.resolve([]);
    return this.repo.find({ where: { id: In(ids) } });
  }
}
