import 'package:design_system/design_system.dart';
import 'package:feature_inventory/feature_inventory.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

// ── Helpers ────────────────────────────────────────────────────────────────────

Widget _wrap(Widget child) {
  return MaterialApp(
    theme: buildKcTheme(),
    home: Scaffold(body: child),
  );
}

InventoryItem _makeItem({
  String id = 'test-1',
  String sku = 'TEST-001',
  String name = 'Test Item',
  String description = 'A test item description',
  String imageUrl = '',
  String category = 'Test Category',
  int quantityOnHand = 10,
  double unitPrice = 9.99,
  int reorderPoint = 3,
  String? supplier,
  String? location,
  InventoryStatus status = InventoryStatus.inStock,
  DateTime? lastUpdated,
}) {
  return InventoryItem(
    id: id,
    sku: sku,
    name: name,
    description: description,
    imageUrl: imageUrl,
    category: category,
    quantityOnHand: quantityOnHand,
    unitPrice: unitPrice,
    reorderPoint: reorderPoint,
    supplier: supplier,
    location: location,
    status: status,
    lastUpdated: lastUpdated ?? DateTime(2026, 7, 1),
  );
}

// ── InventoryStatusChip ────────────────────────────────────────────────────────

void main() {
  group('InventoryStatusChip', () {
    testWidgets('shows In Stock label for inStock status', (tester) async {
      await tester.pumpWidget(_wrap(const InventoryStatusChip(status: InventoryStatus.inStock)));
      expect(find.text('In Stock'), findsOneWidget);
    });

    testWidgets('shows Low Stock label for lowStock status', (tester) async {
      await tester.pumpWidget(_wrap(const InventoryStatusChip(status: InventoryStatus.lowStock)));
      expect(find.text('Low Stock'), findsOneWidget);
    });

    testWidgets('shows Out of Stock label for outOfStock status', (tester) async {
      await tester.pumpWidget(_wrap(const InventoryStatusChip(status: InventoryStatus.outOfStock)));
      expect(find.text('Out of Stock'), findsOneWidget);
    });

    testWidgets('shows Draft label for draft status', (tester) async {
      await tester.pumpWidget(_wrap(const InventoryStatusChip(status: InventoryStatus.draft)));
      expect(find.text('Draft'), findsOneWidget);
    });
  });

  // ── InventoryDetailPanel ─────────────────────────────────────────────────────

  group('InventoryDetailPanel', () {
    testWidgets('displays item name and SKU', (tester) async {
      final item = _makeItem(name: 'Floral Bowl Cozy', sku: 'BC-FLR-001');
      await tester.pumpWidget(_wrap(InventoryDetailPanel(item: item, isUpdating: false)));
      expect(find.text('Floral Bowl Cozy'), findsOneWidget);
      expect(find.text('SKU: BC-FLR-001'), findsOneWidget);
    });

    testWidgets('displays description when non-empty', (tester) async {
      final item = _makeItem(description: 'Hand-sewn fabric bowl cozy.');
      await tester.pumpWidget(_wrap(InventoryDetailPanel(item: item, isUpdating: false)));
      expect(find.text('Hand-sewn fabric bowl cozy.'), findsOneWidget);
    });

    testWidgets('displays quantity on hand', (tester) async {
      final item = _makeItem(quantityOnHand: 18);
      await tester.pumpWidget(_wrap(InventoryDetailPanel(item: item, isUpdating: false)));
      expect(find.text('18'), findsOneWidget);
    });

    testWidgets('displays unit price formatted', (tester) async {
      final item = _makeItem(unitPrice: 12.99);
      await tester.pumpWidget(_wrap(InventoryDetailPanel(item: item, isUpdating: false)));
      expect(find.text('\$12.99'), findsOneWidget);
    });

    testWidgets('shows Adjust Quantity button when not updating', (tester) async {
      final item = _makeItem();
      await tester.pumpWidget(
        _wrap(InventoryDetailPanel(item: item, isUpdating: false, onAdjustQuantity: () {})),
      );
      expect(find.text('Adjust Quantity'), findsOneWidget);
    });

    testWidgets('shows loading indicator when isUpdating is true', (tester) async {
      final item = _makeItem();
      await tester.pumpWidget(_wrap(InventoryDetailPanel(item: item, isUpdating: true)));
      expect(find.byType(CircularProgressIndicator), findsOneWidget);
      expect(find.text('Adjust Quantity'), findsNothing);
    });

    testWidgets('calls onAdjustQuantity when button tapped', (tester) async {
      var called = false;
      final item = _makeItem();
      await tester.pumpWidget(
        _wrap(
          InventoryDetailPanel(
            item: item,
            isUpdating: false,
            onAdjustQuantity: () => called = true,
          ),
        ),
      );
      await tester.tap(find.text('Adjust Quantity'));
      expect(called, true);
    });

    testWidgets('shows View Product button when onViewProduct provided', (tester) async {
      final item = _makeItem();
      await tester.pumpWidget(
        _wrap(InventoryDetailPanel(item: item, isUpdating: false, onViewProduct: () {})),
      );
      expect(find.text('View Product'), findsOneWidget);
    });

    testWidgets('hides View Product button when onViewProduct is null', (tester) async {
      final item = _makeItem();
      await tester.pumpWidget(_wrap(InventoryDetailPanel(item: item, isUpdating: false)));
      expect(find.text('View Product'), findsNothing);
    });

    testWidgets('shows location and supplier when provided', (tester) async {
      final item = _makeItem(location: 'Shelf A1', supplier: 'Kell Creations');
      await tester.pumpWidget(
        _wrap(SingleChildScrollView(child: InventoryDetailPanel(item: item, isUpdating: false))),
      );
      await tester.pump();
      expect(find.text('Shelf A1'), findsOneWidget);
      expect(find.text('Kell Creations'), findsOneWidget);
    });

    testWidgets('shows status chip', (tester) async {
      final item = _makeItem(status: InventoryStatus.lowStock);
      await tester.pumpWidget(_wrap(InventoryDetailPanel(item: item, isUpdating: false)));
      expect(find.text('Low Stock'), findsOneWidget);
    });
  });

  // ── InventoryPage ────────────────────────────────────────────────────────────

  group('InventoryPage', () {
    testWidgets('shows loading state initially', (tester) async {
      final repo = FakeInventoryRepository();
      await tester.pumpWidget(_wrap(InventoryPage(repository: repo)));
      // Pump one frame — the async load has started but not completed.
      await tester.pump();
      expect(find.byType(CircularProgressIndicator), findsOneWidget);
      // Let the pending timer complete so the test teardown is clean.
      await tester.pumpAndSettle();
    });

    testWidgets('shows search bar after load', (tester) async {
      final repo = FakeInventoryRepository();
      await tester.pumpWidget(_wrap(InventoryPage(repository: repo)));
      await tester.pumpAndSettle();
      expect(find.byType(TextField), findsOneWidget);
    });

    testWidgets('shows filter chips after load', (tester) async {
      final repo = FakeInventoryRepository();
      await tester.pumpWidget(_wrap(InventoryPage(repository: repo)));
      await tester.pumpAndSettle();
      expect(find.byType(FilterChip), findsWidgets);
      expect(find.text('All'), findsOneWidget);
      expect(find.text('In Stock'), findsOneWidget);
      expect(find.text('Low Stock'), findsOneWidget);
    });

    testWidgets('shows item count after load', (tester) async {
      final repo = FakeInventoryRepository();
      await tester.pumpWidget(_wrap(InventoryPage(repository: repo)));
      await tester.pumpAndSettle();
      expect(find.text('6 items'), findsOneWidget);
    });

    testWidgets('shows item cards after load', (tester) async {
      final repo = FakeInventoryRepository();
      await tester.pumpWidget(_wrap(InventoryPage(repository: repo)));
      await tester.pumpAndSettle();
      expect(find.byType(InventoryItemCard), findsWidgets);
    });

    testWidgets('search filters items by name', (tester) async {
      final repo = FakeInventoryRepository();
      await tester.pumpWidget(_wrap(InventoryPage(repository: repo)));
      await tester.pumpAndSettle();

      await tester.enterText(find.byType(TextField), 'cozy');
      await tester.pump();

      expect(find.text('1 item'), findsOneWidget);
    });

    testWidgets('filter chip filters items by status', (tester) async {
      final repo = FakeInventoryRepository();
      await tester.pumpWidget(_wrap(InventoryPage(repository: repo)));
      await tester.pumpAndSettle();

      await tester.tap(find.text('Low Stock').first);
      await tester.pump();

      expect(find.text('2 items'), findsOneWidget);
    });

    testWidgets('applies initialFilter on load', (tester) async {
      final repo = FakeInventoryRepository();
      await tester.pumpWidget(_wrap(InventoryPage(repository: repo, initialFilter: 'inStock')));
      await tester.pumpAndSettle();
      // 2 inStock items in seed data (items 1 and 4)
      expect(find.text('2 items'), findsOneWidget);
    });

    testWidgets('applies initialQuery on load', (tester) async {
      final repo = FakeInventoryRepository();
      await tester.pumpWidget(_wrap(InventoryPage(repository: repo, initialQuery: 'ocean')));
      await tester.pumpAndSettle();
      expect(find.text('1 item'), findsOneWidget);
    });
  });

  // ── AdjustQuantityDialogResult ────────────────────────────────────────────────

  group('AdjustQuantityDialogResult', () {
    test('stores delta and reason', () {
      const result = AdjustQuantityDialogResult(delta: 5, reason: 'restock');
      expect(result.delta, 5);
      expect(result.reason, 'restock');
    });

    test('stores negative delta for removal', () {
      const result = AdjustQuantityDialogResult(delta: -3, reason: 'sold');
      expect(result.delta, -3);
      expect(result.reason, 'sold');
    });
  });
}
