import { describe, it, expect } from 'vitest';

// ─── Test: EquipmentTab barrel export ──────────────────────────────────────────

describe('EquipmentTab module structure', () => {
  it('exports EquipmentTab from barrel index', async () => {
    const mod = await import('./EquipmentTab');
    expect(mod.EquipmentTab).toBeDefined();
    expect(typeof mod.EquipmentTab).toBe('function');
  }, 30000);

  it('EquipmentTab has correct displayName', async () => {
    const { EquipmentTab } = await import('./EquipmentTab');
    expect(EquipmentTab.displayName).toBe('EquipmentTab');
  });
});

// ─── Test: Barrel export includes EquipmentTab ─────────────────────────────────

describe('Tab barrel export', () => {
  it('includes EquipmentTab in the tabs index', async () => {
    const mod = await import('@/components/game/tabs');
    expect(mod.EquipmentTab).toBeDefined();
    expect(typeof mod.EquipmentTab).toBe('function');
  });
});

// ─── Test: Equipment slot definitions ──────────────────────────────────────────

describe('Equipment slot definitions', () => {
  it('has exactly 8 equipment slots', async () => {
    const { EQUIPMENT_SLOTS } = await import('@/lib/game/data/equipment');
    expect(EQUIPMENT_SLOTS).toHaveLength(8);
  });

  it('all slots have display names', async () => {
    const { SLOT_NAMES, EQUIPMENT_SLOTS } = await import('@/lib/game/data/equipment');
    for (const slot of EQUIPMENT_SLOTS) {
      expect(SLOT_NAMES[slot]).toBeDefined();
      expect(SLOT_NAMES[slot].length).toBeGreaterThan(0);
    }
  });

  it('includes mainHand, offHand, head, body, hands, feet, accessory1, accessory2', async () => {
    const { EQUIPMENT_SLOTS } = await import('@/lib/game/data/equipment');
    expect(EQUIPMENT_SLOTS).toContain('mainHand');
    expect(EQUIPMENT_SLOTS).toContain('offHand');
    expect(EQUIPMENT_SLOTS).toContain('head');
    expect(EQUIPMENT_SLOTS).toContain('body');
    expect(EQUIPMENT_SLOTS).toContain('hands');
    expect(EQUIPMENT_SLOTS).toContain('feet');
    expect(EQUIPMENT_SLOTS).toContain('accessory1');
    expect(EQUIPMENT_SLOTS).toContain('accessory2');
  });
});

// ─── Test: Equipment type definitions ──────────────────────────────────────────

describe('Equipment type definitions', () => {
  it('all equipment types have required fields', async () => {
    const { EQUIPMENT_TYPES } = await import('@/lib/game/data/equipment');
    for (const [id, type] of Object.entries(EQUIPMENT_TYPES)) {
      expect(type.id).toBe(id);
      expect(type.name).toBeTruthy();
      expect(type.category).toBeTruthy();
      expect(type.slot).toBeTruthy();
      expect(type.baseCapacity).toBeGreaterThan(0);
    }
  });

  it('accessory category types can equip in accessory slots', async () => {
    const { EQUIPMENT_TYPES, getValidSlotsForEquipmentType } = await import('@/lib/game/data/equipment');
    const accessories = Object.values(EQUIPMENT_TYPES).filter((t) => t.category === 'accessory');
    expect(accessories.length).toBeGreaterThan(0);
    for (const acc of accessories) {
      const slots = getValidSlotsForEquipmentType(acc);
      expect(slots).toContain('accessory1');
      expect(slots).toContain('accessory2');
    }
  });
});

// ─── Test: Starting equipment ──────────────────────────────────────────────────

describe('Starting equipment', () => {
  it('crafting store initial state has valid equippedInstances', async () => {
    const { useCraftingStore } = await import('@/lib/game/stores/craftingStore');
    const state = useCraftingStore.getState();

    expect(state.equippedInstances.mainHand).toBeTruthy();
    expect(state.equippedInstances.body).toBeTruthy();
    expect(state.equippedInstances.feet).toBeTruthy();
    expect(state.equippedInstances.offHand).toBeNull();
    expect(state.equippedInstances.head).toBeNull();
    expect(state.equippedInstances.hands).toBeNull();
    expect(state.equippedInstances.accessory1).toBeNull();
    expect(state.equippedInstances.accessory2).toBeNull();

    expect(Object.keys(state.equipmentInstances).length).toBe(3);
  });

  it('starting equipment instances have valid fields', async () => {
    const { useCraftingStore } = await import('@/lib/game/stores/craftingStore');
    const { equipmentInstances } = useCraftingStore.getState();

    for (const instance of Object.values(equipmentInstances)) {
      expect(instance.instanceId).toBeTruthy();
      expect(instance.typeId).toBeTruthy();
      expect(instance.name).toBeTruthy();
      expect(instance.rarity).toBe('common');
      expect(instance.quality).toBe(100);
      expect(instance.usedCapacity).toBeGreaterThanOrEqual(0);
      expect(instance.totalCapacity).toBeGreaterThan(0);
    }
  });
});

