import { Injectable, NotFoundException } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { Role } from './entities/role.entity';
import { CreateRoleDto } from './dto/create-role.dto';
import { UpdateRoleDto } from './dto/update-role.dto';
import { Permission } from '../permission/entities/permission.entity';
import { PermissionService } from '../permission/permission.service';

@Injectable()
export class RoleService {
  constructor(
    @InjectRepository(Role, 'scheme_dbs')
    private readonly roleRepo: Repository<Role>,
    private readonly permissionService: PermissionService,
  ) {}

  async create(dto: CreateRoleDto): Promise<Role> {
    const role = new Role();
    role.name = dto.name;
    role.description = dto.description || '';
    role.is_active = dto.is_active !== undefined ? dto.is_active : true;

    if (dto.permissionIds?.length) {
      role.permissions = await this.permissionService.findByIds(dto.permissionIds);
    }

    return this.roleRepo.save(role);
  }

  async findAll(): Promise<Role[]> {
    return this.roleRepo.find({ relations: ['permissions'] });
  }

  async findOne(id: number): Promise<Role> {
    const role = await this.roleRepo.findOne({
      where: { id },
      relations: ['permissions'],
    });

    if (!role) {
      throw new NotFoundException(`Role with ID ${id} not found`);
    }

    return role;
  }

  async update(id: number, dto: UpdateRoleDto): Promise<Role> {
    const role = await this.findOne(id);

    if (dto.name !== undefined) {
      role.name = dto.name;
    }
    if (dto.description !== undefined) {
      role.description = dto.description;
    }
    if (dto.is_active !== undefined) {
      role.is_active = dto.is_active;
    }

    if (dto.permissionIds !== undefined) {
      if (dto.permissionIds.length > 0) {
        role.permissions = await this.permissionService.findByIds(dto.permissionIds);
      } else {
        role.permissions = [];
      }
    }

    return this.roleRepo.save(role);
  }

  async remove(id: number): Promise<void> {
    const role = await this.findOne(id);
    await this.roleRepo.remove(role);
  }
}
