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

import { Booking } from '../modules/bookings/entities/booking.entity';
import { Locomotive } from '../modules/locomotives/entities/locomotive.entity';
import { TrainSchedule } from '../modules/train-schedules/entities/train-schedule.entity';
import { TrainScheduleBooking } from '../modules/train-schedules/entities/train-schedule-booking.entity';
import { TrainSet } from '../modules/train-sets/entities/train-set.entity';

/**
 * Seeds two ARRIVED train schedules so the Import Arrive Queue (Batch 7) is demonstrable:
 *  - SEED-IMP-TRAIN-01: DJIB_PORT → MOJO (IMPORT) linked to booking SEED-IMP-001  → SHOWS
 *  - SEED-EXP-TRAIN-01: MOJO → DJIB_PORT (EXPORT) linked to booking SEED-EXP-001  → must NOT show
 *
 * Read-only train-schedule SERVICE logic is untouched; this only inserts fixture rows.
 * Idempotent: guards on the import train number.
 */
@Injectable()
export class Batch7TestDataSeeder {
  private readonly logger = new Logger(Batch7TestDataSeeder.name);

  constructor(private readonly dataSource: DataSource) {}

  async run(): Promise<void> {
    const scheduleRepo = this.dataSource.getRepository(TrainSchedule);

    const existing = await scheduleRepo.findOne({ where: { trainNumber: 'SEED-IMP-TRAIN-01' } });
    if (existing) {
      this.logger.log('Batch 7 test data already seeded, skipping');
      return;
    }

    try {
      const bookingRepo = this.dataSource.getRepository(Booking);
      const locoRepo = this.dataSource.getRepository(Locomotive);
      const trainSetRepo = this.dataSource.getRepository(TrainSet);
      const scheduleBookingRepo = this.dataSource.getRepository(TrainScheduleBooking);

      const importBooking = await bookingRepo.findOne({ where: { reference: 'SEED-IMP-001' } });
      const exportBooking = await bookingRepo.findOne({ where: { reference: 'SEED-EXP-001' } });
      if (!importBooking) {
        this.logger.warn('SEED-IMP-001 booking not found; skipping Batch 7 seed');
        return;
      }

      // One shared locomotive is fine — train_set.locomotive_id is not unique.
      const loco =
        (await locoRepo.findOne({ where: { code: 'SEED-LOCO-01' } })) ??
        (await locoRepo.save(
          locoRepo.create({ code: 'SEED-LOCO-01', name: 'Seed Locomotive', maxPullWeightTons: 4000 }),
        ));

      const now = new Date();
      const arrival = new Date(now.getTime() - 3600 * 1000);
      const departure = new Date(now.getTime() - 6 * 3600 * 1000);

      const makeArrivedTrain = async (
        trainNumber: string,
        booking: Booking,
      ): Promise<void> => {
        const trainSet = await trainSetRepo.save(
          trainSetRepo.create({
            locomotiveId: loco.id,
            totalWeightTons: 500,
            totalLengthMeters: 300,
            wagonCount: 10,
            status: 'COMPLETED',
          }),
        );

        const schedule = await scheduleRepo.save(
          scheduleRepo.create({
            trainSetId: trainSet.id,
            originStationId: booking.originYardId,
            destinationStationId: booking.destinationYardId,
            scheduledDepartureDate: departure,
            scheduledArrivalDate: arrival,
            actualArrivalAt: arrival,
            status: 'ARRIVED' as TrainSchedule['status'],
            trainNumber,
          }),
        );

        await scheduleBookingRepo.save(
          scheduleBookingRepo.create({ trainScheduleId: schedule.id, bookingId: booking.id }),
        );

        this.logger.log(`Seeded arrived train ${trainNumber} → booking ${booking.reference}`);
      };

      await makeArrivedTrain('SEED-IMP-TRAIN-01', importBooking);
      if (exportBooking) {
        await makeArrivedTrain('SEED-EXP-TRAIN-01', exportBooking);
      }

      this.logger.log('✅ Batch 7 arrive-queue test data seeded successfully');
    } catch (error) {
      this.logger.error(
        `Batch7TestDataSeeder failed: ${error instanceof Error ? error.message : String(error)}`,
      );
    }
  }
}
