import { Filament } from '../src/types/filament';
import { Pool } from 'pg';

describe('Data Structure Consistency Tests', () => {
  const connectionString = "postgresql://filamenteka_admin:onrBjiAjHKQXBAJSVWU2t2kQ7HDil9re@filamenteka.ci7fsdlbzmag.eu-central-1.rds.amazonaws.com:5432/filamenteka";
  
  // Admin panel expected structure (source of truth)
  const ADMIN_STRUCTURE = {
    fields: [
      'id',
      'tip',
      'finish', 
      'boja',
      'boja_hex', // Now using snake_case consistently
      'refill',
      'spulna',  // Frontend still uses spulna
      'kolicina',
      'cena',
      'created_at',
      'updated_at'
    ],
    requiredFields: ['tip', 'finish', 'boja'],
    excludedFields: ['brand'], // Should NOT exist
    fieldTypes: {
      tip: 'string',
      finish: 'string',
      boja: 'string',
      boja_hex: 'string',
      refill: 'number',
      spulna: 'number',
      kolicina: 'number',
      cena: 'string'
    }
  };

  // Database expected structure
  const DB_STRUCTURE = {
    columns: [
      'id',
      'tip',
      'finish',
      'boja',
      'boja_hex', // Database uses snake_case
      'refill',
      'spulna',
      'kolicina',
      'cena',
      'created_at',
      'updated_at'
    ],
    excludedColumns: ['brand'],
    columnTypes: {
      id: 'uuid',
      tip: 'character varying',
      finish: 'character varying',
      boja: 'character varying',
      boja_hex: 'character varying',
      refill: 'integer',
      spulna: 'integer',
      kolicina: 'integer',
      cena: 'character varying',
      created_at: 'timestamp with time zone',
      updated_at: 'timestamp with time zone'
    }
  };

  describe('Admin Panel Structure', () => {
    it('should have correct TypeScript interface', () => {
      // Check Filament interface matches admin structure
      const filamentKeys: (keyof Filament)[] = [
        'id', 'tip', 'finish', 'boja', 'boja_hex',
        'refill', 'spulna', 'kolicina', 'cena',
        'status', 'createdAt', 'updatedAt'
      ];
      
      // Should not have brand
      expect(filamentKeys).not.toContain('brand');
      
      // Should have all required fields
      ADMIN_STRUCTURE.requiredFields.forEach(field => {
        expect(filamentKeys).toContain(field);
      });
    });

    it('should have consistent form fields in admin dashboard', () => {
      const formFields = [
        'tip', 'finish', 'boja', 'boja_hex', 
        'refill', 'spulna', 'kolicina', 'cena'
      ];
      
      // Check all form fields are in admin structure
      formFields.forEach(field => {
        expect(ADMIN_STRUCTURE.fields).toContain(field);
      });
      
      // Should not have brand in form
      expect(formFields).not.toContain('brand');
    });
  });

  describe('Database Schema Consistency', () => {
    let pool: Pool;

    beforeAll(() => {
      pool = new Pool({
        connectionString,
        ssl: { rejectUnauthorized: false }
      });
    });

    afterAll(async () => {
      await pool.end();
    });

    it('should have correct columns in database', async () => {
      const result = await pool.query(`
        SELECT column_name, data_type 
        FROM information_schema.columns 
        WHERE table_name = 'filaments' 
        ORDER BY ordinal_position
      `);
      
      const columns = result.rows.map(row => row.column_name);
      const columnTypes = result.rows.reduce((acc, row) => {
        acc[row.column_name] = row.data_type;
        return acc;
      }, {} as Record<string, string>);

      // Check all expected columns exist
      DB_STRUCTURE.columns.forEach(col => {
        expect(columns).toContain(col);
      });

      // Check no excluded columns exist
      DB_STRUCTURE.excludedColumns.forEach(col => {
        expect(columns).not.toContain(col);
      });

      // Check column types match
      Object.entries(DB_STRUCTURE.columnTypes).forEach(([col, type]) => {
        expect(columnTypes[col]).toBe(type);
      });
    });

    it('should not have brand column', async () => {
      const result = await pool.query(`
        SELECT COUNT(*) as count
        FROM information_schema.columns 
        WHERE table_name = 'filaments' AND column_name = 'brand'
      `);
      
      expect(parseInt(result.rows[0].count)).toBe(0);
    });
  });

  describe('Frontend Consistency', () => {
    it('should transform fields correctly between admin and database', () => {
      // All fields now use snake_case consistently
      const snakeCaseFields = {
        'boja_hex': 'boja_hex',
        'created_at': 'created_at',
        'updated_at': 'updated_at'
      };

      Object.entries(snakeCaseFields).forEach(([adminField, dbField]) => {
        expect(ADMIN_STRUCTURE.fields).toContain(adminField);
        expect(DB_STRUCTURE.columns).toContain(dbField);
      });
    });

    it('should handle quantity fields correctly', () => {
      // Admin form shows refill, spulna as numbers
      // Database stores them as strings like "2", "1 spulna"
      const quantityFields = ['refill', 'spulna'];
      
      quantityFields.forEach(field => {
        expect(ADMIN_STRUCTURE.fieldTypes[field]).toBe('number');
        expect(DB_STRUCTURE.columnTypes[field]).toBe('integer');
      });
    });
  });

  describe('API Consistency', () => {
    it('should handle requests without brand field', () => {
      const validRequest = {
        tip: 'PLA',
        finish: 'Basic',
        boja: 'Black',
        boja_hex: '#000000',
        refill: '2',
        spulna: '1 spulna',
        kolicina: '3',
        cena: '3999'
      };

      // Should not have brand
      expect(validRequest).not.toHaveProperty('brand');
      
      // Should have all required fields
      expect(validRequest).toHaveProperty('tip');
      expect(validRequest).toHaveProperty('finish');
      expect(validRequest).toHaveProperty('boja');
    });
  });

  describe('Data Flow Consistency', () => {
    it('should maintain consistent data flow: Admin → API → Database', () => {
      // Admin form data
      const adminData = {
        tip: 'PLA',
        finish: 'Basic',
        boja: 'Black',
        boja_hex: '#000000',
        refill: '2',
        spulna: '1 spulna',
        kolicina: '3',
        cena: '3999'
      };

      // No transformation needed - using boja_hex consistently
      const apiData = adminData;

      // Database expected data
      expect(apiData).toHaveProperty('boja_hex');
      // No longer have bojaHex field
      expect(apiData).not.toHaveProperty('brand');
    });
  });
});