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

import 'package:feature_wordpress/feature_wordpress.dart';

/// A repository that always throws on [getProductDrafts] to exercise the
/// error state. Kept test-local to avoid broadening the public API.
class _FailingRepository implements ProductPublishingRepository {
  int loadAttempts = 0;

  @override
  Future<List<ProductDraft>> getProductDrafts() async {
    loadAttempts++;
    throw Exception('network error');
  }

  @override
  Future<ProductDraft> publishDraft(String id) async => throw UnimplementedError();

  @override
  Future<ProductDraft> updateProductStatus(String id, PublishStatus status) async =>
      throw UnimplementedError();

  @override
  Future<ProductDraft> updateProductPrice(String id, double price) async =>
      throw UnimplementedError();

  @override
  Future<ProductDraft> updateProductName(String id, String name) async =>
      throw UnimplementedError();

  @override
  Future<ProductDraft> updateProductDescription(String id, String description) async =>
      throw UnimplementedError();

  @override
  Future<ProductDraft> updateProductCategory(String id, String category) async =>
      throw UnimplementedError();
}

void main() {
  group('ProductPublishingPage polish states', () {
    // ── Loading state ──────────────────────────────────────────────────────

    testWidgets('shows loading indicator with contextual text', (tester) async {
      // Use a narrow viewport to keep the layout simple.
      tester.view.physicalSize = const Size(600, 800);
      tester.view.devicePixelRatio = 1.0;
      addTearDown(tester.view.resetPhysicalSize);
      addTearDown(tester.view.resetDevicePixelRatio);

      final repository = FakeProductPublishingRepository();

      await tester.pumpWidget(
        MaterialApp(
          theme: buildKcTheme(),
          home: Scaffold(body: ProductPublishingPage(repository: repository)),
        ),
      );

      // Before pumpAndSettle — the controller is still loading.
      expect(find.byType(CircularProgressIndicator), findsOneWidget);
      expect(find.text('Loading products…'), findsOneWidget);

      // Let the load complete so the test tears down cleanly.
      await tester.pumpAndSettle();
    });

    // ── Error state ────────────────────────────────────────────────────────

    testWidgets('shows error state with retry button', (tester) async {
      tester.view.physicalSize = const Size(600, 800);
      tester.view.devicePixelRatio = 1.0;
      addTearDown(tester.view.resetPhysicalSize);
      addTearDown(tester.view.resetDevicePixelRatio);

      final repository = _FailingRepository();

      await tester.pumpWidget(
        MaterialApp(
          theme: buildKcTheme(),
          home: Scaffold(body: ProductPublishingPage(repository: repository)),
        ),
      );
      await tester.pumpAndSettle();

      expect(find.text('Failed to load product drafts.'), findsOneWidget);
      expect(find.byIcon(Icons.error_outline), findsOneWidget);
      expect(find.text('Retry'), findsOneWidget);
      expect(repository.loadAttempts, 1);
    });

    testWidgets('retry button triggers a new load attempt', (tester) async {
      tester.view.physicalSize = const Size(600, 800);
      tester.view.devicePixelRatio = 1.0;
      addTearDown(tester.view.resetPhysicalSize);
      addTearDown(tester.view.resetDevicePixelRatio);

      final repository = _FailingRepository();

      await tester.pumpWidget(
        MaterialApp(
          theme: buildKcTheme(),
          home: Scaffold(body: ProductPublishingPage(repository: repository)),
        ),
      );
      await tester.pumpAndSettle();

      expect(repository.loadAttempts, 1);

      await tester.tap(find.text('Retry'));
      await tester.pumpAndSettle();

      expect(repository.loadAttempts, 2);
    });

    // ── Empty list state (filtered to zero results) ────────────────────────

    testWidgets('shows empty state when filter yields no results', (tester) async {
      tester.view.physicalSize = const Size(600, 800);
      tester.view.devicePixelRatio = 1.0;
      addTearDown(tester.view.resetPhysicalSize);
      addTearDown(tester.view.resetDevicePixelRatio);

      final repository = FakeProductPublishingRepository();

      // Use a search query that matches nothing.
      await tester.pumpWidget(
        MaterialApp(
          theme: buildKcTheme(),
          home: Scaffold(
            body: ProductPublishingPage(repository: repository, initialQuery: 'zzz_no_match_zzz'),
          ),
        ),
      );
      await tester.pumpAndSettle();

      expect(find.text('No products match your criteria.'), findsOneWidget);
      expect(find.byIcon(Icons.search_off), findsOneWidget);
    });

    // ── Product count header ───────────────────────────────────────────────

    testWidgets('shows product count header on narrow layout', (tester) async {
      tester.view.physicalSize = const Size(600, 800);
      tester.view.devicePixelRatio = 1.0;
      addTearDown(tester.view.resetPhysicalSize);
      addTearDown(tester.view.resetDevicePixelRatio);

      final repository = FakeProductPublishingRepository();

      await tester.pumpWidget(
        MaterialApp(
          theme: buildKcTheme(),
          home: Scaffold(body: ProductPublishingPage(repository: repository)),
        ),
      );
      await tester.pumpAndSettle();

      // The fake repository has 6 products.
      expect(find.text('6 products'), findsOneWidget);
    });

    testWidgets('shows singular product count when filtered to one', (tester) async {
      tester.view.physicalSize = const Size(600, 800);
      tester.view.devicePixelRatio = 1.0;
      addTearDown(tester.view.resetPhysicalSize);
      addTearDown(tester.view.resetDevicePixelRatio);

      final repository = FakeProductPublishingRepository();

      // "nightlight" matches exactly one product in the fake data.
      await tester.pumpWidget(
        MaterialApp(
          theme: buildKcTheme(),
          home: Scaffold(
            body: ProductPublishingPage(repository: repository, initialQuery: 'nightlight'),
          ),
        ),
      );
      await tester.pumpAndSettle();

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

    // ── Empty selection placeholder (wide layout) ──────────────────────────

    testWidgets('shows selection placeholder with icon on wide layout', (tester) async {
      tester.view.physicalSize = const Size(1200, 800);
      tester.view.devicePixelRatio = 1.0;
      addTearDown(tester.view.resetPhysicalSize);
      addTearDown(tester.view.resetDevicePixelRatio);

      final repository = FakeProductPublishingRepository();

      // A query that matches nothing yields empty drafts + null selection.
      // On wide layout the Row renders both panes, so we can verify both
      // the empty-list and empty-selection placeholders.
      await tester.pumpWidget(
        MaterialApp(
          theme: buildKcTheme(),
          home: Scaffold(
            body: ProductPublishingPage(repository: repository, initialQuery: 'zzz_no_match_zzz'),
          ),
        ),
      );
      await tester.pumpAndSettle();

      // The empty-list state shows in the left pane.
      expect(find.text('No products match your criteria.'), findsOneWidget);

      // The empty-selection state shows in the right pane.
      expect(find.text('Select a product to preview'), findsOneWidget);
      expect(find.byIcon(Icons.touch_app_outlined), findsOneWidget);
    });
  });
}
