/**
 * Transport API Tests
 * Tests for transport-related API endpoints
 *
 * Note: These tests are designed to test API route handlers.
 * They mock the underlying services and test request/response handling.
 */

import { TransportChain, getTransportChain, setTransportChain } from '../../lib/transport/tracker';
import {
  SeedAcquisitionEvent,
  PlantingEvent,
  HarvestEvent,
  TransportLocation,
} from '../../lib/transport/types';

describe('Transport API', () => {
  let chain: TransportChain;

  beforeEach(() => {
    chain = new TransportChain(1);
    setTransportChain(chain);
  });

  describe('POST /api/transport/seed-acquisition', () => {
    it('should record seed acquisition event', () => {
      const event: SeedAcquisitionEvent = {
        id: 'api-seed-001',
        timestamp: new Date().toISOString(),
        eventType: 'seed_acquisition',
        fromLocation: createLocation('seed_bank'),
        toLocation: createLocation('greenhouse'),
        distanceKm: 25,
        durationMinutes: 45,
        transportMethod: 'electric_vehicle',
        carbonFootprintKg: 0,
        senderId: 'seed-bank-1',
        receiverId: 'grower-1',
        status: 'verified',
        seedBatchId: 'batch-001',
        sourceType: 'seed_bank',
        species: 'Solanum lycopersicum',
        quantity: 100,
        quantityUnit: 'seeds',
        generation: 1,
      };

      const block = chain.recordEvent(event);

      expect(block.transportEvent.id).toBe('api-seed-001');
      expect(block.transportEvent.eventType).toBe('seed_acquisition');
    });

    it('should reject invalid seed acquisition data', () => {
      const invalidEvent = {
        id: 'invalid-001',
        eventType: 'seed_acquisition',
        // Missing required fields
      };

      expect(() => {
        chain.recordEvent(invalidEvent as any);
      }).toThrow();
    });
  });

  describe('POST /api/transport/planting', () => {
    it('should record planting event', () => {
      const event: PlantingEvent = {
        id: 'api-planting-001',
        timestamp: new Date().toISOString(),
        eventType: 'planting',
        fromLocation: createLocation('greenhouse'),
        toLocation: createLocation('greenhouse'),
        distanceKm: 0,
        durationMinutes: 10,
        transportMethod: 'walking',
        carbonFootprintKg: 0,
        senderId: 'grower-1',
        receiverId: 'grower-1',
        status: 'verified',
        seedBatchId: 'batch-001',
        plantIds: ['plant-001', 'plant-002'],
        plantingMethod: 'indoor_start',
        quantityPlanted: 2,
        growingEnvironment: 'greenhouse',
      };

      const block = chain.recordEvent(event);

      expect(block.transportEvent.eventType).toBe('planting');
      expect((block.transportEvent as PlantingEvent).plantIds.length).toBe(2);
    });
  });

  describe('POST /api/transport/harvest', () => {
    it('should record harvest event', () => {
      const event: HarvestEvent = {
        id: 'api-harvest-001',
        timestamp: new Date().toISOString(),
        eventType: 'harvest',
        fromLocation: createLocation('farm'),
        toLocation: createLocation('warehouse'),
        distanceKm: 10,
        durationMinutes: 30,
        transportMethod: 'electric_truck',
        carbonFootprintKg: 0,
        senderId: 'grower-1',
        receiverId: 'distributor-1',
        status: 'verified',
        plantIds: ['plant-001'],
        harvestBatchId: 'harvest-001',
        harvestType: 'full',
        produceType: 'tomatoes',
        grossWeight: 10,
        netWeight: 9.5,
        weightUnit: 'kg',
        packagingType: 'crates',
        temperatureRequired: { min: 10, max: 15, optimal: 12, unit: 'celsius' },
        shelfLifeHours: 168,
        seedsSaved: false,
      };

      const block = chain.recordEvent(event);

      expect(block.transportEvent.eventType).toBe('harvest');
    });
  });

  describe('GET /api/transport/journey/[plantId]', () => {
    it('should return plant journey', () => {
      const plantId = 'journey-plant-001';

      // Record events for plant
      const plantingEvent: PlantingEvent = {
        id: 'journey-planting-001',
        timestamp: new Date().toISOString(),
        eventType: 'planting',
        fromLocation: createLocation('greenhouse'),
        toLocation: createLocation('greenhouse'),
        distanceKm: 0,
        durationMinutes: 5,
        transportMethod: 'walking',
        carbonFootprintKg: 0,
        senderId: 'grower-1',
        receiverId: 'grower-1',
        status: 'verified',
        seedBatchId: 'batch-001',
        plantIds: [plantId],
        plantingMethod: 'indoor_start',
        quantityPlanted: 1,
        growingEnvironment: 'greenhouse',
      };

      chain.recordEvent(plantingEvent);

      const journey = chain.getPlantJourney(plantId);

      expect(journey).not.toBeNull();
      expect(journey?.plantId).toBe(plantId);
      expect(journey?.events.length).toBe(1);
    });

    it('should return null for unknown plant', () => {
      const journey = chain.getPlantJourney('unknown-plant-id');
      expect(journey).toBeNull();
    });
  });

  describe('GET /api/transport/footprint/[userId]', () => {
    it('should return environmental impact', () => {
      const userId = 'footprint-user-001';

      const event: SeedAcquisitionEvent = {
        id: 'footprint-event-001',
        timestamp: new Date().toISOString(),
        eventType: 'seed_acquisition',
        fromLocation: createLocation('seed_bank'),
        toLocation: createLocation('greenhouse'),
        distanceKm: 50,
        durationMinutes: 60,
        transportMethod: 'diesel_truck',
        carbonFootprintKg: 0,
        senderId: userId,
        receiverId: userId,
        status: 'verified',
        seedBatchId: 'batch-footprint',
        sourceType: 'seed_bank',
        species: 'Test species',
        quantity: 100,
        quantityUnit: 'seeds',
        generation: 1,
      };

      chain.recordEvent(event);

      const impact = chain.getEnvironmentalImpact(userId);

      expect(impact.totalFoodMiles).toBe(50);
      expect(impact.totalCarbonKg).toBeGreaterThan(0);
      expect(impact.comparisonToConventional).toBeDefined();
    });

    it('should return zero impact for user with no events', () => {
      const impact = chain.getEnvironmentalImpact('no-events-user');

      expect(impact.totalFoodMiles).toBe(0);
      expect(impact.totalCarbonKg).toBe(0);
    });
  });

  describe('GET /api/transport/verify/[blockHash]', () => {
    it('should verify chain integrity', () => {
      chain.recordEvent(createSeedEvent());
      chain.recordEvent(createSeedEvent());

      const isValid = chain.isChainValid();
      expect(isValid).toBe(true);
    });

    it('should detect tampered chain', () => {
      chain.recordEvent(createSeedEvent());

      // Tamper with block
      chain.chain[1].transportEvent.distanceKm = 999999;

      const isValid = chain.isChainValid();
      expect(isValid).toBe(false);
    });
  });

  describe('GET /api/transport/qr/[id]', () => {
    it('should generate QR data for plant', () => {
      const plantId = 'qr-plant-001';

      const plantingEvent: PlantingEvent = {
        id: 'qr-planting-001',
        timestamp: new Date().toISOString(),
        eventType: 'planting',
        fromLocation: createLocation('greenhouse'),
        toLocation: createLocation('greenhouse'),
        distanceKm: 0,
        durationMinutes: 5,
        transportMethod: 'walking',
        carbonFootprintKg: 0,
        senderId: 'grower-1',
        receiverId: 'grower-1',
        status: 'verified',
        seedBatchId: 'batch-001',
        plantIds: [plantId],
        plantingMethod: 'indoor_start',
        quantityPlanted: 1,
        growingEnvironment: 'greenhouse',
      };

      chain.recordEvent(plantingEvent);

      const qrData = chain.generateQRData(plantId, undefined);

      expect(qrData.plantId).toBe(plantId);
      expect(qrData.quickLookupUrl).toContain(plantId);
      expect(qrData.verificationCode).toBeDefined();
    });

    it('should generate QR data for batch', () => {
      const batchId = 'qr-batch-001';

      const event = createSeedEvent();
      event.seedBatchId = batchId;
      chain.recordEvent(event);

      const qrData = chain.generateQRData(undefined, batchId);

      expect(qrData.batchId).toBe(batchId);
    });
  });

  describe('Response Format', () => {
    it('should return blocks with all required fields', () => {
      const block = chain.recordEvent(createSeedEvent());

      expect(block.index).toBeDefined();
      expect(block.timestamp).toBeDefined();
      expect(block.transportEvent).toBeDefined();
      expect(block.previousHash).toBeDefined();
      expect(block.hash).toBeDefined();
      expect(block.nonce).toBeDefined();
      expect(block.cumulativeCarbonKg).toBeDefined();
      expect(block.cumulativeFoodMiles).toBeDefined();
    });
  });
});

// Helper functions
function createLocation(type: string): TransportLocation {
  return {
    latitude: 40.7128,
    longitude: -74.006,
    locationType: type as any,
    facilityName: `Test ${type}`,
  };
}

function createSeedEvent(): SeedAcquisitionEvent {
  return {
    id: `seed-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
    timestamp: new Date().toISOString(),
    eventType: 'seed_acquisition',
    fromLocation: createLocation('seed_bank'),
    toLocation: createLocation('greenhouse'),
    distanceKm: 25,
    durationMinutes: 45,
    transportMethod: 'electric_vehicle',
    carbonFootprintKg: 0,
    senderId: 'seed-bank-1',
    receiverId: 'grower-1',
    status: 'verified',
    seedBatchId: `batch-${Date.now()}`,
    sourceType: 'seed_bank',
    species: 'Test species',
    quantity: 100,
    quantityUnit: 'seeds',
    generation: 1,
  };
}
