import 'reflect-metadata';
import { config } from 'dotenv';
import { resolve } from 'path';
import { NestFactory } from '@nestjs/core';
import { DataSource } from 'typeorm';

config({ path: resolve(__dirname, '../../.env') });
process.env.TYPEORM_LOGGING = 'false';

import { AppModule } from '../app.module';
import { deriveTradeDirection } from '../common/derive-trade-direction.util';
import { WarehouseInventoryService } from '../modules/warehouses/warehouse-inventory.service';

async function main() {
  const app = await NestFactory.createApplicationContext(AppModule, {
    logger: ['error', 'warn'],
  });

  try {
    const dataSource = app.get(DataSource);
    const inventory = app.get(WarehouseInventoryService);

    const schedules: {
      id: string;
      trainNumber: string | null;
      originCountry: string | null;
      destinationCountry: string | null;
    }[] = await dataSource.query(
      `SELECT ts.id,
              ts.train_number AS "trainNumber",
              oy.country AS "originCountry",
              dy.country AS "destinationCountry"
         FROM freight.train_schedules ts
         LEFT JOIN freight.yards oy ON oy.id = ts.origin_station_id
         LEFT JOIN freight.yards dy ON dy.id = ts.destination_station_id
        WHERE ts.status = 'ARRIVED'
          AND ts.deleted_at IS NULL
        ORDER BY COALESCE(ts.actual_arrival_at, ts.scheduled_arrival_date) DESC NULLS LAST,
                 ts.created_at DESC`,
    );

    const importSchedules = schedules.filter(
      (schedule) =>
        deriveTradeDirection(
          { country: schedule.originCountry },
          { country: schedule.destinationCountry },
        ) === 'IMPORT',
    );

    if (importSchedules.length === 0) {
      console.log('No ARRIVED import trains found.');
      return;
    }

    for (const schedule of importSchedules) {
      const result = await inventory.autoUnloadArrivedBookings(
        schedule.id,
        'Demo Auto Unload',
      );
      console.log(
        `${schedule.trainNumber ?? schedule.id}: ${result.unloadedCount} unloaded, ${result.skippedCount} skipped, ${result.failedCount} failed`,
      );
      for (const item of result.results) {
        console.log(`  - ${item.bookingId}: ${item.status}${item.reason ? ` (${item.reason})` : ''}`);
      }
    }

    const queueRows = await inventory.importUnloadedQueue();
    console.log(`Import Unloaded Queue rows now visible: ${queueRows.length}`);
    const byStatus = queueRows.reduce<Record<string, number>>((acc, row) => {
      acc[row.currentStatus] = (acc[row.currentStatus] ?? 0) + 1;
      return acc;
    }, {});
    for (const [status, count] of Object.entries(byStatus)) {
      console.log(`  ${status}: ${count}`);
    }
  } finally {
    await app.close();
  }
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
