/**
 * Transport Types Tests
 * Tests for type validation and consistency
 */

import {
  TransportLocation,
  TransportMethod,
  TransportEventType,
  PlantStage,
  CARBON_FACTORS,
  SeedAcquisitionEvent,
  PlantingEvent,
  GrowingTransportEvent,
  HarvestEvent,
  ProcessingEvent,
  DistributionEvent,
  ConsumerDeliveryEvent,
  SeedSavingEvent,
  SeedSharingEvent,
  TransportBlock,
  PlantJourney,
  EnvironmentalImpact,
  TransportQRData,
} from '../../../lib/transport/types';

describe('Transport Types Validation', () => {
  describe('TransportLocation', () => {
    it('should accept valid location types', () => {
      const validTypes = [
        'farm', 'greenhouse', 'vertical_farm', 'warehouse',
        'hub', 'market', 'consumer', 'seed_bank', 'other'
      ];

      validTypes.forEach(locationType => {
        const location: TransportLocation = {
          latitude: 40.7128,
          longitude: -74.006,
          locationType: locationType as any,
        };
        expect(location.locationType).toBe(locationType);
      });
    });

    it('should have required latitude and longitude', () => {
      const location: TransportLocation = {
        latitude: 0,
        longitude: 0,
        locationType: 'farm',
      };
      expect(location.latitude).toBeDefined();
      expect(location.longitude).toBeDefined();
    });

    it('should accept optional fields', () => {
      const location: TransportLocation = {
        latitude: 40.7128,
        longitude: -74.006,
        address: '123 Farm Lane',
        city: 'New York',
        region: 'NY',
        country: 'USA',
        postalCode: '10001',
        locationType: 'farm',
        facilityId: 'facility-001',
        facilityName: 'Green Acres Farm',
      };

      expect(location.address).toBe('123 Farm Lane');
      expect(location.facilityName).toBe('Green Acres Farm');
    });
  });

  describe('TransportMethod', () => {
    it('should define all transport methods', () => {
      const methods: TransportMethod[] = [
        'walking', 'bicycle', 'electric_vehicle', 'hybrid_vehicle',
        'gasoline_vehicle', 'diesel_truck', 'electric_truck',
        'refrigerated_truck', 'rail', 'ship', 'air', 'drone',
        'local_delivery', 'customer_pickup'
      ];

      // All methods should have corresponding carbon factors
      methods.forEach(method => {
        expect(CARBON_FACTORS[method]).toBeDefined();
      });
    });
  });

  describe('PlantStage', () => {
    it('should cover complete plant lifecycle', () => {
      const stages: PlantStage[] = [
        'seed', 'germinating', 'seedling', 'vegetative',
        'flowering', 'fruiting', 'mature', 'harvesting',
        'post_harvest', 'seed_saving'
      ];

      // Verify all stages are valid strings
      stages.forEach(stage => {
        expect(typeof stage).toBe('string');
        expect(stage.length).toBeGreaterThan(0);
      });
    });
  });

  describe('TransportEventType', () => {
    it('should cover complete transport event types', () => {
      const eventTypes: TransportEventType[] = [
        'seed_acquisition', 'planting', 'growing_transport',
        'harvest', 'processing', 'distribution',
        'consumer_delivery', 'seed_saving', 'seed_sharing'
      ];

      expect(eventTypes.length).toBe(9);
    });
  });

  describe('Event Type Structures', () => {
    it('should validate SeedAcquisitionEvent', () => {
      const event: SeedAcquisitionEvent = {
        id: 'seed-001',
        timestamp: new Date().toISOString(),
        eventType: 'seed_acquisition',
        fromLocation: { latitude: 0, longitude: 0, locationType: 'seed_bank' },
        toLocation: { latitude: 0, longitude: 0, locationType: 'farm' },
        distanceKm: 10,
        durationMinutes: 30,
        transportMethod: 'electric_vehicle',
        carbonFootprintKg: 0.5,
        senderId: 'sender-001',
        receiverId: 'receiver-001',
        status: 'verified',
        seedBatchId: 'batch-001',
        sourceType: 'seed_bank',
        species: 'Solanum lycopersicum',
        quantity: 100,
        quantityUnit: 'seeds',
        generation: 1,
      };

      expect(event.eventType).toBe('seed_acquisition');
      expect(event.seedBatchId).toBeDefined();
      expect(event.species).toBeDefined();
    });

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

      expect(event.eventType).toBe('planting');
      expect(event.plantIds.length).toBe(2);
    });

    it('should validate HarvestEvent', () => {
      const event: HarvestEvent = {
        id: 'harvest-001',
        timestamp: new Date().toISOString(),
        eventType: 'harvest',
        fromLocation: { latitude: 0, longitude: 0, locationType: 'farm' },
        toLocation: { latitude: 0, longitude: 0, locationType: 'warehouse' },
        distanceKm: 5,
        durationMinutes: 20,
        transportMethod: 'electric_truck',
        carbonFootprintKg: 0.1,
        senderId: 'grower-001',
        receiverId: 'processor-001',
        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: true,
        seedBatchIdCreated: 'new-seed-batch-001',
      };

      expect(event.eventType).toBe('harvest');
      expect(event.seedsSaved).toBe(true);
      expect(event.seedBatchIdCreated).toBeDefined();
    });

    it('should validate SeedSavingEvent', () => {
      const event: SeedSavingEvent = {
        id: 'save-001',
        timestamp: new Date().toISOString(),
        eventType: 'seed_saving',
        fromLocation: { latitude: 0, longitude: 0, locationType: 'farm' },
        toLocation: { latitude: 0, longitude: 0, locationType: 'seed_bank' },
        distanceKm: 1,
        durationMinutes: 10,
        transportMethod: 'walking',
        carbonFootprintKg: 0,
        senderId: 'grower-001',
        receiverId: 'grower-001',
        status: 'verified',
        parentPlantIds: ['plant-001', 'plant-002'],
        newSeedBatchId: 'new-batch-001',
        collectionMethod: 'dry_seed',
        seedCount: 500,
        storageConditions: {
          temperature: 10,
          humidity: 30,
          lightExposure: 'dark',
          containerType: 'jar',
          desiccant: true,
          estimatedViability: 5,
        },
        storageLocationId: 'storage-001',
        newGenerationNumber: 2,
        availableForSharing: true,
      };

      expect(event.eventType).toBe('seed_saving');
      expect(event.newGenerationNumber).toBe(2);
    });
  });

  describe('TransportBlock', () => {
    it('should have all required blockchain fields', () => {
      const block: TransportBlock = {
        index: 1,
        timestamp: new Date().toISOString(),
        transportEvent: {
          id: 'test',
          timestamp: new Date().toISOString(),
          eventType: 'seed_acquisition',
          fromLocation: { latitude: 0, longitude: 0, locationType: 'seed_bank' },
          toLocation: { latitude: 0, longitude: 0, locationType: 'farm' },
          distanceKm: 0,
          durationMinutes: 0,
          transportMethod: 'walking',
          carbonFootprintKg: 0,
          senderId: 'a',
          receiverId: 'b',
          status: 'verified',
          seedBatchId: 'batch',
          sourceType: 'seed_bank',
          species: 'test',
          quantity: 1,
          quantityUnit: 'seeds',
          generation: 0,
        },
        previousHash: '0'.repeat(64),
        hash: 'a'.repeat(64),
        nonce: 12345,
        cumulativeCarbonKg: 0,
        cumulativeFoodMiles: 0,
        chainLength: 2,
      };

      expect(block.index).toBeDefined();
      expect(block.previousHash.length).toBe(64);
      expect(block.hash.length).toBe(64);
      expect(block.nonce).toBeGreaterThanOrEqual(0);
    });
  });

  describe('PlantJourney', () => {
    it('should track complete journey data', () => {
      const journey: PlantJourney = {
        plantId: 'plant-001',
        seedBatchOrigin: 'batch-001',
        currentCustodian: 'grower-001',
        currentLocation: { latitude: 40, longitude: -74, locationType: 'farm' },
        currentStage: 'vegetative',
        events: [],
        totalFoodMiles: 25.5,
        totalCarbonKg: 1.2,
        daysInTransit: 2,
        daysGrowing: 45,
        generation: 1,
        ancestorPlantIds: ['parent-001'],
        descendantSeedBatches: ['future-batch-001'],
      };

      expect(journey.plantId).toBe('plant-001');
      expect(journey.totalFoodMiles).toBe(25.5);
      expect(journey.generation).toBe(1);
    });
  });

  describe('EnvironmentalImpact', () => {
    it('should have comparison metrics', () => {
      const impact: EnvironmentalImpact = {
        totalCarbonKg: 10,
        totalFoodMiles: 100,
        carbonPerKgProduce: 0.5,
        milesPerKgProduce: 5,
        breakdownByMethod: {},
        breakdownByEventType: {},
        comparisonToConventional: {
          carbonSaved: 50,
          milesSaved: 1400,
          percentageReduction: 83,
        },
      };

      expect(impact.comparisonToConventional.percentageReduction).toBe(83);
      expect(impact.comparisonToConventional.milesSaved).toBe(1400);
    });
  });

  describe('TransportQRData', () => {
    it('should have verification data', () => {
      const qrData: TransportQRData = {
        plantId: 'plant-001',
        blockchainAddress: '0x' + 'a'.repeat(40),
        quickLookupUrl: 'https://example.com/track/plant-001',
        lineageHash: 'abc123',
        currentCustodian: 'grower-001',
        lastEventType: 'planting',
        lastEventTimestamp: new Date().toISOString(),
        verificationCode: 'ABCD1234',
      };

      expect(qrData.verificationCode.length).toBe(8);
      expect(qrData.quickLookupUrl).toContain('plant-001');
    });
  });

  describe('Status Values', () => {
    it('should have valid event statuses', () => {
      const statuses: Array<'pending' | 'in_transit' | 'delivered' | 'verified' | 'disputed'> = [
        'pending', 'in_transit', 'delivered', 'verified', 'disputed'
      ];

      expect(statuses.length).toBe(5);
    });
  });

  describe('Certification Types', () => {
    it('should define seed certifications', () => {
      const certifications: Array<'organic' | 'non_gmo' | 'heirloom' | 'certified_seed' | 'biodynamic'> = [
        'organic', 'non_gmo', 'heirloom', 'certified_seed', 'biodynamic'
      ];

      expect(certifications.length).toBe(5);
    });
  });
});
