import { MigrationInterface, QueryRunner } from "typeorm";

// auth.controller.ts dejo de usar el chequeo de rol crudo (ensureCanManageUsers,
// admin/super_admin siempre pasa) para gestionar usuarios/tiendas y ahora exige
// el permiso granular "usuarios":"write" via PermissionGuard -- ver commit que
// acompaña esta migracion. Ese permiso YA estaba definido en
// DEFAULT_PERMISSIONS_BY_ROLE (default-permissions.ts) como "read" para ADMIN
// desde antes (no lo tocamos), pero nunca se habia enforced en estas rutas.
//
// Sin esta migracion, todo admin ya existente (permisos NULL o sin la clave
// "usuarios" en su JSON) pasaria de poder crear/editar usuarios y tiendas a
// solo poder listarlos, de un dia para otro y en todos los tenants -- nadie
// pidio ese endurecimiento, es un efecto secundario de dejar de hardcodear.
// Por eso se hace backfill explicito de "usuarios":"write" para admins
// existentes: preserva el comportamiento de hoy. El default mas restrictivo
// ("read") solo aplica de ahi en adelante a admins nuevos, o a los que un
// super_admin decida bajarles el permiso desde el editor de /dashboard/usuarios.
//
// Puramente aditivo y acotado a rol=admin: no toca super_admin (bypassea el
// guard igual) ni el resto de roles (ya defaults en "none" para "usuarios",
// sin cambio de comportamiento).
export class BackfillAdminUsuariosWritePermission1780900000000
  implements MigrationInterface
{
  public async up(queryRunner: QueryRunner): Promise<void> {
    const table = await queryRunner.getTable("taller_usuarios");
    if (!table) return; // tenant sin esta tabla (no deberia pasar), defensivo

    await queryRunner.query(
      `UPDATE taller_usuarios
       SET permisos = JSON_SET(COALESCE(permisos, JSON_OBJECT()), '$.usuarios', 'write')
       WHERE rol = 'admin'
         AND (permisos IS NULL OR JSON_EXTRACT(permisos, '$.usuarios') IS NULL)`,
    );
  }

  // Reversion best-effort: solo deshace la clave "usuarios" que esta misma
  // migracion pudo haber puesto (rol=admin, valor exactamente 'write'). Si un
  // super_admin la volvio a tocar manualmente despues (p.ej. para bajarle el
  // permiso a un admin puntual y luego subirselo de nuevo a mano), este down
  // no puede distinguirlo de lo que puso la migracion -- mismo tipo de
  // limitacion que el resto de las migraciones "Reconcile*" de esta carpeta.
  public async down(queryRunner: QueryRunner): Promise<void> {
    const table = await queryRunner.getTable("taller_usuarios");
    if (!table) return;

    await queryRunner.query(
      `UPDATE taller_usuarios
       SET permisos = CASE
         WHEN JSON_LENGTH(permisos) <= 1 THEN NULL
         ELSE JSON_REMOVE(permisos, '$.usuarios')
       END
       WHERE rol = 'admin'
         AND JSON_UNQUOTE(JSON_EXTRACT(permisos, '$.usuarios')) = 'write'`,
    );
  }
}
