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

void main() {
  Future<void> pumpConsole(
    WidgetTester tester, {
    required Size viewport,
    Widget? executionLogs,
    IopConsoleConfig? config,
    IopConsoleThemeAdapter? themeAdapter,
    IopConsoleNavigationCallback? onNavigate,
  }) async {
    tester.view.physicalSize = viewport;
    tester.view.devicePixelRatio = 1;
    addTearDown(tester.view.resetPhysicalSize);
    addTearDown(tester.view.resetDevicePixelRatio);

    await tester.pumpWidget(
      MaterialApp(
        home: IopConsoleShell(
          overview: const Center(child: Text('Overview content')),
          executionLogs: executionLogs,
          config: config,
          themeAdapter: themeAdapter,
          onNavigate: onNavigate,
        ),
      ),
    );
  }

  testWidgets('public shell renders without an app-owned console wrapper', (
    tester,
  ) async {
    await pumpConsole(tester, viewport: const Size(1024, 768));

    expect(find.text('Overview content'), findsOneWidget);
    expect(find.byIcon(Icons.dashboard_outlined), findsOneWidget);
    expect(find.byIcon(Icons.smart_toy_outlined), findsNothing);
    expect(tester.takeException(), isNull);
  });

  testWidgets('rail and content remain stable on narrow and wide viewports', (
    tester,
  ) async {
    for (final viewport in const [Size(320, 640), Size(1200, 800)]) {
      await pumpConsole(tester, viewport: viewport);

      expect(find.text('Overview content'), findsOneWidget);
      expect(find.byIcon(Icons.tune), findsOneWidget);
      expect(tester.getSize(find.byIcon(Icons.dashboard_outlined)).height, 24);
      expect(tester.takeException(), isNull);
    }
  });

  testWidgets(
    'supports navigation to executionLogs and displays injected widget',
    (tester) async {
      var navigatedSection = IopConsoleSection.overview;

      await pumpConsole(
        tester,
        viewport: const Size(1024, 768),
        executionLogs: const Center(child: Text('Custom Logs Content')),
        onNavigate: (section) => navigatedSection = section,
      );

      // Tap on Execution & Logs rail item
      await tester.tap(find.byIcon(Icons.list_alt_outlined));
      await tester.pump();

      expect(navigatedSection, IopConsoleSection.executionLogs);
      expect(find.text('Custom Logs Content'), findsOneWidget);
      expect(tester.takeException(), isNull);
    },
  );

  testWidgets(
    'IopConsoleOverview renders endpoints, status badge, and triggers refresh',
    (tester) async {
      tester.view.physicalSize = const Size(1024, 768);
      tester.view.devicePixelRatio = 1;
      addTearDown(tester.view.resetPhysicalSize);
      addTearDown(tester.view.resetDevicePixelRatio);

      const config = IopConsoleConfig(
        controlPlaneHttpUrl: 'https://api.iop.test',
        controlPlaneWireUrl: 'wss://wire.iop.test',
        authTokenReference: 'cp-auth-ref-main',
      );
      var refreshCount = 0;

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: IopConsoleOverview(
              config: config,
              statusText: 'Connected to Control Plane',
              onRefresh: () => refreshCount++,
            ),
          ),
        ),
      );

      // Check header and status badge
      expect(find.text('Operations Overview'), findsOneWidget);
      expect(find.text('CONNECTED TO CONTROL PLANE'), findsOneWidget);

      // Check config values
      expect(find.text('https://api.iop.test'), findsOneWidget);
      expect(find.text('wss://wire.iop.test'), findsOneWidget);
      // Check auth token reference key value
      expect(find.text('cp-auth-ref-main'), findsOneWidget);

      // Check refresh button functionality
      final refreshBtn = find.text('Refresh Connection');
      expect(refreshBtn, findsOneWidget);

      await tester.tap(refreshBtn);
      await tester.pump();

      expect(refreshCount, 1);
      expect(tester.takeException(), isNull);
    },
  );

  testWidgets('IopConsoleOverview handles disconnected status correctly', (
    tester,
  ) async {
    tester.view.physicalSize = const Size(1024, 768);
    tester.view.devicePixelRatio = 1;
    addTearDown(tester.view.resetPhysicalSize);
    addTearDown(tester.view.resetDevicePixelRatio);

    const config = IopConsoleConfig(
      controlPlaneHttpUrl: 'https://api.iop.test',
      controlPlaneWireUrl: 'wss://wire.iop.test',
    );

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: IopConsoleOverview(config: config, statusText: 'Disconnected'),
        ),
      ),
    );

    // Verify it displays OFFLINE status text and DISCONNECTED status badge
    expect(find.text('DISCONNECTED'), findsOneWidget);
    expect(find.text('OFFLINE'), findsOneWidget);
    expect(tester.takeException(), isNull);
  });

  testWidgets(
    'IopConsoleOverview preserves narrow and wide responsive sections',
    (tester) async {
      const config = IopConsoleConfig(
        controlPlaneHttpUrl: 'https://api.iop.test',
        controlPlaneWireUrl: 'wss://wire.iop.test',
        authTokenReference: 'cp-auth-ref-main',
      );

      // 400px width drives the narrow (< 600) layout; 1024px drives the wide one.
      for (final viewport in const [Size(400, 1200), Size(1024, 1200)]) {
        tester.view.physicalSize = viewport;
        tester.view.devicePixelRatio = 1;
        addTearDown(tester.view.resetPhysicalSize);
        addTearDown(tester.view.resetDevicePixelRatio);

        await tester.pumpWidget(
          MaterialApp(
            home: Scaffold(
              body: IopConsoleOverview(
                config: config,
                statusText: 'Connected to Control Plane',
              ),
            ),
          ),
        );
        await tester.pump();

        // Header, status badge, and endpoint sections render on both viewports.
        expect(find.text('Operations Overview'), findsOneWidget);
        expect(find.text('CONNECTED TO CONTROL PLANE'), findsOneWidget);
        expect(find.text('SYSTEM ENDPOINTS'), findsOneWidget);
        expect(find.text('https://api.iop.test'), findsOneWidget);
        expect(find.text('wss://wire.iop.test'), findsOneWidget);
        expect(tester.takeException(), isNull);
      }
    },
  );
}
