import { MigrationInterface, QueryRunner, Table, TableForeignKey } from "typeorm";

export class CreateControlPlaneTables1761900000000 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.createTable(
      new Table({
        name: "tenants",
        columns: [
          { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" },
          { name: "codigo", type: "varchar", length: "64", isUnique: true },
          { name: "nombre", type: "varchar", length: "255" },
          { name: "estado", type: "enum", enum: ["onboarding", "activo", "suspendido"], default: "'onboarding'" },
          { name: "entorno", type: "enum", enum: ["demo", "produccion"] },
          { name: "db_host", type: "varchar", length: "255" },
          { name: "db_port", type: "int", default: 3306 },
          { name: "db_name", type: "varchar", length: "128" },
          { name: "db_user", type: "varchar", length: "128" },
          { name: "db_password_encrypted", type: "text" },
          { name: "schema_version_cache", type: "varchar", length: "255", isNullable: true },
          { name: "schema_version_cache_at", type: "datetime", isNullable: true },
          { name: "created_at", type: "timestamp", default: "CURRENT_TIMESTAMP" },
          { name: "updated_at", type: "timestamp", default: "CURRENT_TIMESTAMP", onUpdate: "CURRENT_TIMESTAMP" },
        ],
      }),
      true,
    );

    await queryRunner.createTable(
      new Table({
        name: "identidades",
        columns: [
          { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" },
          { name: "email", type: "varchar", length: "255", isUnique: true },
          { name: "nombre", type: "varchar", length: "255" },
          { name: "password_hash", type: "varchar", length: "255" },
          { name: "estado", type: "enum", enum: ["activa", "suspendida"], default: "'activa'" },
          { name: "rol_plataforma", type: "enum", enum: ["ninguno", "admin_plataforma"], default: "'ninguno'" },
          { name: "created_at", type: "timestamp", default: "CURRENT_TIMESTAMP" },
          { name: "updated_at", type: "timestamp", default: "CURRENT_TIMESTAMP", onUpdate: "CURRENT_TIMESTAMP" },
        ],
      }),
      true,
    );

    await queryRunner.createTable(
      new Table({
        name: "tenant_membership",
        columns: [
          { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" },
          { name: "identidad_id", type: "int" },
          { name: "tenant_id", type: "int" },
          { name: "usuario_local_id", type: "int" },
          { name: "estado", type: "enum", enum: ["activa", "revocada"], default: "'activa'" },
          { name: "otorgado_por_identidad_id", type: "int" },
          { name: "otorgado_en", type: "timestamp", default: "CURRENT_TIMESTAMP" },
          { name: "revocado_en", type: "datetime", isNullable: true },
        ],
        uniques: [{ name: "UQ_tenant_membership_identidad_tenant", columnNames: ["identidad_id", "tenant_id"] }],
      }),
      true,
    );

    await queryRunner.createForeignKeys("tenant_membership", [
      new TableForeignKey({
        columnNames: ["identidad_id"],
        referencedTableName: "identidades",
        referencedColumnNames: ["id"],
        onDelete: "CASCADE",
      }),
      new TableForeignKey({
        columnNames: ["tenant_id"],
        referencedTableName: "tenants",
        referencedColumnNames: ["id"],
        onDelete: "CASCADE",
      }),
    ]);

    await queryRunner.createTable(
      new Table({
        name: "tenant_config",
        columns: [
          { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" },
          { name: "tenant_id", type: "int", isUnique: true },
          { name: "whatsapp_phone_number_id", type: "varchar", length: "64", isNullable: true },
          { name: "whatsapp_access_token_encrypted", type: "text", isNullable: true },
          { name: "whatsapp_template_language", type: "varchar", length: "16", isNullable: true },
          { name: "whatsapp_template_cotizacion", type: "varchar", length: "128", isNullable: true },
          { name: "whatsapp_template_estado", type: "varchar", length: "128", isNullable: true },
          { name: "whatsapp_default_country_code", type: "varchar", length: "8", isNullable: true },
        ],
      }),
      true,
    );

    await queryRunner.createForeignKey(
      "tenant_config",
      new TableForeignKey({
        columnNames: ["tenant_id"],
        referencedTableName: "tenants",
        referencedColumnNames: ["id"],
        onDelete: "CASCADE",
      }),
    );

    await queryRunner.createTable(
      new Table({
        name: "auditoria",
        columns: [
          { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" },
          { name: "identidad_id", type: "int" },
          { name: "tenant_id", type: "int", isNullable: true },
          { name: "via", type: "enum", enum: ["tenant", "plataforma"] },
          { name: "accion", type: "varchar", length: "128" },
          { name: "detalle", type: "json", isNullable: true },
          { name: "ip", type: "varchar", length: "64", isNullable: true },
          { name: "created_at", type: "timestamp", default: "CURRENT_TIMESTAMP" },
        ],
        indices: [
          { name: "IDX_auditoria_identidad", columnNames: ["identidad_id"] },
          { name: "IDX_auditoria_tenant", columnNames: ["tenant_id"] },
          { name: "IDX_auditoria_accion", columnNames: ["accion"] },
        ],
      }),
      true,
    );

    await queryRunner.createTable(
      new Table({
        name: "migration_jobs",
        columns: [
          { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" },
          { name: "tenant_id", type: "int" },
          {
            name: "estado",
            type: "enum",
            enum: ["pendiente", "corriendo", "completo", "incompleto", "simulacion"],
            default: "'pendiente'",
          },
          { name: "fallo_en_migracion", type: "varchar", length: "255", isNullable: true },
          { name: "error_mensaje", type: "text", isNullable: true },
          { name: "iniciado_por_identidad_id", type: "int" },
          { name: "es_simulacion", type: "boolean", default: false },
          { name: "created_at", type: "timestamp", default: "CURRENT_TIMESTAMP" },
          { name: "updated_at", type: "timestamp", default: "CURRENT_TIMESTAMP", onUpdate: "CURRENT_TIMESTAMP" },
        ],
        indices: [{ name: "IDX_migration_jobs_tenant", columnNames: ["tenant_id"] }],
      }),
      true,
    );

    await queryRunner.createTable(
      new Table({
        name: "migration_job_steps",
        columns: [
          { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" },
          { name: "migration_job_id", type: "int" },
          { name: "migracion_nombre", type: "varchar", length: "255" },
          { name: "aplicado_en", type: "timestamp", default: "CURRENT_TIMESTAMP" },
        ],
        indices: [{ name: "IDX_migration_job_steps_job", columnNames: ["migration_job_id"] }],
      }),
      true,
    );

    await queryRunner.createForeignKey(
      "migration_job_steps",
      new TableForeignKey({
        columnNames: ["migration_job_id"],
        referencedTableName: "migration_jobs",
        referencedColumnNames: ["id"],
        onDelete: "CASCADE",
      }),
    );

    await queryRunner.createTable(
      new Table({
        name: "schema_deviations",
        columns: [
          { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" },
          { name: "tenant_id", type: "int" },
          { name: "tabla", type: "varchar", length: "128" },
          { name: "columna", type: "varchar", length: "128" },
          { name: "severidad", type: "enum", enum: ["informativo", "advertencia", "grave"] },
          { name: "tipo_esperado", type: "varchar", length: "128" },
          { name: "tipo_real", type: "varchar", length: "128" },
          { name: "alter_sugerido", type: "text" },
          { name: "omitido_por_identidad_id", type: "int" },
          { name: "created_at", type: "timestamp", default: "CURRENT_TIMESTAMP" },
        ],
        indices: [{ name: "IDX_schema_deviations_tenant", columnNames: ["tenant_id"] }],
      }),
      true,
    );

    await queryRunner.createTable(
      new Table({
        name: "tenant_migration_locks",
        columns: [
          { name: "tenant_id", type: "int", isPrimary: true },
          { name: "migration_job_id", type: "int" },
          { name: "expira_en", type: "datetime" },
        ],
      }),
      true,
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.dropTable("tenant_migration_locks", true);
    await queryRunner.dropTable("schema_deviations", true);
    await queryRunner.dropTable("migration_job_steps", true);
    await queryRunner.dropTable("migration_jobs", true);
    await queryRunner.dropTable("auditoria", true);
    await queryRunner.dropTable("tenant_config", true);
    await queryRunner.dropTable("tenant_membership", true);
    await queryRunner.dropTable("identidades", true);
    await queryRunner.dropTable("tenants", true);
  }
}
