import { MigrationInterface, QueryRunner } from "typeorm";

/**
 * Repair for environments missing the GPS tracking tables.
 *
 * AddGpsTracking2000000000000 creates freight.gps_devices / gps_positions, but
 * some databases have it RECORDED in public.migrations without the tables ever
 * landing. TypeORM never re-runs a recorded migration, so those environments
 * stay broken through any number of restarts — the GT06 listener accepts tracker
 * packets on its TCP port regardless of schema state and fails per packet with
 * `relation "freight.gps_devices" does not exist`, dropping position fixes.
 *
 * This re-issues the same DDL under a new name so it is applied afresh. Every
 * statement is IF NOT EXISTS, so it is a no-op where the tables already exist
 * and safe on every environment.
 *
 * Kept byte-identical to the original DDL on purpose: this must converge on the
 * schema the entities expect, not a variant of it.
 */
export class RepairGpsTrackingTables2300000000000 implements MigrationInterface {
  name = "RepairGpsTrackingTables2300000000000";

  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`
      CREATE TABLE IF NOT EXISTS freight.gps_devices (
        id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
        imei varchar(20) NOT NULL UNIQUE,
        name varchar,
        vehicle_id uuid REFERENCES freight.vehicles(id),
        status varchar(16) NOT NULL DEFAULT 'REGISTERED',
        last_seen_at timestamptz,
        last_lat numeric(10,6),
        last_lng numeric(10,6),
        last_speed numeric(6,2),
        last_course int,
        last_fix_at timestamptz,
        voltage_level int,
        gsm_level int,
        created_at timestamptz NOT NULL DEFAULT now(),
        updated_at timestamptz NOT NULL DEFAULT now(),
        deleted_at timestamptz
      )
    `);
    await queryRunner.query(`
      CREATE INDEX IF NOT EXISTS "IDX_GPS_DEVICES_VEHICLE"
      ON freight.gps_devices (vehicle_id)
    `);

    await queryRunner.query(`
      CREATE TABLE IF NOT EXISTS freight.gps_positions (
        id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
        device_id uuid NOT NULL,
        imei varchar(20) NOT NULL,
        vehicle_id uuid,
        lat numeric(10,6) NOT NULL,
        lng numeric(10,6) NOT NULL,
        speed numeric(6,2) NOT NULL DEFAULT 0,
        course int NOT NULL DEFAULT 0,
        satellites int NOT NULL DEFAULT 0,
        positioned boolean NOT NULL DEFAULT false,
        gps_time timestamptz NOT NULL,
        alarm int NOT NULL DEFAULT 0,
        created_at timestamptz NOT NULL DEFAULT now(),
        updated_at timestamptz NOT NULL DEFAULT now(),
        deleted_at timestamptz
      )
    `);
    await queryRunner.query(`
      CREATE INDEX IF NOT EXISTS "IDX_GPS_POSITIONS_DEVICE_TIME"
      ON freight.gps_positions (device_id, gps_time)
    `);
    await queryRunner.query(`
      CREATE INDEX IF NOT EXISTS "IDX_GPS_POSITIONS_VEHICLE_TIME"
      ON freight.gps_positions (vehicle_id, gps_time)
    `);
  }

  public async down(): Promise<void> {
    // No-op: dropping the tables would discard tracker history on environments
    // where this migration was the one that created them. AddGpsTracking owns
    // the teardown.
  }
}
