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

import 'package:design_system/design_system.dart';

void main() {
  // ── Existing widget tests ────────────────────────────────────────────────

  group('KcStatusChip', () {
    testWidgets('renders label text', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Scaffold(
            body: KcStatusChip(label: 'Active', background: Colors.green, foreground: Colors.white),
          ),
        ),
      );

      expect(find.text('Active'), findsOneWidget);
    });
  });

  group('KcCard', () {
    testWidgets('renders child widget', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Scaffold(body: KcCard(child: Text('Hello'))),
        ),
      );

      expect(find.text('Hello'), findsOneWidget);
    });
  });

  group('buildKcTheme', () {
    test('returns a ThemeData', () {
      final theme = buildKcTheme();
      expect(theme, isA<ThemeData>());
    });

    test('theme uses KcTypography scale', () {
      final theme = buildKcTheme();
      expect(theme.textTheme.headlineMedium?.fontSize, 28);
      expect(theme.textTheme.headlineMedium?.fontWeight, FontWeight.w700);
      expect(theme.textTheme.titleLarge?.fontSize, 20);
      expect(theme.textTheme.bodyLarge?.fontSize, 16);
      expect(theme.textTheme.bodyMedium?.fontSize, 14);
    });
  });

  // ── KcTypography tests ───────────────────────────────────────────────────

  group('KcTypography', () {
    test('displayLarge has expected properties', () {
      expect(KcTypography.displayLarge.fontSize, 57);
      expect(KcTypography.displayLarge.fontWeight, FontWeight.w400);
      expect(KcTypography.displayLarge.color, KcColors.deepTeal);
    });

    test('headlineMedium has expected properties', () {
      expect(KcTypography.headlineMedium.fontSize, 28);
      expect(KcTypography.headlineMedium.fontWeight, FontWeight.w700);
    });

    test('titleLarge has expected properties', () {
      expect(KcTypography.titleLarge.fontSize, 20);
      expect(KcTypography.titleLarge.fontWeight, FontWeight.w600);
    });

    test('bodyLarge has expected properties', () {
      expect(KcTypography.bodyLarge.fontSize, 16);
      expect(KcTypography.bodyLarge.fontWeight, FontWeight.w400);
    });

    test('bodySmall has expected properties', () {
      expect(KcTypography.bodySmall.fontSize, 12);
    });

    test('labelSmall has expected properties', () {
      expect(KcTypography.labelSmall.fontSize, 11);
      expect(KcTypography.labelSmall.letterSpacing, 0.5);
    });

    test('applyKcTypography produces a complete TextTheme', () {
      final textTheme = KcTypography.applyKcTypography();
      expect(textTheme.displayLarge, KcTypography.displayLarge);
      expect(textTheme.displayMedium, KcTypography.displayMedium);
      expect(textTheme.displaySmall, KcTypography.displaySmall);
      expect(textTheme.headlineLarge, KcTypography.headlineLarge);
      expect(textTheme.headlineMedium, KcTypography.headlineMedium);
      expect(textTheme.headlineSmall, KcTypography.headlineSmall);
      expect(textTheme.titleLarge, KcTypography.titleLarge);
      expect(textTheme.titleMedium, KcTypography.titleMedium);
      expect(textTheme.titleSmall, KcTypography.titleSmall);
      expect(textTheme.bodyLarge, KcTypography.bodyLarge);
      expect(textTheme.bodyMedium, KcTypography.bodyMedium);
      expect(textTheme.bodySmall, KcTypography.bodySmall);
      expect(textTheme.labelLarge, KcTypography.labelLarge);
      expect(textTheme.labelMedium, KcTypography.labelMedium);
      expect(textTheme.labelSmall, KcTypography.labelSmall);
    });

    test('applyKcTypography can merge with an existing TextTheme', () {
      const base = TextTheme(displayLarge: TextStyle(fontSize: 100));
      final textTheme = KcTypography.applyKcTypography(base);
      // Should override the base
      expect(textTheme.displayLarge?.fontSize, 57);
    });
  });

  // ── KcBreakpoints tests ──────────────────────────────────────────────────

  group('KcBreakpoints', () {
    test('isCompact returns true below 600', () {
      expect(KcBreakpoints.isCompact(599), true);
      expect(KcBreakpoints.isCompact(600), false);
    });

    test('isMedium returns true between 600 and 900', () {
      expect(KcBreakpoints.isMedium(600), true);
      expect(KcBreakpoints.isMedium(899), true);
      expect(KcBreakpoints.isMedium(900), false);
      expect(KcBreakpoints.isMedium(599), false);
    });

    test('isExpanded returns true between 900 and 1200', () {
      expect(KcBreakpoints.isExpanded(900), true);
      expect(KcBreakpoints.isExpanded(1199), true);
      expect(KcBreakpoints.isExpanded(1200), false);
    });

    test('isLarge returns true at 1200 and above', () {
      expect(KcBreakpoints.isLarge(1200), true);
      expect(KcBreakpoints.isLarge(1199), false);
    });

    test('isMobile returns true below 600', () {
      expect(KcBreakpoints.isMobile(400), true);
      expect(KcBreakpoints.isMobile(600), false);
    });

    test('isDesktop returns true at 900 and above', () {
      expect(KcBreakpoints.isDesktop(900), true);
      expect(KcBreakpoints.isDesktop(899), false);
    });

    test('isTabletOrLarger returns true at 900 and above', () {
      expect(KcBreakpoints.isTabletOrLarger(900), true);
      expect(KcBreakpoints.isTabletOrLarger(899), false);
    });

    test('isTablet matches isMedium range', () {
      expect(KcBreakpoints.isTablet(700), true);
      expect(KcBreakpoints.isTablet(500), false);
      expect(KcBreakpoints.isTablet(900), false);
    });

    test('gridColumns returns correct count for each range', () {
      expect(KcBreakpoints.gridColumns(400), 1);
      expect(KcBreakpoints.gridColumns(700), 2);
      expect(KcBreakpoints.gridColumns(1000), 3);
      expect(KcBreakpoints.gridColumns(1300), 4);
    });

    test('gridColumns boundary values', () {
      expect(KcBreakpoints.gridColumns(599), 1);
      expect(KcBreakpoints.gridColumns(600), 2);
      expect(KcBreakpoints.gridColumns(899), 2);
      expect(KcBreakpoints.gridColumns(900), 3);
      expect(KcBreakpoints.gridColumns(1199), 3);
      expect(KcBreakpoints.gridColumns(1200), 4);
    });
  });

  // ── KcEmptyState tests ───────────────────────────────────────────────────

  group('KcEmptyState', () {
    testWidgets('renders icon and message', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Scaffold(
            body: KcEmptyState(icon: Icons.inbox, message: 'No items yet'),
          ),
        ),
      );

      expect(find.byIcon(Icons.inbox), findsOneWidget);
      expect(find.text('No items yet'), findsOneWidget);
    });

    testWidgets('renders optional action widget', (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: KcEmptyState(
              icon: Icons.inbox,
              message: 'No items yet',
              action: ElevatedButton(onPressed: () {}, child: const Text('Add Item')),
            ),
          ),
        ),
      );

      expect(find.text('Add Item'), findsOneWidget);
    });

    testWidgets('does not render action when null', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Scaffold(
            body: KcEmptyState(icon: Icons.inbox, message: 'No items yet'),
          ),
        ),
      );

      expect(find.byType(ElevatedButton), findsNothing);
    });
  });

  // ── KcErrorState tests ───────────────────────────────────────────────────

  group('KcErrorState', () {
    testWidgets('renders error icon and message', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Scaffold(body: KcErrorState(message: 'Something went wrong')),
        ),
      );

      expect(find.byIcon(Icons.error_outline), findsOneWidget);
      expect(find.text('Something went wrong'), findsOneWidget);
    });

    testWidgets('renders retry button when onRetry is provided', (WidgetTester tester) async {
      var retried = false;
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: KcErrorState(message: 'Failed to load', onRetry: () => retried = true),
          ),
        ),
      );

      expect(find.text('Retry'), findsOneWidget);
      await tester.tap(find.text('Retry'));
      expect(retried, true);
    });

    testWidgets('does not render retry button when onRetry is null', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Scaffold(body: KcErrorState(message: 'Error occurred')),
        ),
      );

      expect(find.text('Retry'), findsNothing);
    });
  });

  // ── KcLoadingState tests ─────────────────────────────────────────────────

  group('KcLoadingState', () {
    testWidgets('renders a CircularProgressIndicator', (WidgetTester tester) async {
      await tester.pumpWidget(const MaterialApp(home: Scaffold(body: KcLoadingState())));

      expect(find.byType(CircularProgressIndicator), findsOneWidget);
    });

    testWidgets('renders optional message', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Scaffold(body: KcLoadingState(message: 'Loading data...')),
        ),
      );

      expect(find.text('Loading data...'), findsOneWidget);
    });

    testWidgets('does not render message when null', (WidgetTester tester) async {
      await tester.pumpWidget(const MaterialApp(home: Scaffold(body: KcLoadingState())));

      // Only the progress indicator, no text widget for message.
      expect(find.byType(Text), findsNothing);
    });
  });

  // ── KcSectionHeader tests ────────────────────────────────────────────────

  group('KcSectionHeader', () {
    testWidgets('renders title text', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Scaffold(body: KcSectionHeader(title: 'My Section')),
        ),
      );

      expect(find.text('My Section'), findsOneWidget);
    });

    testWidgets('renders optional action widget', (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: KcSectionHeader(
              title: 'Section',
              action: TextButton(onPressed: () {}, child: const Text('View All')),
            ),
          ),
        ),
      );

      expect(find.text('View All'), findsOneWidget);
    });

    testWidgets('does not render action when null', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Scaffold(body: KcSectionHeader(title: 'Section')),
        ),
      );

      expect(find.byType(TextButton), findsNothing);
    });
  });

  // ── KcSummaryCard tests ──────────────────────────────────────────────────

  group('KcSummaryCard', () {
    testWidgets('renders icon, label, and value', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Scaffold(
            body: KcSummaryCard(
              icon: Icons.inventory_2,
              iconColor: Colors.blue,
              label: 'Total Products',
              value: '42',
            ),
          ),
        ),
      );

      expect(find.byIcon(Icons.inventory_2), findsOneWidget);
      expect(find.text('Total Products'), findsOneWidget);
      expect(find.text('42'), findsOneWidget);
    });

    testWidgets('is tappable when onTap is provided', (WidgetTester tester) async {
      var tapped = false;
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: KcSummaryCard(
              icon: Icons.inventory_2,
              iconColor: Colors.blue,
              label: 'Total',
              value: '10',
              onTap: () => tapped = true,
            ),
          ),
        ),
      );

      await tester.tap(find.text('10'));
      expect(tapped, true);
    });

    testWidgets('is not tappable when onTap is null', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Scaffold(
            body: KcSummaryCard(
              icon: Icons.inventory_2,
              iconColor: Colors.blue,
              label: 'Total',
              value: '10',
            ),
          ),
        ),
      );

      // Should not have a GestureDetector wrapping
      expect(find.byType(GestureDetector), findsNothing);
    });
  });

  // ── KcColors tests ───────────────────────────────────────────────────────

  group('KcColors', () {
    test('brand colors are defined', () {
      expect(KcColors.skyBlue, isA<Color>());
      expect(KcColors.denimBlue, isA<Color>());
      expect(KcColors.deepTeal, isA<Color>());
      expect(KcColors.honeyGold, isA<Color>());
      expect(KcColors.sunsetOrange, isA<Color>());
    });

    test('semantic colors are defined', () {
      expect(KcColors.success, isA<Color>());
      expect(KcColors.warning, isA<Color>());
      expect(KcColors.danger, isA<Color>());
      expect(KcColors.neutral, isA<Color>());
    });
  });

  // ── KcSpacing tests ──────────────────────────────────────────────────────

  group('KcSpacing', () {
    test('spacing scale is ordered correctly', () {
      expect(KcSpacing.xs, lessThan(KcSpacing.sm));
      expect(KcSpacing.sm, lessThan(KcSpacing.md));
      expect(KcSpacing.md, lessThan(KcSpacing.lg));
      expect(KcSpacing.lg, lessThan(KcSpacing.xl));
    });

    test('spacing values match expected constants', () {
      expect(KcSpacing.xs, 4.0);
      expect(KcSpacing.sm, 8.0);
      expect(KcSpacing.md, 16.0);
      expect(KcSpacing.lg, 24.0);
      expect(KcSpacing.xl, 32.0);
    });
  });
}
