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

import { Facility } from '../modules/facilities/entities/facility.entity';
import { Warehouse } from '../modules/warehouses/entities/warehouse.entity';
import { WarehouseInventory } from '../modules/warehouses/entities/warehouse-inventory.entity';
import { WarehouseYard } from '../modules/warehouses/entities/warehouse-yard.entity';
import { WarehouseZone } from '../modules/warehouses/entities/warehouse-zone.entity';

/**
 * Test data seeder for Batch 1-4 warehouse system.
 * Creates Indode facility with warehouses, yards, zones, and sample inventory
 * in all status states (RECEIVED, STORED, RESERVED, READY_FOR_LOADING, LOADED, DISPATCHED).
 */
@Injectable()
export class Batch14TestDataSeeder {
  private readonly logger = new Logger(Batch14TestDataSeeder.name);

  constructor(private readonly dataSource: DataSource) {}

  async run(): Promise<void> {
    try {
      const facilityRepo = this.dataSource.getRepository(Facility);
      const warehouseRepo = this.dataSource.getRepository(Warehouse);
      const yardRepo = this.dataSource.getRepository(WarehouseYard);
      const zoneRepo = this.dataSource.getRepository(WarehouseZone);
      const inventoryRepo = this.dataSource.getRepository(WarehouseInventory);

      // Check if facility already exists
      const existingFacility = await facilityRepo.findOne({
        where: { code: 'INDODE_TEST' },
      });

      if (existingFacility) {
        this.logger.log('Batch 1-4 test data already seeded, skipping');
        return;
      }

      // Create Facility
      const facility = await facilityRepo.save(
        facilityRepo.create({
          code: 'INDODE_TEST',
          name: 'Indode Test Facility',
          facilityType: 'DRY_PORT',
          facilityStatus: 'ACTIVE',
          locationName: 'Indode',
          country: 'Djibouti',
          city: 'Djibouti',
          isActive: true,
          capacity: 100000,
        }),
      );
      this.logger.log(`Created facility: ${facility.code}`);

      // Create Warehouse
      const warehouse = await warehouseRepo.save(
        warehouseRepo.create({
          code: 'TEST_WH_001',
          name: 'Test Warehouse 1',
          type: 'OPEN_WAREHOUSE',
          locationName: 'Test Location',
          status: 'ACTIVE',
          isActive: true,
          facilityId: facility.id,
          capacityWeight: 50000,
          capacityContainers: 500,
          maxWeight: 50000,
          maxVolume: 10000,
        }),
      );
      this.logger.log(`Created warehouse: ${warehouse.code}`);

      // Create Yards
      const yard1 = await yardRepo.save(
        yardRepo.create({
          warehouseId: warehouse.id,
          code: 'YARD_001',
          name: 'Container Yard 1',
          type: 'CONTAINER_YARD',
          status: 'ACTIVE',
          isActive: true,
          capacityWeight: 25000,
          capacityContainers: 250,
          maxWeight: 25000,
          maxVolume: 5000,
        }),
      );

      const yard2 = await yardRepo.save(
        yardRepo.create({
          warehouseId: warehouse.id,
          code: 'YARD_002',
          name: 'Bulk Yard 1',
          type: 'BULK_YARD',
          status: 'ACTIVE',
          isActive: true,
          capacityWeight: 25000,
          capacityContainers: 100,
          maxWeight: 25000,
          maxVolume: 5000,
        }),
      );
      this.logger.log(`Created yards: ${yard1.code}, ${yard2.code}`);

      // Create Zones
      const zone1 = await zoneRepo.save(
        zoneRepo.create({
          yardId: yard1.id,
          code: 'ZONE_001',
          name: 'Container Zone A',
          type: 'CONTAINER_ZONE',
          status: 'ACTIVE',
          isActive: true,
          capacityWeight: 12500,
          capacityContainers: 125,
          maxWeight: 12500,
          maxVolume: 2500,
        }),
      );

      const zone2 = await zoneRepo.save(
        zoneRepo.create({
          yardId: yard2.id,
          code: 'ZONE_002',
          name: 'Bulk Zone A',
          type: 'BULK_ZONE',
          status: 'ACTIVE',
          isActive: true,
          capacityWeight: 12500,
          capacityContainers: 50,
          maxWeight: 12500,
          maxVolume: 2500,
        }),
      );
      this.logger.log(`Created zones: ${zone1.code}, ${zone2.code}`);

      // Create inventory in all statuses for testing
      const statuses = ['RECEIVED', 'STORED', 'RESERVED', 'READY_FOR_LOADING', 'LOADED', 'DISPATCHED'] as const;
      const now = new Date();

      for (let i = 0; i < statuses.length; i++) {
        const status = statuses[i];
        const zone = i < 3 ? zone1 : zone2;

        await inventoryRepo.save(
          inventoryRepo.create({
            warehouseId: warehouse.id,
            yardId: zone.yardId,
            zoneId: zone.id,
            status: status as any,
            quantity: 100 + i * 10,
            weight: 500 + i * 50,
            volume: 100 + i * 10,
            arrivedAt: new Date(now.getTime() - i * 3600000),
            storedAt: status !== 'RECEIVED' ? new Date(now.getTime() - (i - 1) * 3600000) : null,
            reservedAt: ['RESERVED', 'READY_FOR_LOADING', 'LOADED', 'DISPATCHED'].includes(status) ? new Date() : null,
            readyForLoadingAt: ['READY_FOR_LOADING', 'LOADED', 'DISPATCHED'].includes(status) ? new Date() : null,
            loadedAt: ['LOADED', 'DISPATCHED'].includes(status) ? new Date() : null,
            dispatchedAt: status === 'DISPATCHED' ? new Date() : null,
          }),
        );
      }
      this.logger.log('Created 6 test inventory items in all statuses');

      this.logger.log('✅ Batch 1-4 test data seeded successfully');
    } catch (error) {
      this.logger.error(`Batch 1-4 seeder failed: ${error instanceof Error ? error.message : String(error)}`);
    }
  }
}
