import 'package:flutter_test/flutter_test.dart';

import 'package:feature_inventory/feature_inventory.dart';
import 'package:feature_inventory/src/application/get_inventory_items.dart';
import 'package:feature_inventory/src/application/inventory_controller.dart';

void main() {
  group('InventoryStatus', () {
    test('has four values', () {
      expect(InventoryStatus.values.length, 4);
    });

    test('contains expected statuses', () {
      expect(InventoryStatus.values, contains(InventoryStatus.inStock));
      expect(InventoryStatus.values, contains(InventoryStatus.lowStock));
      expect(InventoryStatus.values, contains(InventoryStatus.outOfStock));
      expect(InventoryStatus.values, contains(InventoryStatus.draft));
    });
  });

  group('FakeInventoryRepository', () {
    late FakeInventoryRepository repository;

    setUp(() {
      repository = FakeInventoryRepository();
    });

    test('returns six sample items', () async {
      final items = await repository.getInventoryItems();
      expect(items.length, 6);
    });

    test('returns items with expected names', () async {
      final items = await repository.getInventoryItems();
      final names = items.map((i) => i.name).toList();
      expect(names, contains('Floral Bowl Cozy'));
      expect(names, contains('Citrus Coaster Set'));
      expect(names, contains('Ocean Nightlight'));
    });
  });

  group('InventoryController', () {
    late FakeInventoryRepository repository;
    late InventoryController controller;

    setUp(() {
      repository = FakeInventoryRepository();
      controller = InventoryController(GetInventoryItems(repository));
    });

    tearDown(() {
      controller.dispose();
    });

    test('starts with empty state', () {
      expect(controller.isLoading, false);
      expect(controller.items, isEmpty);
      expect(controller.selectedItem, isNull);
      expect(controller.activeFilter, isNull);
      expect(controller.searchQuery, '');
      expect(controller.error, isNull);
    });

    test('load populates items', () async {
      await controller.load();

      expect(controller.isLoading, false);
      expect(controller.items.length, 6);
      expect(controller.error, isNull);
    });

    test('setFilter filters by status', () async {
      await controller.load();

      controller.setFilter('lowStock');
      expect(controller.items.length, 2);
      expect(controller.items.every((i) => i.status == InventoryStatus.lowStock), true);
    });

    test('setFilter with null shows all items', () async {
      await controller.load();

      controller.setFilter('lowStock');
      expect(controller.items.length, 2);

      controller.setFilter(null);
      expect(controller.items.length, 6);
    });

    test('setSearchQuery filters by name', () async {
      await controller.load();

      controller.setSearchQuery('cozy');
      expect(controller.items.length, 1);
      expect(controller.items.first.name, 'Floral Bowl Cozy');
    });

    test('setSearchQuery filters by SKU', () async {
      await controller.load();

      controller.setSearchQuery('BC-FLR');
      expect(controller.items.length, 1);
      expect(controller.items.first.sku, 'BC-FLR-001');
    });

    test('search is case-insensitive', () async {
      await controller.load();

      controller.setSearchQuery('OCEAN');
      expect(controller.items.length, 1);
      expect(controller.items.first.name, 'Ocean Nightlight');
    });

    test('filter and search combine', () async {
      await controller.load();

      controller.setFilter('inStock');
      controller.setSearchQuery('floral');
      expect(controller.items.length, 1);
      expect(controller.items.first.name, 'Floral Bowl Cozy');
    });

    test('selectItem sets selectedItem', () async {
      await controller.load();

      final item = controller.items[2];
      controller.selectItem(item);
      expect(controller.selectedItem, item);
    });

    test('selectBySku selects matching item', () async {
      await controller.load();

      final found = controller.selectBySku('CS-CIT-002');
      expect(found, true);
      expect(controller.selectedItem!.sku, 'CS-CIT-002');
    });

    test('selectBySku returns false for unknown SKU', () async {
      await controller.load();

      final found = controller.selectBySku('UNKNOWN');
      expect(found, false);
      expect(controller.selectedItem, isNull);
    });

    test('selection is cleared when filtered out', () async {
      await controller.load();

      // Select an inStock item.
      controller.selectBySku('BC-FLR-001');
      expect(controller.selectedItem, isNotNull);

      // Filter to lowStock — the selected item should be cleared.
      controller.setFilter('lowStock');
      expect(controller.selectedItem, isNull);
    });
  });
}
