/**
 * Plants API Tests
 * Integration tests for plant-related API endpoints
 */

// Mock the blockchain manager
jest.mock('../../lib/blockchain/manager', () => ({
  getBlockchain: jest.fn(() => ({
    getChain: jest.fn(() => [
      // Genesis block
      {
        index: 0,
        timestamp: '2024-01-01T00:00:00Z',
        plant: { id: 'genesis' },
        previousHash: '0',
        hash: 'genesis-hash',
        nonce: 0,
      },
      // Test plants
      {
        index: 1,
        timestamp: '2024-01-02T00:00:00Z',
        plant: {
          id: 'plant-1',
          name: 'Cherry Tomato',
          species: 'Tomato',
          variety: 'Cherry',
          generation: 1,
          propagationType: 'original',
          status: 'healthy',
          location: { latitude: 40.7128, longitude: -74.006 },
        },
        previousHash: 'genesis-hash',
        hash: 'hash-1',
        nonce: 1,
      },
      {
        index: 2,
        timestamp: '2024-01-03T00:00:00Z',
        plant: {
          id: 'plant-2',
          name: 'Sweet Basil',
          species: 'Basil',
          variety: 'Genovese',
          generation: 1,
          propagationType: 'seed',
          parentPlantId: 'plant-1',
          status: 'thriving',
          location: { latitude: 40.7228, longitude: -74.016 },
        },
        previousHash: 'hash-1',
        hash: 'hash-2',
        nonce: 2,
      },
    ]),
    addPlant: jest.fn((plant) => ({
      index: 3,
      timestamp: new Date().toISOString(),
      plant,
      previousHash: 'hash-2',
      hash: 'hash-3',
      nonce: 3,
    })),
    findPlant: jest.fn((id) => {
      if (id === 'plant-1') {
        return {
          index: 1,
          plant: {
            id: 'plant-1',
            name: 'Cherry Tomato',
            species: 'Tomato',
            variety: 'Cherry',
            generation: 1,
            status: 'healthy',
          },
        };
      }
      return undefined;
    }),
    isValid: jest.fn(() => true),
  })),
}));

describe('Plants API', () => {
  describe('GET /api/plants', () => {
    it('should return plant list', async () => {
      const { getBlockchain } = require('../../lib/blockchain/manager');
      const blockchain = getBlockchain();
      const chain = blockchain.getChain();

      expect(chain.length).toBeGreaterThan(1);
      expect(chain[1].plant.name).toBe('Cherry Tomato');
    });
  });

  describe('GET /api/plants/[id]', () => {
    it('should return plant by ID', async () => {
      const { getBlockchain } = require('../../lib/blockchain/manager');
      const blockchain = getBlockchain();
      const plant = blockchain.findPlant('plant-1');

      expect(plant).toBeDefined();
      expect(plant.plant.name).toBe('Cherry Tomato');
    });

    it('should return undefined for non-existent plant', async () => {
      const { getBlockchain } = require('../../lib/blockchain/manager');
      const blockchain = getBlockchain();
      const plant = blockchain.findPlant('non-existent');

      expect(plant).toBeUndefined();
    });
  });

  describe('POST /api/plants/register', () => {
    it('should register new plant', async () => {
      const { getBlockchain } = require('../../lib/blockchain/manager');
      const blockchain = getBlockchain();

      const newPlant = {
        id: 'plant-3',
        name: 'New Plant',
        species: 'Test',
        variety: 'Test',
        generation: 1,
        propagationType: 'seed',
        status: 'healthy',
        location: { latitude: 40.7, longitude: -74.0 },
      };

      const block = blockchain.addPlant(newPlant);

      expect(block).toBeDefined();
      expect(block.plant.name).toBe('New Plant');
      expect(blockchain.addPlant).toHaveBeenCalledWith(newPlant);
    });
  });

  describe('GET /api/plants/network', () => {
    it('should return network statistics', async () => {
      const { getBlockchain } = require('../../lib/blockchain/manager');
      const blockchain = getBlockchain();
      const chain = blockchain.getChain();

      // Calculate network stats
      const plants = chain.slice(1); // Skip genesis
      const totalPlants = plants.length;
      const speciesCounts: Record<string, number> = {};

      plants.forEach((block: any) => {
        const species = block.plant.species;
        speciesCounts[species] = (speciesCounts[species] || 0) + 1;
      });

      expect(totalPlants).toBe(2);
      expect(speciesCounts['Tomato']).toBe(1);
      expect(speciesCounts['Basil']).toBe(1);
    });
  });

  describe('GET /api/plants/lineage/[id]', () => {
    it('should return lineage for plant with parent', async () => {
      const { getBlockchain } = require('../../lib/blockchain/manager');
      const blockchain = getBlockchain();
      const chain = blockchain.getChain();

      const plant2 = chain[2].plant;
      expect(plant2.parentPlantId).toBe('plant-1');
    });
  });

  describe('Blockchain Validation', () => {
    it('should validate chain integrity', async () => {
      const { getBlockchain } = require('../../lib/blockchain/manager');
      const blockchain = getBlockchain();

      expect(blockchain.isValid()).toBe(true);
    });
  });
});