// ─── Test: Equipment actions ───────────────────────────────────────────────────

describe('Equipment actions', () => {
  it('equipItem is a function', async () => {
    const { equipItem } = await import('@/lib/game/crafting-actions/equipment-actions');
    expect(typeof equipItem).toBe('function');
  });

  it('unequipItem is a function', async () => {
    const { unequipItem } = await import('@/lib/game/crafting-actions/equipment-actions');
    expect(typeof unequipItem).toBe('function');
  });

  it('deleteEquipmentInstance is a function', async () => {
    const { deleteEquipmentInstance } = await import('@/lib/game/crafting-actions/equipment-actions');
    expect(typeof deleteEquipmentInstance).toBe('function');
  });

  it('createEquipmentInstance is a function', async () => {
    const { createEquipmentInstance } = await import('@/lib/game/crafting-actions/equipment-actions');
    expect(typeof createEquipmentInstance).toBe('function');
  });
});

// ─── Test: Equipment effects ───────────────────────────────────────────────────

describe('Equipment effects computation', () => {
  it('computeEquipmentEffects returns empty for no equipment', async () => {
    const { computeEquipmentEffects } = await import('@/lib/game/effects');
    const result = computeEquipmentEffects({}, { mainHand: null, offHand: null, head: null, body: null, hands: null, feet: null, accessory1: null, accessory2: null });
    expect(Object.keys(result.bonuses)).toHaveLength(0);
    expect(Object.keys(result.multipliers)).toHaveLength(0);
    expect(result.specials.size).toBe(0);
  });

  it('computeEquipmentEffects detects enchantment bonuses', async () => {
    const { computeEquipmentEffects } = await import('@/lib/game/effects');
    const instances = {
      test1: {
        instanceId: 'test1',
        typeId: 'basicStaff',
        name: 'Test Staff',
        enchantments: [{ effectId: 'spell_manaBolt', stacks: 1, actualCost: 50 }],
        usedCapacity: 50,
        totalCapacity: 50,
        rarity: 'common' as const,
        quality: 100,
        tags: [],
      },
    };
    const equipped = { mainHand: 'test1', offHand: null, head: null, body: null, hands: null, feet: null, accessory1: null, accessory2: null };
    const result = computeEquipmentEffects(instances, equipped);
    // Should at least not crash and return a valid structure
    expect(result).toHaveProperty('bonuses');
    expect(result).toHaveProperty('multipliers');
    expect(result).toHaveProperty('specials');
  });
});

// ─── Test: File size limits ────────────────────────────────────────────────────

describe('File size limits (400 lines max)', () => {
  it('EquipmentTab.tsx is under 400 lines', async () => {
    const fs = await import('fs');
    const path = await import('path');
    const filePath = path.join(__dirname, 'EquipmentTab.tsx');
    const content = fs.readFileSync(filePath, 'utf-8');
    const lines = content.split('\n').length;
    expect(lines).toBeLessThan(400);
  });

  it('EquipmentSlotGrid.tsx is under 400 lines', async () => {
    const fs = await import('fs');
    const path = await import('path');
    const filePath = path.join(__dirname, 'EquipmentTab/EquipmentSlotGrid.tsx');
    const content = fs.readFileSync(filePath, 'utf-8');
    const lines = content.split('\n').length;
    expect(lines).toBeLessThan(400);
  });

  it('InventoryList.tsx is under 400 lines', async () => {
    const fs = await import('fs');
    const path = await import('path');
    const filePath = path.join(__dirname, 'EquipmentTab/InventoryList.tsx');
    const content = fs.readFileSync(filePath, 'utf-8');
    const lines = content.split('\n').length;
    expect(lines).toBeLessThan(400);
  });

  it('EquipmentEffectsSummary.tsx is under 400 lines', async () => {
    const fs = await import('fs');
    const path = await import('path');
    const filePath = path.join(__dirname, 'EquipmentTab/EquipmentEffectsSummary.tsx');
    const content = fs.readFileSync(filePath, 'utf-8');
    const lines = content.split('\n').length;
    expect(lines).toBeLessThan(400);
  });
});
