import { PrismaClient } from '@prisma/client';
import * as bcrypt from 'bcrypt';

const prisma = new PrismaClient();

// ============================================================================
// SECTION 1: STATIONS (18 STATIONS)
// ============================================================================
async function seedStations() {
  console.log('📍 Seeding 18 stations...');
  
  const stations = [
    { code: 'SBT', name: 'Sebeta', city: 'Sebeta', countryCode: 'ET', lat: 8.9167, lng: 38.6167 },
    { code: 'LBU', name: 'Labu', city: 'Labu', countryCode: 'ET', lat: 8.8500, lng: 38.7000 },
    { code: 'IND', name: 'Indode', city: 'Indode', countryCode: 'ET', lat: 8.7800, lng: 38.8200 },
    { code: 'BSH', name: 'Bishoftu', city: 'Bishoftu', countryCode: 'ET', lat: 8.7500, lng: 38.9833 },
    { code: 'MJO', name: 'Mojo', city: 'Mojo', countryCode: 'ET', lat: 8.6000, lng: 39.1200 },
    { code: 'ADM', name: 'Adama', city: 'Adama', countryCode: 'ET', lat: 8.5400, lng: 39.2675 },
    { code: 'FTO', name: 'Feto', city: 'Feto', countryCode: 'ET', lat: 8.4500, lng: 39.4000 },
    { code: 'MTH', name: 'Metahara', city: 'Metahara', countryCode: 'ET', lat: 8.9000, lng: 39.9167 },
    { code: 'MSO', name: 'Mieso', city: 'Mieso', countryCode: 'ET', lat: 9.2400, lng: 40.7500 },
    { code: 'BKE', name: 'Bike', city: 'Bike', countryCode: 'ET', lat: 9.4200, lng: 41.2000 },
    { code: 'DDW', name: 'Diredawa', city: 'Diredawa', countryCode: 'ET', lat: 9.5931, lng: 41.8661 },
    { code: 'ARW', name: 'Arawa', city: 'Arawa', countryCode: 'ET', lat: 10.2000, lng: 42.1500 },
    { code: 'ADG', name: 'Adigala', city: 'Adigala', countryCode: 'ET', lat: 10.8500, lng: 42.4000 },
    { code: 'AYS', name: 'Aysha', city: 'Aysha', countryCode: 'ET', lat: 11.5500, lng: 42.7167 },
    { code: 'DWL', name: 'Dawanle', city: 'Dawanle', countryCode: 'DJ', lat: 11.4000, lng: 42.9500 },
    { code: 'ALI', name: 'Alisabieh', city: 'Alisabieh', countryCode: 'DJ', lat: 11.1667, lng: 42.7167 },
    { code: 'HOL', name: 'Holhol', city: 'Holhol', countryCode: 'DJ', lat: 11.3500, lng: 43.0500 },
    { code: 'NGD', name: 'Nagad', city: 'Nagad', countryCode: 'DJ', timezone: 'Africa/Djibouti', lat: 11.5720, lng: 43.1456 },
  ];

  const created = [];
  for (const station of stations) {
    const s = await prisma.station.upsert({
      where: { code: station.code },
      update: {},
      create: station,
    });
    created.push(s);
  }

  console.log(`  ✅ Created ${created.length} stations`);
  return created;
}

// ============================================================================
// SECTION 2: SEAT CLASSES
// ============================================================================
async function seedSeatClasses() {
  console.log('💺 Seeding seat classes...');
  
  const classes = [
    { name: 'Economy Regular', description: 'Standard economy seating', basePrice: 25000 },
    { name: 'Economy Bed', description: 'Economy bed lower berth', basePrice: 35000 },
    { name: 'VIP Bed', description: 'First class VIP bed', basePrice: 55000 },
  ];

  const created = [];
  for (const cls of classes) {
    const c = await prisma.seatClass.upsert({
      where: { name: cls.name },
      update: {},
      create: { ...cls, isActive: true },
    });
    created.push(c);
  }

  console.log(`  ✅ Created ${created.length} seat classes`);
  return created;
}

// ============================================================================
// SECTION 3: TRAINS
// ============================================================================
async function seedTrains() {
  console.log('🚂 Seeding trains...');
  
  const trains = [
    { number: '301', name: 'Express 301', description: 'Sebeta-Nagad Express' },
    { number: '302', name: 'Express 302', description: 'Nagad-Sebeta Express' },
    { number: '303', name: 'Local 303', description: 'Regional Service' },
  ];

  const created = [];
  for (const train of trains) {
    const t = await prisma.train.upsert({
      where: { number: train.number },
      update: {},
      create: train,
    });
    created.push(t);
  }

  console.log(`  ✅ Created ${created.length} trains`);
  return created;
}

// ============================================================================
// SECTION 4: COACHES & SEATS
// ============================================================================
async function seedCoachesAndSeats(seatClasses: any[]) {
  console.log('🚃 Seeding coaches and seats...');
  
  const [scEconomy, scEconomyBed, scVip] = seatClasses;
  
  const coachConfigs = [
    { coachNumber: 'C-A1', label: 'A', seatClassId: scEconomy.id, mode: 'seat', totalUnits: 60 },
    { coachNumber: 'C-B1', label: 'B', seatClassId: scEconomyBed.id, mode: 'bed', totalUnits: 40 },
    { coachNumber: 'C-C1', label: 'C', seatClassId: scVip.id, mode: 'bed', totalUnits: 20 },
    { coachNumber: 'C-A2', label: 'A', seatClassId: scEconomy.id, mode: 'seat', totalUnits: 60 },
    { coachNumber: 'C-B2', label: 'B', seatClassId: scEconomyBed.id, mode: 'bed', totalUnits: 40 },
    { coachNumber: 'C-C2', label: 'C', seatClassId: scVip.id, mode: 'bed', totalUnits: 20 },
  ];

  const coaches = [];
  for (const config of coachConfigs) {
    const coach = await prisma.coach.upsert({
      where: { coachNumber: config.coachNumber },
      update: {},
      create: config,
    });
    coaches.push(coach);

    // Create seats for this coach
    const existingSeats = await prisma.seat.count({ where: { coachId: coach.id } });
    if (existingSeats === 0) {
      const seats = [];
      const rows = Math.ceil(config.totalUnits / 4);
      for (let row = 1; row <= rows; row++) {
        for (const col of ['A', 'B', 'C', 'D']) {
          if (seats.length >= config.totalUnits) break;
          seats.push({
            coachId: coach.id,
            row,
            col,
            label: `${row}${col}`,
            seatNumber: `${config.label}${row}${col}`,
            kind: row === 1 && col === 'A' ? 'ACCESSIBLE' : 'STANDARD',
          });
        }
      }
      await prisma.seat.createMany({ data: seats as any });
    }
  }

  console.log(`  ✅ Created ${coaches.length} coaches with seats`);
  return coaches;
}

