import { Injectable, Logger } from '@nestjs/common';
import { DataSource } from 'typeorm';

/**
 * EDR's load/unload facilities, mapped onto the yards that already represent them.
 *
 * The codes are historical and don't read like the facility names, so map by code
 * and never by label: Indode is `KALITY` ("Gelan Multi Purpose Port (Indode)") and
 * Sebeta is `LEGACY_DEST` ("Sebeta"). Creating fresh INDODE/SEBETA yards would
 * split data that existing routes and bookings already point at.
 *
 * Only Indode stores cargo, so it is the only facility with a warehouse — the rest
 * move cargo on and off the train, which is why they accrue no storage/demurrage.
 *
 * Negad is deliberately absent: there are two candidates (`NAGAD` "DCT/SGDT" in
 * Djibouti and `NEGAD_FY_BCC` in Ethiopia, currently inactive) and it is not yet
 * settled which is the intercity facility.
 */
const FACILITY_YARDS: Array<{
  code: string;
  facility: string;
  hasWarehouse: boolean;
  handlesContainer: boolean;
}> = [
  // Containers need a reach stacker or gantry — only these three are equipped.
  // Bulk needs far less, so every facility handles it.
  { code: 'KALITY', facility: 'Indode', hasWarehouse: true, handlesContainer: true },
  { code: 'MOJO', facility: 'Modjo', hasWarehouse: false, handlesContainer: true },
  { code: 'DIRE_DAWA', facility: 'Dire Dawa', hasWarehouse: false, handlesContainer: true },
  { code: 'LEGACY_DEST', facility: 'Sebeta', hasWarehouse: false, handlesContainer: false },
  { code: 'ADAMA', facility: 'Adama', hasWarehouse: false, handlesContainer: false },
];

@Injectable()
export class YardFacilitiesSeeder {
  private readonly logger = new Logger(YardFacilitiesSeeder.name);

  constructor(private readonly dataSource: DataSource) {}

  /**
   * Idempotent: flags existing yards and upserts their facility record. Creates no
   * yards — a missing code is logged and skipped rather than invented.
   */
  async run(): Promise<void> {
    for (const { code, facility, hasWarehouse, handlesContainer } of FACILITY_YARDS) {
      const [yard]: Array<{ id: string }> = await this.dataSource.query(
        `SELECT id FROM freight.yards WHERE code = $1 AND deleted_at IS NULL`,
        [code],
      );
      if (!yard) {
        this.logger.warn(`Yard ${code} (${facility}) not found — skipping facility flag`);
        continue;
      }

      await this.dataSource.query(
        `UPDATE freight.yards
            SET has_facility = true, updated_at = NOW()
          WHERE id = $1 AND has_facility = false`,
        [yard.id],
      );

      await this.dataSource.query(
        `INSERT INTO freight.yard_facilities
           (yard_id, has_warehouse, handles_container, handles_bulk, equipment_notes)
         VALUES ($1, $2, $3, true, $4)
         ON CONFLICT (yard_id) WHERE deleted_at IS NULL
         DO UPDATE SET has_warehouse     = EXCLUDED.has_warehouse,
                       handles_container = EXCLUDED.handles_container,
                       handles_bulk      = EXCLUDED.handles_bulk,
                       updated_at        = NOW()`,
        [yard.id, hasWarehouse, handlesContainer, `${facility} load/unload facility`],
      );
    }
    this.logger.log(
      `Yard facilities seeded: ${FACILITY_YARDS.map((f) => f.facility).join(', ')}`,
    );
  }
}
