import { MigrationInterface, QueryRunner, TableColumn } from "typeorm";

// RECONCILIACION. CreateTallerTables1738852000000 creo taller_ot_fotos sin la
// columna `orden` que la entidad (OtFoto.orden, default 0) y la demo real
// SI tienen, y con `descripcion` como TEXT en vez de VARCHAR(255) (entidad y
// demo coinciden en varchar(255)).
export class ReconcileOtFotos1770100000000 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    const table = await queryRunner.getTable("taller_ot_fotos");
    if (!table) return;

    if (!table.findColumnByName("orden")) {
      await queryRunner.addColumn(
        "taller_ot_fotos",
        new TableColumn({ name: "orden", type: "int", default: 0 }),
      );
    }

    const descripcion = table.findColumnByName("descripcion");
    if (descripcion && descripcion.type === "text") {
      // Achicar TEXT -> VARCHAR(255) puede truncar. Verificar ANTES de
      // intentar el ALTER, para fallar con un mensaje claro en vez de un
      // error de MySQL poco informativo (o, sin STRICT_TRANS_TABLES, un
      // truncamiento silencioso).
      const tooLong = await queryRunner.query(
        `SELECT id, CHAR_LENGTH(descripcion) as len
         FROM taller_ot_fotos
         WHERE descripcion IS NOT NULL AND CHAR_LENGTH(descripcion) > 255
         LIMIT 1`,
      );
      if (tooLong.length > 0) {
        throw new Error(
          "No se puede achicar taller_ot_fotos.descripcion a varchar(255): " +
            `la fila id=${tooLong[0].id} tiene ${tooLong[0].len} caracteres. ` +
            "Decidir a mano (recortar el dato o mantener text en este tenant) antes de reintentar.",
        );
      }

      await queryRunner.query(
        "ALTER TABLE taller_ot_fotos MODIFY COLUMN descripcion varchar(255) NULL",
      );
    }
  }

  // Revertir descripcion varchar(255)->text SIEMPRE es seguro (ensanchar
  // nunca pierde datos). Revertir `orden` es DISTINTO: implica DROPear la
  // columna, y si algun tenant ya la uso (orden != 0 en alguna fila), eso
  // es dato real que se perderia. Se verifica ANTES de tocar nada — ABORTA
  // en vez de borrar en silencio.
  public async down(queryRunner: QueryRunner): Promise<void> {
    const table = await queryRunner.getTable("taller_ot_fotos");
    if (!table) return;

    const descripcion = table.findColumnByName("descripcion");
    if (descripcion && descripcion.type === "varchar") {
      await queryRunner.query(
        "ALTER TABLE taller_ot_fotos MODIFY COLUMN descripcion text NULL",
      );
    }

    if (table.findColumnByName("orden")) {
      const usada = await queryRunner.query(
        "SELECT COUNT(*) as c FROM taller_ot_fotos WHERE orden != 0",
      );
      if (Number(usada[0].c) > 0) {
        throw new Error(
          `No se puede revertir ReconcileOtFotos1770100000000: ${usada[0].c} fila(s) ` +
            "tienen orden!=0 — revertir borraria ese dato real (la columna se DROPea). ABORTA.",
        );
      }
      await queryRunner.dropColumn("taller_ot_fotos", "orden");
    }
  }
}