// ============================================================================
// SECTION 5: SCHEDULES (15+ SEGMENTS)
// ============================================================================
async function seedSchedules(trains: any[], stations: any[], routes: any[]) {
  console.log('📅 Seeding schedules with 15+ segments...');
  
  const [train301, train302, train303] = trains;
  const [sebeta, labu, indode, bishoftu, mojo, adama, feto, metahara, mieso, bike, diredawa, arawa, adigala, aysha, dawanle, alisabieh, holhol, nagad] = stations;
  const [fullRoute, regionalRoute] = routes;

  // Clean up existing schedules
  const existingScheduleIds = (await prisma.trainSchedule.findMany({
    where: { trainId: { in: [train301.id, train302.id, train303.id] } },
    select: { id: true },
  })).map((s: { id: string }) => s.id);

  if (existingScheduleIds.length > 0) {
    // Delete in correct order to avoid foreign key constraints
    await prisma.bookingSeat.deleteMany({ 
      where: { 
        booking: { 
          scheduleId: { in: existingScheduleIds } 
        } 
      } 
    });
    await prisma.booking.deleteMany({ where: { scheduleId: { in: existingScheduleIds } } });
    await prisma.fareRule.deleteMany({ where: { tripId: { in: existingScheduleIds } } });
    await prisma.tripStopTime.deleteMany({ where: { scheduleId: { in: existingScheduleIds } } });
    await prisma.coachAssignment.deleteMany({ where: { scheduleId: { in: existingScheduleIds } } });
    await prisma.trainSchedule.deleteMany({ where: { id: { in: existingScheduleIds } } });
  }

  const schedules = [
    // Full route: Sebeta to Nagad (18 stations)
    {
      trainId: train301.id,
      routeId: fullRoute.id,
      originStationId: sebeta.id,
      destinationStationId: nagad.id,
      departureAt: new Date('2026-06-15T06:00:00Z'),
      arrivalAt: new Date('2026-06-15T22:00:00Z'),
      durationMinutes: 960,
      stopsCount: 18,
    },
    // Return route: Nagad to Sebeta
    {
      trainId: train302.id,
      routeId: fullRoute.id,
      originStationId: nagad.id,
      destinationStationId: sebeta.id,
      departureAt: new Date('2026-06-16T07:00:00Z'),
      arrivalAt: new Date('2026-06-16T23:30:00Z'),
      durationMinutes: 990,
      stopsCount: 18,
    },
    // Regional service: Sebeta to Diredawa
    {
      trainId: train303.id,
      routeId: regionalRoute.id,
      originStationId: sebeta.id,
      destinationStationId: diredawa.id,
      departureAt: new Date('2026-06-17T08:00:00Z'),
      arrivalAt: new Date('2026-06-17T18:00:00Z'),
      durationMinutes: 600,
      stopsCount: 11,
    },
    // Additional schedules for next day
    {
      trainId: train301.id,
      routeId: fullRoute.id,
      originStationId: sebeta.id,
      destinationStationId: nagad.id,
      departureAt: new Date('2026-06-18T06:30:00Z'),
      arrivalAt: new Date('2026-06-18T22:45:00Z'),
      durationMinutes: 975,
      stopsCount: 18,
    },
    {
      trainId: train302.id,
      routeId: fullRoute.id,
      originStationId: nagad.id,
      destinationStationId: sebeta.id,
      departureAt: new Date('2026-06-19T07:15:00Z'),
      arrivalAt: new Date('2026-06-19T23:45:00Z'),
      durationMinutes: 990,
      stopsCount: 18,
    },
  ];

  const created = [];
  for (const schedule of schedules) {
    const s = await prisma.trainSchedule.create({ data: schedule });
    created.push(s);
  }

  console.log(`  ✅ Created ${created.length} schedules`);
  return created;
}

// ============================================================================
// SECTION 6: COACH ASSIGNMENTS
// ============================================================================
async function seedCoachAssignments(schedules: any[], coaches: any[]) {
  console.log('🔗 Seeding coach assignments...');
  
  const [coachA1, coachB1, coachC1, coachA2, coachB2, coachC2] = coaches;
  const [schedule1, schedule2, schedule3] = schedules;

  const assignments = [
    { scheduleId: schedule1.id, coachId: coachA1.id, positionNumber: 1 },
    { scheduleId: schedule1.id, coachId: coachB1.id, positionNumber: 2 },
    { scheduleId: schedule1.id, coachId: coachC1.id, positionNumber: 3 },
    { scheduleId: schedule2.id, coachId: coachA2.id, positionNumber: 1 },
    { scheduleId: schedule2.id, coachId: coachB2.id, positionNumber: 2 },
    { scheduleId: schedule2.id, coachId: coachC2.id, positionNumber: 3 },
    { scheduleId: schedule3.id, coachId: coachA1.id, positionNumber: 1 },
    { scheduleId: schedule3.id, coachId: coachB1.id, positionNumber: 2 },
    { scheduleId: schedule3.id, coachId: coachC1.id, positionNumber: 3 },
  ];

  await prisma.coachAssignment.createMany({ data: assignments, skipDuplicates: true });
  console.log(`  ✅ Created ${assignments.length} coach assignments`);
}

