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

export class CreateTallerTables1738852000000 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    // ========== TIPOS DE VEHICULO ==========
    await queryRunner.createTable(
      new Table({
        name: "taller_tipos_vehiculo",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          { name: "nombre", type: "varchar", length: "100" },
          { name: "descripcion", type: "text", isNullable: true },
          {
            name: "plantilla_danos",
            type: "varchar",
            length: "50",
            default: "'carro'",
          },
          { name: "activo", type: "boolean", default: true },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
          {
            name: "updated_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
            onUpdate: "CURRENT_TIMESTAMP",
          },
          { name: "created_by", type: "int", isNullable: true },
          { name: "updated_by", type: "int", isNullable: true },
        ],
      }),
      true,
    );

    await queryRunner.createIndex(
      "taller_tipos_vehiculo",
      new TableIndex({
        name: "IDX_tipo_vehiculo_activo",
        columnNames: ["activo"],
      }),
    );

    // ========== COSAS QUE TRAE ==========
    await queryRunner.createTable(
      new Table({
        name: "taller_cosas_trae",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          { name: "nombre", type: "varchar", length: "150" },
          { name: "descripcion", type: "text", isNullable: true },
          { name: "activo", type: "boolean", default: true },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
          {
            name: "updated_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
            onUpdate: "CURRENT_TIMESTAMP",
          },
        ],
      }),
      true,
    );

    await queryRunner.createIndex(
      "taller_cosas_trae",
      new TableIndex({ name: "IDX_cosa_trae_activo", columnNames: ["activo"] }),
    );

    // ========== TIPOS DE DAÑO ==========
    await queryRunner.createTable(
      new Table({
        name: "taller_tipos_dano",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          { name: "nombre", type: "varchar", length: "100" },
          { name: "descripcion", type: "text", isNullable: true },
          { name: "icono", type: "varchar", length: "50", isNullable: true },
          { name: "color", type: "varchar", length: "20", isNullable: true },
          { name: "activo", type: "boolean", default: true },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
          {
            name: "updated_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
            onUpdate: "CURRENT_TIMESTAMP",
          },
        ],
      }),
      true,
    );

    await queryRunner.createIndex(
      "taller_tipos_dano",
      new TableIndex({ name: "IDX_tipo_dano_activo", columnNames: ["activo"] }),
    );

    // ========== VEHICULOS ==========
    await queryRunner.createTable(
      new Table({
        name: "taller_vehiculos",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          { name: "placa", type: "varchar", length: "20", isUnique: true },
          { name: "marca", type: "varchar", length: "100", isNullable: true },
          { name: "modelo", type: "varchar", length: "100", isNullable: true },
          { name: "anio", type: "int", isNullable: true },
          { name: "motor", type: "varchar", length: "100", isNullable: true },
          {
            name: "cilindraje",
            type: "varchar",
            length: "50",
            isNullable: true,
          },
          { name: "color", type: "varchar", length: "50", isNullable: true },
          { name: "tipo_vehiculo_id", type: "int", isNullable: true },
          {
            name: "cliente_id",
            type: "varchar",
            length: "24",
            isNullable: true,
          },
          { name: "notas", type: "text", isNullable: true },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
          {
            name: "updated_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
            onUpdate: "CURRENT_TIMESTAMP",
          },
          { name: "created_by", type: "int", isNullable: true },
          { name: "updated_by", type: "int", isNullable: true },
        ],
      }),
      true,
    );

    await queryRunner.createIndex(
      "taller_vehiculos",
      new TableIndex({ name: "IDX_vehiculo_placa", columnNames: ["placa"] }),
    );
    await queryRunner.createIndex(
      "taller_vehiculos",
      new TableIndex({
        name: "IDX_vehiculo_cliente",
        columnNames: ["cliente_id"],
      }),
    );

    await queryRunner.createForeignKey(
      "taller_vehiculos",
      new TableForeignKey({
        columnNames: ["tipo_vehiculo_id"],
        referencedTableName: "taller_tipos_vehiculo",
        referencedColumnNames: ["id"],
        onDelete: "SET NULL",
      }),
    );

    // ========== ORDENES DE TRABAJO ==========
    await queryRunner.createTable(
      new Table({
        name: "taller_ordenes_trabajo",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          { name: "numero_ot", type: "varchar", length: "20", isUnique: true },
          { name: "cliente_tarjeta", type: "varchar", length: "24" },
          { name: "vehiculo_id", type: "int" },
          { name: "fecha_entrada", type: "datetime" },
          { name: "fecha_salida", type: "datetime", isNullable: true },
          { name: "km", type: "int" },
          { name: "nivel_gasolina", type: "int", default: 0 },
          { name: "requerimiento_cliente", type: "text", isNullable: true },
          { name: "observaciones", type: "text", isNullable: true },
          {
            name: "estado",
            type: "enum",
            enum: [
              "borrador",
              "en_proceso",
              "cotizada",
              "aprobada",
              "terminada",
              "entregada",
            ],
            default: "'borrador'",
          },
          {
            name: "pdf_escaner",
            type: "varchar",
            length: "500",
            isNullable: true,
          },
          { name: "local_id", type: "varchar", length: "36", isNullable: true },
          { name: "version", type: "int", default: 1 },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
          {
            name: "updated_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
            onUpdate: "CURRENT_TIMESTAMP",
          },
          { name: "created_by", type: "int", isNullable: true },
          { name: "updated_by", type: "int", isNullable: true },
        ],
      }),
      true,
    );

    await queryRunner.createIndex(
      "taller_ordenes_trabajo",
      new TableIndex({ name: "IDX_ot_numero", columnNames: ["numero_ot"] }),
    );
    await queryRunner.createIndex(
      "taller_ordenes_trabajo",
      new TableIndex({
        name: "IDX_ot_cliente",
        columnNames: ["cliente_tarjeta"],
      }),
    );
    await queryRunner.createIndex(
      "taller_ordenes_trabajo",
      new TableIndex({ name: "IDX_ot_estado", columnNames: ["estado"] }),
    );
    await queryRunner.createIndex(
      "taller_ordenes_trabajo",
      new TableIndex({
        name: "IDX_ot_fecha_entrada",
        columnNames: ["fecha_entrada"],
      }),
    );
    await queryRunner.createIndex(
      "taller_ordenes_trabajo",
      new TableIndex({
        name: "IDX_ot_fecha_salida",
        columnNames: ["fecha_salida"],
      }),
    );
    await queryRunner.createIndex(
      "taller_ordenes_trabajo",
      new TableIndex({ name: "IDX_ot_local_id", columnNames: ["local_id"] }),
    );

    await queryRunner.createForeignKey(
      "taller_ordenes_trabajo",
      new TableForeignKey({
        columnNames: ["vehiculo_id"],
        referencedTableName: "taller_vehiculos",
        referencedColumnNames: ["id"],
        onDelete: "RESTRICT",
      }),
    );

    // ========== OT - COSAS QUE TRAE (relación) ==========
    await queryRunner.createTable(
      new Table({
        name: "taller_ot_cosas_trae",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          { name: "ot_id", type: "int" },
          { name: "cosa_trae_id", type: "int" },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
        ],
      }),
      true,
    );

    await queryRunner.createForeignKey(
      "taller_ot_cosas_trae",
      new TableForeignKey({
        columnNames: ["ot_id"],
        referencedTableName: "taller_ordenes_trabajo",
        referencedColumnNames: ["id"],
        onDelete: "CASCADE",
      }),
    );

    await queryRunner.createForeignKey(
      "taller_ot_cosas_trae",
      new TableForeignKey({
        columnNames: ["cosa_trae_id"],
        referencedTableName: "taller_cosas_trae",
        referencedColumnNames: ["id"],
        onDelete: "CASCADE",
      }),
    );

    // ========== OT - DAÑOS ==========
    await queryRunner.createTable(
      new Table({
        name: "taller_ot_danos",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          { name: "ot_id", type: "int" },
          { name: "tipo_dano_id", type: "int" },
          { name: "zona", type: "varchar", length: "100", isNullable: true },
          { name: "descripcion", type: "text", isNullable: true },
          {
            name: "posicion_x",
            type: "decimal",
            precision: 5,
            scale: 2,
            isNullable: true,
          },
          {
            name: "posicion_y",
            type: "decimal",
            precision: 5,
            scale: 2,
            isNullable: true,
          },
          {
            name: "foto_url",
            type: "varchar",
            length: "500",
            isNullable: true,
          },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
        ],
      }),
      true,
    );

    await queryRunner.createForeignKey(
      "taller_ot_danos",
      new TableForeignKey({
        columnNames: ["ot_id"],
        referencedTableName: "taller_ordenes_trabajo",
        referencedColumnNames: ["id"],
        onDelete: "CASCADE",
      }),
    );

    await queryRunner.createForeignKey(
      "taller_ot_danos",
      new TableForeignKey({
        columnNames: ["tipo_dano_id"],
        referencedTableName: "taller_tipos_dano",
        referencedColumnNames: ["id"],
        onDelete: "RESTRICT",
      }),
    );

    // ========== OT - FOTOS ==========
    await queryRunner.createTable(
      new Table({
        name: "taller_ot_fotos",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          { name: "ot_id", type: "int" },
          {
            name: "tipo",
            type: "enum",
            enum: ["general", "dano", "documento"],
            default: "'general'",
          },
          { name: "url", type: "varchar", length: "500" },
          { name: "descripcion", type: "text", isNullable: true },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
        ],
      }),
      true,
    );

    await queryRunner.createForeignKey(
      "taller_ot_fotos",
      new TableForeignKey({
        columnNames: ["ot_id"],
        referencedTableName: "taller_ordenes_trabajo",
        referencedColumnNames: ["id"],
        onDelete: "CASCADE",
      }),
    );

    // ========== OT - FIRMAS ==========
    await queryRunner.createTable(
      new Table({
        name: "taller_ot_firmas",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          { name: "ot_id", type: "int", isUnique: true },
          {
            name: "firma_cliente",
            type: "varchar",
            length: "500",
            isNullable: true,
          },
          { name: "fecha_firma_cliente", type: "datetime", isNullable: true },
          {
            name: "nombre_firma_cliente",
            type: "varchar",
            length: "200",
            isNullable: true,
          },
          {
            name: "firma_recepcion",
            type: "varchar",
            length: "500",
            isNullable: true,
          },
          { name: "fecha_firma_recepcion", type: "datetime", isNullable: true },
          {
            name: "nombre_firma_recepcion",
            type: "varchar",
            length: "200",
            isNullable: true,
          },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
          {
            name: "updated_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
            onUpdate: "CURRENT_TIMESTAMP",
          },
        ],
      }),
      true,
    );

    await queryRunner.createForeignKey(
      "taller_ot_firmas",
      new TableForeignKey({
        columnNames: ["ot_id"],
        referencedTableName: "taller_ordenes_trabajo",
        referencedColumnNames: ["id"],
        onDelete: "CASCADE",
      }),
    );

    // ========== COTIZACIONES ==========
    await queryRunner.createTable(
      new Table({
        name: "taller_cotizaciones",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          { name: "ot_id", type: "int" },
          {
            name: "numero_cotizacion",
            type: "varchar",
            length: "20",
            isNullable: true,
          },
          {
            name: "subtotal",
            type: "decimal",
            precision: 12,
            scale: 2,
            default: 0,
          },
          { name: "iva", type: "decimal", precision: 12, scale: 2, default: 0 },
          {
            name: "total",
            type: "decimal",
            precision: 12,
            scale: 2,
            default: 0,
          },
          {
            name: "estado",
            type: "enum",
            enum: ["borrador", "enviada", "aprobada", "rechazada"],
            default: "'borrador'",
          },
          { name: "fecha_aprobacion", type: "datetime", isNullable: true },
          {
            name: "aprobado_por",
            type: "varchar",
            length: "255",
            isNullable: true,
          },
          { name: "notas", type: "text", isNullable: true },
          { name: "local_id", type: "varchar", length: "36", isNullable: true },
          { name: "version", type: "int", default: 1 },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
          {
            name: "updated_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
            onUpdate: "CURRENT_TIMESTAMP",
          },
        ],
      }),
      true,
    );

    await queryRunner.createIndex(
      "taller_cotizaciones",
      new TableIndex({ name: "IDX_cotizacion_ot", columnNames: ["ot_id"] }),
    );
    await queryRunner.createIndex(
      "taller_cotizaciones",
      new TableIndex({
        name: "IDX_cotizacion_estado",
        columnNames: ["estado"],
      }),
    );

    await queryRunner.createForeignKey(
      "taller_cotizaciones",
      new TableForeignKey({
        columnNames: ["ot_id"],
        referencedTableName: "taller_ordenes_trabajo",
        referencedColumnNames: ["id"],
        onDelete: "CASCADE",
      }),
    );

    // ========== COTIZACION - LINEAS ==========
    await queryRunner.createTable(
      new Table({
        name: "taller_cotizacion_lineas",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          { name: "cotizacion_id", type: "int" },
          { name: "plu", type: "varchar", length: "24" },
          { name: "descripcion", type: "varchar", length: "255" },
          { name: "precio_unitario", type: "decimal", precision: 12, scale: 2 },
          {
            name: "cantidad",
            type: "decimal",
            precision: 10,
            scale: 3,
            default: 1,
          },
          { name: "subtotal", type: "decimal", precision: 12, scale: 2 },
          { name: "iva", type: "decimal", precision: 12, scale: 2, default: 0 },
          { name: "total", type: "decimal", precision: 12, scale: 2 },
          { name: "es_servicio", type: "boolean", default: false },
          { name: "orden", type: "int", default: 0 },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
        ],
      }),
      true,
    );

    await queryRunner.createIndex(
      "taller_cotizacion_lineas",
      new TableIndex({
        name: "IDX_linea_cotizacion",
        columnNames: ["cotizacion_id"],
      }),
    );

    await queryRunner.createForeignKey(
      "taller_cotizacion_lineas",
      new TableForeignKey({
        columnNames: ["cotizacion_id"],
        referencedTableName: "taller_cotizaciones",
        referencedColumnNames: ["id"],
        onDelete: "CASCADE",
      }),
    );

    // ========== SYNC EVENTS ==========
    await queryRunner.createTable(
      new Table({
        name: "taller_sync_events",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          { name: "event_id", type: "varchar", length: "36", isUnique: true },
          { name: "event_type", type: "varchar", length: "50" },
          { name: "entity_type", type: "varchar", length: "50" },
          { name: "local_id", type: "varchar", length: "36" },
          { name: "payload", type: "json" },
          {
            name: "status",
            type: "enum",
            enum: ["pending", "processing", "completed", "failed"],
            default: "'pending'",
          },
          { name: "error_message", type: "text", isNullable: true },
          { name: "retries", type: "int", default: 0 },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
          { name: "processed_at", type: "timestamp", isNullable: true },
        ],
      }),
      true,
    );

    await queryRunner.createIndex(
      "taller_sync_events",
      new TableIndex({ name: "IDX_sync_event_id", columnNames: ["event_id"] }),
    );
    await queryRunner.createIndex(
      "taller_sync_events",
      new TableIndex({ name: "IDX_sync_status", columnNames: ["status"] }),
    );
    await queryRunner.createIndex(
      "taller_sync_events",
      new TableIndex({ name: "IDX_sync_created", columnNames: ["created_at"] }),
    );

    console.log("✅ Todas las tablas del taller creadas");
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.dropTable("taller_sync_events", true);
    await queryRunner.dropTable("taller_cotizacion_lineas", true);
    await queryRunner.dropTable("taller_cotizaciones", true);
    await queryRunner.dropTable("taller_ot_firmas", true);
    await queryRunner.dropTable("taller_ot_fotos", true);
    await queryRunner.dropTable("taller_ot_danos", true);
    await queryRunner.dropTable("taller_ot_cosas_trae", true);
    await queryRunner.dropTable("taller_ordenes_trabajo", true);
    await queryRunner.dropTable("taller_vehiculos", true);
    await queryRunner.dropTable("taller_tipos_dano", true);
    await queryRunner.dropTable("taller_cosas_trae", true);
    await queryRunner.dropTable("taller_tipos_vehiculo", true);

    console.log("✅ Todas las tablas del taller eliminadas");
  }
}
