import {
  Controller,
  Get,
  Patch,
  Body,
  UseGuards,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { RolesGuard, Roles } from '@it0/common';
import { Role } from '../../../domain/entities/role.entity';

// All available permissions in the system
const ALL_PERMISSIONS = [
  { id: 'servers:create', key: 'servers:create', resource: 'servers', action: 'create', description: 'Create servers' },
  { id: 'servers:read', key: 'servers:read', resource: 'servers', action: 'read', description: 'View servers' },
  { id: 'servers:update', key: 'servers:update', resource: 'servers', action: 'update', description: 'Update servers' },
  { id: 'servers:delete', key: 'servers:delete', resource: 'servers', action: 'delete', description: 'Delete servers' },
  { id: 'servers:execute', key: 'servers:execute', resource: 'servers', action: 'execute', description: 'Execute commands on servers' },
  { id: 'tasks:create', key: 'tasks:create', resource: 'tasks', action: 'create', description: 'Create tasks' },
  { id: 'tasks:read', key: 'tasks:read', resource: 'tasks', action: 'read', description: 'View tasks' },
  { id: 'tasks:update', key: 'tasks:update', resource: 'tasks', action: 'update', description: 'Update tasks' },
  { id: 'tasks:delete', key: 'tasks:delete', resource: 'tasks', action: 'delete', description: 'Delete tasks' },
  { id: 'tasks:execute', key: 'tasks:execute', resource: 'tasks', action: 'execute', description: 'Execute tasks' },
  { id: 'alerts:create', key: 'alerts:create', resource: 'alerts', action: 'create', description: 'Create alert rules' },
  { id: 'alerts:read', key: 'alerts:read', resource: 'alerts', action: 'read', description: 'View alerts' },
  { id: 'alerts:update', key: 'alerts:update', resource: 'alerts', action: 'update', description: 'Update alert rules' },
  { id: 'alerts:delete', key: 'alerts:delete', resource: 'alerts', action: 'delete', description: 'Delete alert rules' },
  { id: 'users:create', key: 'users:create', resource: 'users', action: 'create', description: 'Create users' },
  { id: 'users:read', key: 'users:read', resource: 'users', action: 'read', description: 'View users' },
  { id: 'users:update', key: 'users:update', resource: 'users', action: 'update', description: 'Update users' },
  { id: 'users:delete', key: 'users:delete', resource: 'users', action: 'delete', description: 'Delete users' },
  { id: 'tenants:create', key: 'tenants:create', resource: 'tenants', action: 'create', description: 'Create tenants' },
  { id: 'tenants:read', key: 'tenants:read', resource: 'tenants', action: 'read', description: 'View tenants' },
  { id: 'tenants:update', key: 'tenants:update', resource: 'tenants', action: 'update', description: 'Update tenants' },
  { id: 'tenants:delete', key: 'tenants:delete', resource: 'tenants', action: 'delete', description: 'Delete tenants' },
  { id: 'agent:create', key: 'agent:create', resource: 'agent', action: 'create', description: 'Create agent sessions' },
  { id: 'agent:read', key: 'agent:read', resource: 'agent', action: 'read', description: 'View agent data' },
  { id: 'agent:update', key: 'agent:update', resource: 'agent', action: 'update', description: 'Update agent config' },
  { id: 'agent:execute', key: 'agent:execute', resource: 'agent', action: 'execute', description: 'Execute agent tasks' },
  { id: 'credentials:create', key: 'credentials:create', resource: 'credentials', action: 'create', description: 'Create credentials' },
  { id: 'credentials:read', key: 'credentials:read', resource: 'credentials', action: 'read', description: 'View credentials' },
  { id: 'credentials:update', key: 'credentials:update', resource: 'credentials', action: 'update', description: 'Update credentials' },
  { id: 'credentials:delete', key: 'credentials:delete', resource: 'credentials', action: 'delete', description: 'Delete credentials' },
  { id: 'settings:read', key: 'settings:read', resource: 'settings', action: 'read', description: 'View settings' },
  { id: 'settings:update', key: 'settings:update', resource: 'settings', action: 'update', description: 'Update settings' },
];

@Controller('api/v1/auth/permissions')
@UseGuards(RolesGuard)
@Roles('admin', 'platform_admin', 'platform_super_admin')
export class PermissionController {
  constructor(
    @InjectRepository(Role)
    private readonly roleRepository: Repository<Role>,
  ) {}

  @Get()
  async listPermissions() {
    return { data: ALL_PERMISSIONS };
  }

  @Get('matrix')
  async getMatrix() {
    const roles = await this.roleRepository.find({ order: { createdAt: 'ASC' } });

    const rolesDto = roles.map((r) => ({
      id: r.id,
      name: r.name,
      isSystem: ['admin', 'operator', 'viewer'].includes(r.name),
    }));

    const matrix: { roleId: string; permissionId: string; granted: boolean }[] = [];

    for (const role of roles) {
      for (const perm of ALL_PERMISSIONS) {
        matrix.push({
          roleId: role.id,
          permissionId: perm.id,
          granted: role.permissions?.includes(perm.key) ?? false,
        });
      }
    }

    return {
      roles: rolesDto,
      permissions: ALL_PERMISSIONS,
      matrix,
    };
  }

  @Patch('matrix')
  async updateMatrix(
    @Body() body: { roleId: string; permissionId: string; grant: boolean },
  ) {
    const role = await this.roleRepository.findOne({ where: { id: body.roleId } });
    if (!role) return { success: false };

    if (body.grant) {
      if (!role.permissions.includes(body.permissionId)) {
        role.permissions = [...role.permissions, body.permissionId];
      }
    } else {
      role.permissions = role.permissions.filter((p) => p !== body.permissionId);
    }

    await this.roleRepository.save(role);
    return { success: true };
  }
}