// ============================================================================
// SECTION 7: STOP TIMES (ALL 18 STATIONS)
// ============================================================================
async function seedStopTimes(schedules: any[], stations: any[]) {
  console.log('⏱️  Seeding stop times for all stations...');
  
  const [sebeta, labu, indode, bishoftu, mojo, adama, feto, metahara, mieso, bike, diredawa, arawa, adigala, aysha, dawanle, alisabieh, holhol, nagad] = stations;
  const [schedule1, schedule2, schedule3] = schedules;

  // Full route stop times (Sebeta to Nagad)
  const fullRouteStops = [
    { scheduleId: schedule1.id, stationId: sebeta.id, sequence: 1, plannedDepartureAt: new Date('2026-06-15T06:00:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: labu.id, sequence: 2, plannedArrivalAt: new Date('2026-06-15T06:30:00Z'), plannedDepartureAt: new Date('2026-06-15T06:35:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: indode.id, sequence: 3, plannedArrivalAt: new Date('2026-06-15T07:00:00Z'), plannedDepartureAt: new Date('2026-06-15T07:05:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: bishoftu.id, sequence: 4, plannedArrivalAt: new Date('2026-06-15T07:30:00Z'), plannedDepartureAt: new Date('2026-06-15T07:40:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: mojo.id, sequence: 5, plannedArrivalAt: new Date('2026-06-15T08:15:00Z'), plannedDepartureAt: new Date('2026-06-15T08:25:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: adama.id, sequence: 6, plannedArrivalAt: new Date('2026-06-15T09:00:00Z'), plannedDepartureAt: new Date('2026-06-15T09:15:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: feto.id, sequence: 7, plannedArrivalAt: new Date('2026-06-15T09:45:00Z'), plannedDepartureAt: new Date('2026-06-15T09:50:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: metahara.id, sequence: 8, plannedArrivalAt: new Date('2026-06-15T10:30:00Z'), plannedDepartureAt: new Date('2026-06-15T10:45:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: mieso.id, sequence: 9, plannedArrivalAt: new Date('2026-06-15T12:00:00Z'), plannedDepartureAt: new Date('2026-06-15T12:10:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: bike.id, sequence: 10, plannedArrivalAt: new Date('2026-06-15T13:30:00Z'), plannedDepartureAt: new Date('2026-06-15T13:40:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: diredawa.id, sequence: 11, plannedArrivalAt: new Date('2026-06-15T15:00:00Z'), plannedDepartureAt: new Date('2026-06-15T15:20:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: arawa.id, sequence: 12, plannedArrivalAt: new Date('2026-06-15T16:30:00Z'), plannedDepartureAt: new Date('2026-06-15T16:35:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: adigala.id, sequence: 13, plannedArrivalAt: new Date('2026-06-15T17:45:00Z'), plannedDepartureAt: new Date('2026-06-15T17:50:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: aysha.id, sequence: 14, plannedArrivalAt: new Date('2026-06-15T18:30:00Z'), plannedDepartureAt: new Date('2026-06-15T18:40:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: dawanle.id, sequence: 15, plannedArrivalAt: new Date('2026-06-15T19:15:00Z'), plannedDepartureAt: new Date('2026-06-15T19:20:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: alisabieh.id, sequence: 16, plannedArrivalAt: new Date('2026-06-15T20:00:00Z'), plannedDepartureAt: new Date('2026-06-15T20:05:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: holhol.id, sequence: 17, plannedArrivalAt: new Date('2026-06-15T21:00:00Z'), plannedDepartureAt: new Date('2026-06-15T21:05:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule1.id, stationId: nagad.id, sequence: 18, plannedArrivalAt: new Date('2026-06-15T22:00:00Z'), status: 'UPCOMING' as const },
  ];

  // Regional route stop times (Sebeta to Diredawa)
  const regionalStops = [
    { scheduleId: schedule3.id, stationId: sebeta.id, sequence: 1, plannedDepartureAt: new Date('2026-06-17T08:00:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule3.id, stationId: labu.id, sequence: 2, plannedArrivalAt: new Date('2026-06-17T08:30:00Z'), plannedDepartureAt: new Date('2026-06-17T08:35:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule3.id, stationId: indode.id, sequence: 3, plannedArrivalAt: new Date('2026-06-17T09:00:00Z'), plannedDepartureAt: new Date('2026-06-17T09:05:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule3.id, stationId: bishoftu.id, sequence: 4, plannedArrivalAt: new Date('2026-06-17T09:30:00Z'), plannedDepartureAt: new Date('2026-06-17T09:40:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule3.id, stationId: mojo.id, sequence: 5, plannedArrivalAt: new Date('2026-06-17T10:15:00Z'), plannedDepartureAt: new Date('2026-06-17T10:25:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule3.id, stationId: adama.id, sequence: 6, plannedArrivalAt: new Date('2026-06-17T11:00:00Z'), plannedDepartureAt: new Date('2026-06-17T11:15:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule3.id, stationId: feto.id, sequence: 7, plannedArrivalAt: new Date('2026-06-17T11:45:00Z'), plannedDepartureAt: new Date('2026-06-17T11:50:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule3.id, stationId: metahara.id, sequence: 8, plannedArrivalAt: new Date('2026-06-17T12:30:00Z'), plannedDepartureAt: new Date('2026-06-17T12:45:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule3.id, stationId: mieso.id, sequence: 9, plannedArrivalAt: new Date('2026-06-17T14:00:00Z'), plannedDepartureAt: new Date('2026-06-17T14:10:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule3.id, stationId: bike.id, sequence: 10, plannedArrivalAt: new Date('2026-06-17T15:30:00Z'), plannedDepartureAt: new Date('2026-06-17T15:40:00Z'), status: 'UPCOMING' as const },
    { scheduleId: schedule3.id, stationId: diredawa.id, sequence: 11, plannedArrivalAt: new Date('2026-06-17T18:00:00Z'), status: 'UPCOMING' as const },
  ];

  const allStops = [...fullRouteStops, ...regionalStops];
  await prisma.tripStopTime.createMany({ data: allStops });
  console.log(`  ✅ Created ${allStops.length} stop times`);
}

// ============================================================================
// SECTION 8: FARE RULES (COMPREHENSIVE SEGMENTS)
// ============================================================================
async function seedFareRules(schedules: any[], seatClasses: any[]) {
  console.log('💰 Seeding comprehensive fare rules...');
  
  const [scEconomy, scEconomyBed, scVip] = seatClasses;

  // Segment-based fare rules (15+ segments)
  const segmentRules = [
    // Short segments (1-3 stations)
    { route: 'SBT-LBU', seatClassId: scEconomy.id, baseFareMinor: 5000, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'LBU-IND', seatClassId: scEconomy.id, baseFareMinor: 4500, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'IND-BSH', seatClassId: scEconomy.id, baseFareMinor: 5500, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'BSH-MJO', seatClassId: scEconomy.id, baseFareMinor: 6000, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'MJO-ADM', seatClassId: scEconomy.id, baseFareMinor: 7000, validFrom: new Date('2026-01-01'), refundable: true },
    
    // Medium segments (3-6 stations)
    { route: 'SBT-BSH', seatClassId: scEconomy.id, baseFareMinor: 12000, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'SBT-ADM', seatClassId: scEconomy.id, baseFareMinor: 18000, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'ADM-MTH', seatClassId: scEconomy.id, baseFareMinor: 8500, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'MTH-MSO', seatClassId: scEconomy.id, baseFareMinor: 9500, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'MSO-BKE', seatClassId: scEconomy.id, baseFareMinor: 8000, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'BKE-DDW', seatClassId: scEconomy.id, baseFareMinor: 7500, validFrom: new Date('2026-01-01'), refundable: true },
    
    // Long segments (6+ stations)
    { route: 'SBT-DDW', seatClassId: scEconomy.id, baseFareMinor: 35000, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'DDW-AYS', seatClassId: scEconomy.id, baseFareMinor: 15000, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'AYS-NGD', seatClassId: scEconomy.id, baseFareMinor: 18000, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'SBT-NGD', seatClassId: scEconomy.id, baseFareMinor: 65000, validFrom: new Date('2026-01-01'), refundable: true },
    
    // Cross-border segments
    { route: 'DDW-DWL', seatClassId: scEconomy.id, baseFareMinor: 22000, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'DWL-ALI', seatClassId: scEconomy.id, baseFareMinor: 12000, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'ALI-HOL', seatClassId: scEconomy.id, baseFareMinor: 8500, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'HOL-NGD', seatClassId: scEconomy.id, baseFareMinor: 6000, validFrom: new Date('2026-01-01'), refundable: true },
  ];

  // Add Economy Bed prices (40% higher)
  const bedRules = segmentRules.map(rule => ({
    ...rule,
    seatClassId: scEconomyBed.id,
    baseFareMinor: Math.round(rule.baseFareMinor * 1.4),
  }));

  // Add VIP prices (80% higher)
  const vipRules = segmentRules.map(rule => ({
    ...rule,
    seatClassId: scVip.id,
    baseFareMinor: Math.round(rule.baseFareMinor * 1.8),
  }));

  const allRules = [...segmentRules, ...bedRules, ...vipRules];
  await prisma.fareRule.createMany({ data: allRules, skipDuplicates: true });

  // Nationality-specific discounts
  const nationalityRules = [
    // Ethiopian nationals - 10% discount on domestic routes
    { route: 'SBT-DDW', nationality: 'Ethiopian', seatClassId: scEconomy.id, baseFareMinor: 31500, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'SBT-ADM', nationality: 'Ethiopian', seatClassId: scEconomy.id, baseFareMinor: 16200, validFrom: new Date('2026-01-01'), refundable: true },
    
    // Djiboutian nationals - 5% discount on cross-border routes
    { route: 'DDW-NGD', nationality: 'Djiboutian', seatClassId: scEconomy.id, baseFareMinor: 42750, validFrom: new Date('2026-01-01'), refundable: true },
    { route: 'SBT-NGD', nationality: 'Djiboutian', seatClassId: scEconomy.id, baseFareMinor: 61750, validFrom: new Date('2026-01-01'), refundable: true },
  ];
  
  await prisma.fareRule.createMany({ data: nationalityRules, skipDuplicates: true });

  console.log(`  ✅ Created ${allRules.length + nationalityRules.length} fare rules`);
}

// ============================================================================
// SECTION 9: USERS & PASSENGERS
// ============================================================================
async function seedUsers() {
  console.log('👥 Seeding users...');
  
  const hash = await bcrypt.hash('password123', 10);
  const adminHash = await bcrypt.hash('admin123', 10);
  const agentHash = await bcrypt.hash('agent123', 10);

  // Admin
  await prisma.user.upsert({
    where: { email: 'admin@edr-platform.com' },
    update: { passwordHash: adminHash, role: 'ADMIN' },
    create: {
      fullName: 'EDR Admin',
      email: 'admin@edr-platform.com',
      phone: '+251900000000',
      passwordHash: adminHash,
      role: 'ADMIN',
    },
  });

  // Ethiopian Passenger
  const ethiopianUser = await prisma.user.upsert({
    where: { email: 'abebe@email.com' },
    update: {},
    create: {
      fullName: 'Abebe Kebede',
      email: 'abebe@email.com',
      phone: '+251912345678',
      passwordHash: hash,
      nationality: 'Ethiopian',
      nationalId: 'ET123456789',
    },
  });

  let ethiopianPassenger = await prisma.passenger.findUnique({ where: { userId: ethiopianUser.id } });
  if (!ethiopianPassenger) {
    ethiopianPassenger = await prisma.passenger.create({ data: { userId: ethiopianUser.id } });
    await prisma.loyaltyAccount.create({ data: { passengerId: ethiopianPassenger.id, pointsBalance: 2450, tier: 'SILVER' } });
    await prisma.walletAccount.create({ data: { passengerId: ethiopianPassenger.id, balanceMinor: 125000 } });
  }
  await prisma.userPreferences.upsert({
    where: { userId: ethiopianUser.id },
    update: {},
    create: { userId: ethiopianUser.id, language: 'en' },
  });

  // Djiboutian Passenger
  const djiboutianUser = await prisma.user.upsert({
    where: { email: 'ahmed@email.com' },
    update: {},
    create: {
      fullName: 'Ahmed Hassan',
      email: 'ahmed@email.com',
      phone: '+25377123456',
      passwordHash: hash,
      nationality: 'Djiboutian',
      passportNumber: 'DJ1234567',
    },
  });

  let djiboutianPassenger = await prisma.passenger.findUnique({ where: { userId: djiboutianUser.id } });
  if (!djiboutianPassenger) {
    djiboutianPassenger = await prisma.passenger.create({ data: { userId: djiboutianUser.id } });
    await prisma.loyaltyAccount.create({ data: { passengerId: djiboutianPassenger.id, pointsBalance: 1200, tier: 'BRONZE' } });
    await prisma.walletAccount.create({ data: { passengerId: djiboutianPassenger.id, balanceMinor: 85000 } });
  }
  await prisma.userPreferences.upsert({
    where: { userId: djiboutianUser.id },
    update: {},
    create: { userId: djiboutianUser.id, language: 'fr' },
  });

  // Agent
  const agentUser = await prisma.user.upsert({
    where: { email: 'agent@edr-platform.com' },
    update: { passwordHash: agentHash, role: 'AGENT' },
    create: {
      fullName: 'Agent Abebe',
      email: 'agent@edr-platform.com',
      phone: '+251911111111',
      passwordHash: agentHash,
      role: 'AGENT',
    },
  });

  const stations = await prisma.station.findMany();
  await prisma.agent.upsert({
    where: { userId: agentUser.id },
    update: {},
    create: {
      userId: agentUser.id,
      agentCode: 'AG001',
      stationId: stations[0].id,
      commissionRate: 5,
      active: true,
    },
  });

  console.log(`  ✅ Created 4 users (Admin, Ethiopian, Djiboutian, Agent)`);
}

// ============================================================================
// SECTION 10: ROUTES
// ============================================================================
async function seedRoutes(stations: any[], seatClasses: any[]) {
  console.log('🛤️  Seeding routes...');
  
  const [sebeta, labu, indode, bishoftu, mojo, adama, feto, metahara, mieso, bike, diredawa, arawa, adigala, aysha, dawanle, alisabieh, holhol, nagad] = stations;
  const [scEconomy, scEconomyBed, scVip] = seatClasses;

  // Route 1: Full Line (Sebeta to Nagad)
  const fullRoute = await prisma.route.upsert({
    where: { code: 'SBT-NGD-FULL' },
    update: {},
    create: {
      code: 'SBT-NGD-FULL',
      name: 'Sebeta - Nagad Express',
      description: 'Complete Ethio-Djibouti Railway route from Sebeta to Nagad',
      effectiveFrom: new Date('2026-01-01'),
      active: true,
    },
  });

  // Create stops for full route
  const fullRouteStops = [
    { routeId: fullRoute.id, stationId: sebeta.id, sequence: 1, distanceKm: 0 },
    { routeId: fullRoute.id, stationId: labu.id, sequence: 2, distanceKm: 15 },
    { routeId: fullRoute.id, stationId: indode.id, sequence: 3, distanceKm: 28 },
    { routeId: fullRoute.id, stationId: bishoftu.id, sequence: 4, distanceKm: 45 },
    { routeId: fullRoute.id, stationId: mojo.id, sequence: 5, distanceKm: 73 },
    { routeId: fullRoute.id, stationId: adama.id, sequence: 6, distanceKm: 99 },
    { routeId: fullRoute.id, stationId: feto.id, sequence: 7, distanceKm: 125 },
    { routeId: fullRoute.id, stationId: metahara.id, sequence: 8, distanceKm: 168 },
    { routeId: fullRoute.id, stationId: mieso.id, sequence: 9, distanceKm: 245 },
    { routeId: fullRoute.id, stationId: bike.id, sequence: 10, distanceKm: 312 },
    { routeId: fullRoute.id, stationId: diredawa.id, sequence: 11, distanceKm: 378 },
    { routeId: fullRoute.id, stationId: arawa.id, sequence: 12, distanceKm: 445 },
    { routeId: fullRoute.id, stationId: adigala.id, sequence: 13, distanceKm: 512 },
    { routeId: fullRoute.id, stationId: aysha.id, sequence: 14, distanceKm: 578 },
    { routeId: fullRoute.id, stationId: dawanle.id, sequence: 15, distanceKm: 625 },
    { routeId: fullRoute.id, stationId: alisabieh.id, sequence: 16, distanceKm: 672 },
    { routeId: fullRoute.id, stationId: holhol.id, sequence: 17, distanceKm: 718 },
    { routeId: fullRoute.id, stationId: nagad.id, sequence: 18, distanceKm: 756 },
  ];
  await prisma.routeStop.createMany({ data: fullRouteStops, skipDuplicates: true });

  // Fare rules for full route
  const fullRouteFares = [
    { routeId: fullRoute.id, seatClassId: scEconomy.id, passengerCategory: 'ADULT' as const, baseFareMinor: 65000, validFrom: new Date('2026-01-01') },
    { routeId: fullRoute.id, seatClassId: scEconomy.id, passengerCategory: 'CHILD' as const, baseFareMinor: 65000, validFrom: new Date('2026-01-01') },
    { routeId: fullRoute.id, seatClassId: scEconomyBed.id, passengerCategory: 'ADULT' as const, baseFareMinor: 91000, validFrom: new Date('2026-01-01') },
    { routeId: fullRoute.id, seatClassId: scEconomyBed.id, passengerCategory: 'CHILD' as const, baseFareMinor: 91000, validFrom: new Date('2026-01-01') },
    { routeId: fullRoute.id, seatClassId: scVip.id, passengerCategory: 'ADULT' as const, baseFareMinor: 117000, validFrom: new Date('2026-01-01') },
    { routeId: fullRoute.id, seatClassId: scVip.id, passengerCategory: 'CHILD' as const, baseFareMinor: 117000, validFrom: new Date('2026-01-01') },
  ];
  await prisma.routeFareRule.createMany({ data: fullRouteFares, skipDuplicates: true });

  // Route 2: Regional (Sebeta to Diredawa)
  const regionalRoute = await prisma.route.upsert({
    where: { code: 'SBT-DDW-REG' },
    update: {},
    create: {
      code: 'SBT-DDW-REG',
      name: 'Sebeta - Diredawa Regional',
      description: 'Regional service from Sebeta to Diredawa',
      effectiveFrom: new Date('2026-01-01'),
      active: true,
    },
  });

  const regionalStops = [
    { routeId: regionalRoute.id, stationId: sebeta.id, sequence: 1, distanceKm: 0 },
    { routeId: regionalRoute.id, stationId: labu.id, sequence: 2, distanceKm: 15 },
    { routeId: regionalRoute.id, stationId: indode.id, sequence: 3, distanceKm: 28 },
    { routeId: regionalRoute.id, stationId: bishoftu.id, sequence: 4, distanceKm: 45 },
    { routeId: regionalRoute.id, stationId: mojo.id, sequence: 5, distanceKm: 73 },
    { routeId: regionalRoute.id, stationId: adama.id, sequence: 6, distanceKm: 99 },
    { routeId: regionalRoute.id, stationId: feto.id, sequence: 7, distanceKm: 125 },
    { routeId: regionalRoute.id, stationId: metahara.id, sequence: 8, distanceKm: 168 },
    { routeId: regionalRoute.id, stationId: mieso.id, sequence: 9, distanceKm: 245 },
    { routeId: regionalRoute.id, stationId: bike.id, sequence: 10, distanceKm: 312 },
    { routeId: regionalRoute.id, stationId: diredawa.id, sequence: 11, distanceKm: 378 },
  ];
  await prisma.routeStop.createMany({ data: regionalStops, skipDuplicates: true });

  const regionalFares = [
    { routeId: regionalRoute.id, seatClassId: scEconomy.id, passengerCategory: 'ADULT' as const, baseFareMinor: 35000, validFrom: new Date('2026-01-01') },
    { routeId: regionalRoute.id, seatClassId: scEconomy.id, passengerCategory: 'CHILD' as const, baseFareMinor: 35000, validFrom: new Date('2026-01-01') },
    { routeId: regionalRoute.id, seatClassId: scEconomyBed.id, passengerCategory: 'ADULT' as const, baseFareMinor: 49000, validFrom: new Date('2026-01-01') },
    { routeId: regionalRoute.id, seatClassId: scEconomyBed.id, passengerCategory: 'CHILD' as const, baseFareMinor: 49000, validFrom: new Date('2026-01-01') },
    { routeId: regionalRoute.id, seatClassId: scVip.id, passengerCategory: 'ADULT' as const, baseFareMinor: 63000, validFrom: new Date('2026-01-01') },
    { routeId: regionalRoute.id, seatClassId: scVip.id, passengerCategory: 'CHILD' as const, baseFareMinor: 63000, validFrom: new Date('2026-01-01') },
  ];
  await prisma.routeFareRule.createMany({ data: regionalFares, skipDuplicates: true });

  // Route 3: Short Distance (Sebeta to Adama)
  const shortRoute = await prisma.route.upsert({
    where: { code: 'SBT-ADM-SHORT' },
    update: {},
    create: {
      code: 'SBT-ADM-SHORT',
      name: 'Sebeta - Adama Commuter',
      description: 'Short distance commuter service',
      effectiveFrom: new Date('2026-01-01'),
      active: true,
    },
  });

  const shortStops = [
    { routeId: shortRoute.id, stationId: sebeta.id, sequence: 1, distanceKm: 0 },
    { routeId: shortRoute.id, stationId: labu.id, sequence: 2, distanceKm: 15 },
    { routeId: shortRoute.id, stationId: indode.id, sequence: 3, distanceKm: 28 },
    { routeId: shortRoute.id, stationId: bishoftu.id, sequence: 4, distanceKm: 45 },
    { routeId: shortRoute.id, stationId: mojo.id, sequence: 5, distanceKm: 73 },
    { routeId: shortRoute.id, stationId: adama.id, sequence: 6, distanceKm: 99 },
  ];
  await prisma.routeStop.createMany({ data: shortStops, skipDuplicates: true });

  const shortFares = [
    { routeId: shortRoute.id, seatClassId: scEconomy.id, passengerCategory: 'ADULT' as const, baseFareMinor: 18000, validFrom: new Date('2026-01-01') },
    { routeId: shortRoute.id, seatClassId: scEconomy.id, passengerCategory: 'CHILD' as const, baseFareMinor: 18000, validFrom: new Date('2026-01-01') },
    { routeId: shortRoute.id, seatClassId: scEconomyBed.id, passengerCategory: 'ADULT' as const, baseFareMinor: 25200, validFrom: new Date('2026-01-01') },
    { routeId: shortRoute.id, seatClassId: scEconomyBed.id, passengerCategory: 'CHILD' as const, baseFareMinor: 25200, validFrom: new Date('2026-01-01') },
    { routeId: shortRoute.id, seatClassId: scVip.id, passengerCategory: 'ADULT' as const, baseFareMinor: 32400, validFrom: new Date('2026-01-01') },
    { routeId: shortRoute.id, seatClassId: scVip.id, passengerCategory: 'CHILD' as const, baseFareMinor: 32400, validFrom: new Date('2026-01-01') },
  ];
  await prisma.routeFareRule.createMany({ data: shortFares, skipDuplicates: true });

  // Route 4: Cross-Border (Diredawa to Nagad)
  const crossBorderRoute = await prisma.route.upsert({
    where: { code: 'DDW-NGD-INTL' },
    update: {},
    create: {
      code: 'DDW-NGD-INTL',
      name: 'Diredawa - Nagad International',
      description: 'Cross-border service from Ethiopia to Djibouti',
      effectiveFrom: new Date('2026-01-01'),
      active: true,
    },
  });

  const crossBorderStops = [
    { routeId: crossBorderRoute.id, stationId: diredawa.id, sequence: 1, distanceKm: 0 },
    { routeId: crossBorderRoute.id, stationId: arawa.id, sequence: 2, distanceKm: 67 },
    { routeId: crossBorderRoute.id, stationId: adigala.id, sequence: 3, distanceKm: 134 },
    { routeId: crossBorderRoute.id, stationId: aysha.id, sequence: 4, distanceKm: 200 },
    { routeId: crossBorderRoute.id, stationId: dawanle.id, sequence: 5, distanceKm: 247 },
    { routeId: crossBorderRoute.id, stationId: alisabieh.id, sequence: 6, distanceKm: 294 },
    { routeId: crossBorderRoute.id, stationId: holhol.id, sequence: 7, distanceKm: 340 },
    { routeId: crossBorderRoute.id, stationId: nagad.id, sequence: 8, distanceKm: 378 },
  ];
  await prisma.routeStop.createMany({ data: crossBorderStops, skipDuplicates: true });

  const crossBorderFares = [
    { routeId: crossBorderRoute.id, seatClassId: scEconomy.id, passengerCategory: 'ADULT' as const, baseFareMinor: 45000, validFrom: new Date('2026-01-01') },
    { routeId: crossBorderRoute.id, seatClassId: scEconomy.id, passengerCategory: 'CHILD' as const, baseFareMinor: 45000, validFrom: new Date('2026-01-01') },
    { routeId: crossBorderRoute.id, seatClassId: scEconomyBed.id, passengerCategory: 'ADULT' as const, baseFareMinor: 63000, validFrom: new Date('2026-01-01') },
    { routeId: crossBorderRoute.id, seatClassId: scEconomyBed.id, passengerCategory: 'CHILD' as const, baseFareMinor: 63000, validFrom: new Date('2026-01-01') },
    { routeId: crossBorderRoute.id, seatClassId: scVip.id, passengerCategory: 'ADULT' as const, baseFareMinor: 81000, validFrom: new Date('2026-01-01') },
    { routeId: crossBorderRoute.id, seatClassId: scVip.id, passengerCategory: 'CHILD' as const, baseFareMinor: 81000, validFrom: new Date('2026-01-01') },
  ];
  await prisma.routeFareRule.createMany({ data: crossBorderFares, skipDuplicates: true });

  console.log(`  ✅ Created 4 routes with stops and fare rules`);
  return [fullRoute, regionalRoute, shortRoute, crossBorderRoute];
}

// ============================================================================
// SECTION 11: SUPPORTING DATA
// ============================================================================
async function seedSupportingData(seatClasses: any[]) {
  console.log('📦 Seeding supporting data...');
  
  // Baggage Allowance
  await prisma.baggageAllowance.deleteMany({});
  await prisma.baggageAllowance.createMany({
    data: [
      { seatClassId: seatClasses[0].id, maxWeightKg: 20, maxPiecesCount: 2, excessFeePerKg: 500 },
      { seatClassId: seatClasses[1].id, maxWeightKg: 25, maxPiecesCount: 2, excessFeePerKg: 450 },
      { seatClassId: seatClasses[2].id, maxWeightKg: 30, maxPiecesCount: 3, excessFeePerKg: 400 },
    ],
  });

  // Supported Payment Methods (platform-wide catalog)
  const paymentMethods = [
    { type: 'TELEBIRR', displayName: 'Telebirr', region: 'ETHIOPIA', currency: 'ETB', sortOrder: 1, isDefault: true },
    { type: 'CBE_BIRR', displayName: 'CBE Birr', region: 'ETHIOPIA', currency: 'ETB', sortOrder: 2 },
    { type: 'EBIRR', displayName: 'E-Birr', region: 'ETHIOPIA', currency: 'ETB', sortOrder: 3 },
    { type: 'WAAFI', displayName: 'Waafi', region: 'DJIBOUTI', currency: 'DJF', sortOrder: 4 },
    { type: 'CARD', displayName: 'Credit / Debit Card', region: 'INTERNATIONAL', currency: 'USD', sortOrder: 5 },
    { type: 'WALLET', displayName: 'EDR Wallet', region: 'GLOBAL', currency: 'ETB', sortOrder: 6 },
  ] as const;
  for (const pm of paymentMethods) {
    await prisma.paymentMethod.upsert({
      where: { type: pm.type as any },
      update: { displayName: pm.displayName, region: pm.region as any, currency: pm.currency, sortOrder: pm.sortOrder, enabled: true },
      create: { ...pm, region: pm.region as any, type: pm.type as any },
    });
  }

  // Notification Templates
  await prisma.notificationTemplate.upsert({
    where: { code: 'BOOKING_CONFIRMED' },
    update: {},
    create: {
      code: 'BOOKING_CONFIRMED',
      channel: 'EMAIL',
      subject: 'Booking Confirmed',
      bodyTemplate: 'Your booking {{bookingRef}} is confirmed for {{tripDate}}.',
      active: true,
    },
  });

  await prisma.notificationTemplate.upsert({
    where: { code: 'booking.created' },
    update: {},
    create: {
      code: 'booking.created',
      channel: 'EMAIL',
      subject: 'Booking Created',
      bodyTemplate: 'Your booking {{bookingRef}} has been created successfully.',
      active: true,
    },
  });

  await prisma.notificationTemplate.upsert({
    where: { code: 'PAYMENT_SUCCESS' },
    update: {},
    create: {
      code: 'PAYMENT_SUCCESS',
      channel: 'SMS',
      bodyTemplate: 'Payment successful for {{bookingRef}}. Amount: {{amount}} ETB',
      active: true,
    },
  });

  // Promotions
  await prisma.promotion.upsert({
    where: { code: 'WEEKEND15' },
    update: {},
    create: {
      title: 'Weekend Sale',
      subtitle: '15% off all trips',
      code: 'WEEKEND15',
      percentOff: 15,
      validUntil: new Date('2026-12-31'),
      ctaLabel: 'Book Now',
      active: true,
    },
  });

  // Currency Exchange Rates
  await prisma.currencyExchangeRate.deleteMany({});
  await prisma.currencyExchangeRate.createMany({
    data: [
      { fromCurrency: 'ETB', toCurrency: 'ETB', rate: 1.0, effectiveDate: new Date() },
      { fromCurrency: 'ETB', toCurrency: 'USD', rate: 0.018, effectiveDate: new Date() },
      { fromCurrency: 'ETB', toCurrency: 'DJF', rate: 3.2, effectiveDate: new Date() },
      { fromCurrency: 'DJF', toCurrency: 'ETB', rate: 0.3125, effectiveDate: new Date() },
      { fromCurrency: 'DJF', toCurrency: 'DJF', rate: 1.0, effectiveDate: new Date() },
    ],
  });

  // Fraud Rules
  await prisma.fraudRule.upsert({
    where: { type: 'VELOCITY' },
    update: {},
    create: {
      type: 'VELOCITY',
      enabled: true,
      threshold: 3,
      config: { windowMinutes: 60, action: 'FLAG' },
    },
  });

  console.log(`  ✅ Created supporting data`);
}

// ============================================================================
// MAIN SEED FUNCTION
// ============================================================================
async function main() {
  console.log('🌱 Starting comprehensive modular seed with 18 stations...\n');

  const stations = await seedStations();
  const seatClasses = await seedSeatClasses();
  const trains = await seedTrains();
  const coaches = await seedCoachesAndSeats(seatClasses);
  const routes = await seedRoutes(stations, seatClasses);
  const schedules = await seedSchedules(trains, stations, routes);
  await seedCoachAssignments(schedules, coaches);
  await seedStopTimes(schedules, stations);
  await seedFareRules(schedules, seatClasses);
  await seedUsers();
  await seedSupportingData(seatClasses);

  console.log('\n✅ Comprehensive seed complete!\n');
  console.log('📋 Seed Summary:');
  console.log('  - 18 Stations: SBT, LBU, IND, BSH, MJO, ADM, FTO, MTH, MSO, BKE, DDW, ARW, ADG, AYS, DWL, ALI, HOL, NGD');
  console.log('  - 3 Seat Classes (Economy Regular, Economy Bed, VIP Bed)');
  console.log('  - 3 Trains (Express 301, Express 302, Local 303)');
  console.log('  - 6 Physical Coaches with seats');
  console.log('  - 5 Train Schedules covering full and regional routes');
  console.log('  - 4 Routes with stops and fare rules');
  console.log('  - 15+ Fare Segments with nationality-based pricing');
  console.log('  - 4 Users: Admin, Ethiopian Passenger, Djiboutian Passenger, Agent');
  console.log('  - Currency rates: ETB, USD, DJF');
  console.log('\n🔑 Login Credentials:');
  console.log('  Admin:              admin@edr-platform.com / admin123');
  console.log('  Ethiopian Passenger: abebe@email.com / password123');
  console.log('  Djiboutian Passenger: ahmed@email.com / password123');
  console.log('  Agent:              agent@edr-platform.com / agent123');
  console.log('\n💰 Booking Flow Ready:');
  console.log('  - Search: 18 stations with multiple route combinations');
  console.log('  - Select: 3 seat classes with dynamic pricing');
  console.log('  - Book: Complete passenger details and payment');
  console.log('  - Pay: Multiple payment methods (Telebirr, CBE, Card, Wallet)');
  console.log('  - Ticket: QR code generation and validation');
  console.log('\n🚂 Sample Routes:');
  console.log('  - Full Route: Sebeta → Nagad (18 stations, 756 km)');
  console.log('  - Regional: Sebeta → Diredawa (11 stations, 378 km)');
  console.log('  - Short: Sebeta → Adama (6 stations, 99 km)');
  console.log('  - Cross-border: Diredawa → Nagad (8 stations, 378 km)');
}

main()
  .catch((e) => {
    console.error('❌ Seed failed:', e);
    process.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
