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';

void main() {
  final sampleDraft = ProductDraft(
    id: '1',
    name: 'Test Bowl Cozy',
    description: 'A beautifully crafted test product.',
    price: 12.99,
    sku: 'BC-TST-001',
    category: 'Bowl Cozies',
    imageUrl: '',
    status: PublishStatus.draft,
    lastModified: DateTime(2026, 4, 1),
  );

  final draftWithImageUrl = ProductDraft(
    id: '7',
    name: 'Product With Image',
    description: 'Has an image URL.',
    price: 25.00,
    sku: 'IMG-001',
    category: 'Bowl Cozies',
    imageUrl: 'https://example.com/product.jpg',
    status: PublishStatus.draft,
    lastModified: DateTime(2026, 4, 5),
  );

  final publishedDraft = ProductDraft(
    id: '2',
    name: 'Published Product',
    description: 'Already published.',
    price: 19.99,
    sku: 'PP-001',
    category: 'Coasters',
    imageUrl: '',
    status: PublishStatus.published,
    lastModified: DateTime(2026, 3, 28),
  );

  final pendingDraft = ProductDraft(
    id: '3',
    name: 'Pending Product',
    description: 'Awaiting review.',
    price: 14.99,
    sku: 'PR-001',
    category: 'Nightlights',
    imageUrl: '',
    status: PublishStatus.pendingReview,
    lastModified: DateTime(2026, 4, 1),
  );

  final unpublishedDraft = ProductDraft(
    id: '4',
    name: 'Unpublished Product',
    description: 'Previously published but taken down.',
    price: 9.99,
    sku: 'UP-001',
    category: 'Coasters',
    imageUrl: '',
    status: PublishStatus.unpublished,
    lastModified: DateTime(2026, 3, 20),
  );

  Widget buildTestWidget(
    ProductDraft draft, {
    VoidCallback? onPublish,
    VoidCallback? onMoveToDraft,
    ValueChanged<double>? onPriceChanged,
    ValueChanged<String>? onNameChanged,
    ValueChanged<String>? onDescriptionChanged,
    ValueChanged<String>? onCategoryChanged,
    bool isUpdating = false,
  }) {
    return MaterialApp(
      theme: buildKcTheme(),
      home: Scaffold(
        body: SingleChildScrollView(
          child: ProductPreviewPanel(
            draft: draft,
            onPublish: onPublish,
            onMoveToDraft: onMoveToDraft,
            onPriceChanged: onPriceChanged,
            onNameChanged: onNameChanged,
            onDescriptionChanged: onDescriptionChanged,
            onCategoryChanged: onCategoryChanged,
            isUpdating: isUpdating,
          ),
        ),
      ),
    );
  }

  group('ProductPreviewPanel', () {
    testWidgets('displays product name', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.text('Test Bowl Cozy'), findsOneWidget);
    });

    testWidgets('displays description', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.text('A beautifully crafted test product.'), findsOneWidget);
    });

    testWidgets('displays SKU metadata', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.text('BC-TST-001'), findsOneWidget);
    });

    testWidgets('displays price metadata', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.text('\$12.99'), findsOneWidget);
    });

    testWidgets('displays category metadata', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.text('Bowl Cozies'), findsOneWidget);
    });

    testWidgets('displays last modified date', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.text('2026-04-01'), findsOneWidget);
    });

    testWidgets('calls onPublish when button is tapped', (tester) async {
      var published = false;
      await tester.pumpWidget(buildTestWidget(sampleDraft, onPublish: () => published = true));
      await tester.tap(find.text('Publish to Store'));
      expect(published, true);
    });
  });

  group('image display', () {
    testWidgets('shows placeholder icon when imageUrl is empty', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.byIcon(Icons.image_outlined), findsOneWidget);
    });

    testWidgets('hides Image URL metadata row when imageUrl is empty', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.text('Image URL'), findsNothing);
    });

    testWidgets('shows Image URL metadata row when imageUrl is present', (tester) async {
      await tester.pumpWidget(buildTestWidget(draftWithImageUrl));
      expect(find.text('Image URL'), findsOneWidget);
      expect(find.text('https://example.com/product.jpg'), findsOneWidget);
    });

    testWidgets('renders Image.network when imageUrl is present', (tester) async {
      await tester.pumpWidget(buildTestWidget(draftWithImageUrl));
      expect(find.byType(Image), findsOneWidget);
    });

    testWidgets('does not render Image.network when imageUrl is empty', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.byType(Image), findsNothing);
    });
  });

  group('status-aware action buttons', () {
    testWidgets('draft row shows Publish to Store button', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.text('Publish to Store'), findsOneWidget);
      expect(find.text('Move to Draft'), findsNothing);
    });

    testWidgets('published row shows Move to Draft button', (tester) async {
      await tester.pumpWidget(buildTestWidget(publishedDraft));
      expect(find.text('Move to Draft'), findsOneWidget);
      expect(find.text('Publish to Store'), findsNothing);
    });

    testWidgets('pending review row shows Move to Draft button', (tester) async {
      await tester.pumpWidget(buildTestWidget(pendingDraft));
      expect(find.text('Move to Draft'), findsOneWidget);
      expect(find.text('Publish to Store'), findsNothing);
    });

    testWidgets('calls onMoveToDraft when Move to Draft is tapped for pending review', (
      tester,
    ) async {
      var movedToDraft = false;
      await tester.pumpWidget(
        buildTestWidget(pendingDraft, onMoveToDraft: () => movedToDraft = true),
      );
      await tester.tap(find.text('Move to Draft'));
      expect(movedToDraft, true);
    });

    testWidgets('calls onMoveToDraft when Move to Draft is tapped', (tester) async {
      var movedToDraft = false;
      await tester.pumpWidget(
        buildTestWidget(publishedDraft, onMoveToDraft: () => movedToDraft = true),
      );
      await tester.tap(find.text('Move to Draft'));
      expect(movedToDraft, true);
    });

    testWidgets('unpublished row shows Move to Draft button', (tester) async {
      await tester.pumpWidget(buildTestWidget(unpublishedDraft));
      expect(find.text('Move to Draft'), findsOneWidget);
      expect(find.text('Publish to Store'), findsNothing);
    });

    testWidgets('calls onMoveToDraft when Move to Draft is tapped for unpublished', (tester) async {
      var movedToDraft = false;
      await tester.pumpWidget(
        buildTestWidget(unpublishedDraft, onMoveToDraft: () => movedToDraft = true),
      );
      await tester.tap(find.text('Move to Draft'));
      expect(movedToDraft, true);
    });
  });

  group('updating state', () {
    testWidgets('Publish button is disabled while updating', (tester) async {
      var tapped = false;
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, isUpdating: true, onPublish: () => tapped = true),
      );

      // The button should be present but disabled.
      expect(find.text('Publish to Store'), findsOneWidget);
      await tester.tap(find.text('Publish to Store'));
      expect(tapped, false);
    });

    testWidgets('Move to Draft button is disabled while updating', (tester) async {
      var tapped = false;
      await tester.pumpWidget(
        buildTestWidget(publishedDraft, isUpdating: true, onMoveToDraft: () => tapped = true),
      );

      // The button should be present but disabled.
      expect(find.text('Move to Draft'), findsOneWidget);
      await tester.tap(find.text('Move to Draft'));
      expect(tapped, false);
    });

    testWidgets('Move to Draft button is disabled while updating for pending review', (
      tester,
    ) async {
      var tapped = false;
      await tester.pumpWidget(
        buildTestWidget(pendingDraft, isUpdating: true, onMoveToDraft: () => tapped = true),
      );

      expect(find.text('Move to Draft'), findsOneWidget);
      await tester.tap(find.text('Move to Draft'));
      expect(tapped, false);
    });

    testWidgets('Move to Draft button is disabled while updating for unpublished', (tester) async {
      var tapped = false;
      await tester.pumpWidget(
        buildTestWidget(unpublishedDraft, isUpdating: true, onMoveToDraft: () => tapped = true),
      );

      expect(find.text('Move to Draft'), findsOneWidget);
      await tester.tap(find.text('Move to Draft'));
      expect(tapped, false);
    });

    testWidgets('shows progress indicator while updating', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, isUpdating: true));
      expect(find.byType(CircularProgressIndicator), findsOneWidget);
    });

    testWidgets('hides progress indicator when not updating', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, isUpdating: false));
      expect(find.byType(CircularProgressIndicator), findsNothing);
    });
  });

  group('price editing', () {
    testWidgets('shows edit icon when onPriceChanged is provided', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onPriceChanged: (_) {}));
      expect(find.byIcon(Icons.edit), findsOneWidget);
    });

    testWidgets('hides edit icon when onPriceChanged is null', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.byIcon(Icons.edit), findsNothing);
    });

    testWidgets('hides edit icon while updating', (tester) async {
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onPriceChanged: (_) {}, isUpdating: true),
      );
      expect(find.byIcon(Icons.edit), findsNothing);
    });

    testWidgets('tapping edit icon shows text field with current price', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onPriceChanged: (_) {}));

      await tester.tap(find.byIcon(Icons.edit));
      await tester.pump();

      expect(find.byType(TextField), findsOneWidget);
      // The text field should be pre-filled with the current price.
      final textField = tester.widget<TextField>(find.byType(TextField));
      expect(textField.controller!.text, '12.99');
    });

    testWidgets('tapping check icon submits the new price', (tester) async {
      double? receivedPrice;
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onPriceChanged: (p) => receivedPrice = p),
      );

      // Enter edit mode.
      await tester.tap(find.byIcon(Icons.edit));
      await tester.pump();

      // Clear and type a new price.
      await tester.enterText(find.byType(TextField), '15.50');
      await tester.tap(find.byIcon(Icons.check));
      await tester.pump();

      expect(receivedPrice, 15.50);
      // Should exit edit mode — no more text field.
      expect(find.byType(TextField), findsNothing);
    });

    testWidgets('tapping close icon cancels editing', (tester) async {
      double? receivedPrice;
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onPriceChanged: (p) => receivedPrice = p),
      );

      // Enter edit mode.
      await tester.tap(find.byIcon(Icons.edit));
      await tester.pump();

      // Type a new price but cancel.
      await tester.enterText(find.byType(TextField), '99.99');
      await tester.tap(find.byIcon(Icons.close));
      await tester.pump();

      expect(receivedPrice, isNull);
      // Should exit edit mode and show original price.
      expect(find.byType(TextField), findsNothing);
      expect(find.text('\$12.99'), findsOneWidget);
    });

    testWidgets('submitting via keyboard calls onPriceChanged', (tester) async {
      double? receivedPrice;
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onPriceChanged: (p) => receivedPrice = p),
      );

      await tester.tap(find.byIcon(Icons.edit));
      await tester.pump();

      await tester.enterText(find.byType(TextField), '20.00');
      await tester.testTextInput.receiveAction(TextInputAction.done);
      await tester.pump();

      expect(receivedPrice, 20.00);
    });
  });

  group('name editing', () {
    testWidgets('shows edit name icon when onNameChanged is provided', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onNameChanged: (_) {}));
      // Find the edit icon with 'Edit name' tooltip.
      expect(find.byTooltip('Edit name'), findsOneWidget);
    });

    testWidgets('hides edit name icon when onNameChanged is null', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.byTooltip('Edit name'), findsNothing);
    });

    testWidgets('hides edit name icon while updating', (tester) async {
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onNameChanged: (_) {}, isUpdating: true),
      );
      expect(find.byTooltip('Edit name'), findsNothing);
    });

    testWidgets('tapping edit name icon shows text field with current name', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onNameChanged: (_) {}));

      await tester.tap(find.byTooltip('Edit name'));
      await tester.pump();

      expect(find.byType(TextField), findsOneWidget);
      final textField = tester.widget<TextField>(find.byType(TextField));
      expect(textField.controller!.text, 'Test Bowl Cozy');
    });

    testWidgets('tapping check icon submits the new name', (tester) async {
      String? receivedName;
      await tester.pumpWidget(buildTestWidget(sampleDraft, onNameChanged: (n) => receivedName = n));

      // Enter edit mode.
      await tester.tap(find.byTooltip('Edit name'));
      await tester.pump();

      // Clear and type a new name.
      await tester.enterText(find.byType(TextField), 'Updated Bowl Cozy');
      await tester.tap(find.byTooltip('Save name'));
      await tester.pump();

      expect(receivedName, 'Updated Bowl Cozy');
      // Should exit edit mode — no more text field.
      expect(find.byType(TextField), findsNothing);
    });

    testWidgets('tapping close icon cancels name editing', (tester) async {
      String? receivedName;
      await tester.pumpWidget(buildTestWidget(sampleDraft, onNameChanged: (n) => receivedName = n));

      // Enter edit mode.
      await tester.tap(find.byTooltip('Edit name'));
      await tester.pump();

      // Type a new name but cancel.
      await tester.enterText(find.byType(TextField), 'Cancelled Name');
      // Find the Cancel button (close icon) — use tooltip to disambiguate.
      await tester.tap(find.byTooltip('Cancel'));
      await tester.pump();

      expect(receivedName, isNull);
      // Should exit edit mode and show original name.
      expect(find.byType(TextField), findsNothing);
      expect(find.text('Test Bowl Cozy'), findsOneWidget);
    });

    testWidgets('submitting via keyboard calls onNameChanged', (tester) async {
      String? receivedName;
      await tester.pumpWidget(buildTestWidget(sampleDraft, onNameChanged: (n) => receivedName = n));

      await tester.tap(find.byTooltip('Edit name'));
      await tester.pump();

      await tester.enterText(find.byType(TextField), 'Keyboard Name');
      await tester.testTextInput.receiveAction(TextInputAction.done);
      await tester.pump();

      expect(receivedName, 'Keyboard Name');
    });

    testWidgets('does not submit empty name', (tester) async {
      String? receivedName;
      await tester.pumpWidget(buildTestWidget(sampleDraft, onNameChanged: (n) => receivedName = n));

      await tester.tap(find.byTooltip('Edit name'));
      await tester.pump();

      // Clear the field and try to submit.
      await tester.enterText(find.byType(TextField), '');
      await tester.tap(find.byTooltip('Save name'));
      await tester.pump();

      // Should not have called the callback.
      expect(receivedName, isNull);
      // Should still be in edit mode.
      expect(find.byType(TextField), findsOneWidget);
    });
  });

  group('description editing', () {
    testWidgets('shows edit description icon when onDescriptionChanged is provided', (
      tester,
    ) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onDescriptionChanged: (_) {}));
      expect(find.byTooltip('Edit description'), findsOneWidget);
    });

    testWidgets('hides edit description icon when onDescriptionChanged is null', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft));
      expect(find.byTooltip('Edit description'), findsNothing);
    });

    testWidgets('hides edit description icon while updating', (tester) async {
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onDescriptionChanged: (_) {}, isUpdating: true),
      );
      expect(find.byTooltip('Edit description'), findsNothing);
    });

    testWidgets('tapping edit description icon shows text field with current description', (
      tester,
    ) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onDescriptionChanged: (_) {}));

      await tester.tap(find.byTooltip('Edit description'));
      await tester.pump();

      // Should show a multi-line TextField.
      final textFields = find.byType(TextField);
      expect(textFields, findsOneWidget);
      final textField = tester.widget<TextField>(textFields);
      expect(textField.controller!.text, 'A beautifully crafted test product.');
    });

    testWidgets('tapping check icon submits the new description', (tester) async {
      String? receivedDescription;
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onDescriptionChanged: (d) => receivedDescription = d),
      );

      // Enter edit mode.
      await tester.tap(find.byTooltip('Edit description'));
      await tester.pump();

      // Clear and type a new description.
      await tester.enterText(find.byType(TextField), 'Updated description text.');
      await tester.tap(find.byTooltip('Save description'));
      await tester.pump();

      expect(receivedDescription, 'Updated description text.');
      // Should exit edit mode — no more text field.
      expect(find.byType(TextField), findsNothing);
    });

    testWidgets('tapping close icon cancels description editing', (tester) async {
      String? receivedDescription;
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onDescriptionChanged: (d) => receivedDescription = d),
      );

      // Enter edit mode.
      await tester.tap(find.byTooltip('Edit description'));
      await tester.pump();

      // Type a new description but cancel.
      await tester.enterText(find.byType(TextField), 'Cancelled description');
      await tester.tap(find.byTooltip('Cancel description edit'));
      await tester.pump();

      expect(receivedDescription, isNull);
      // Should exit edit mode and show original description.
      expect(find.byType(TextField), findsNothing);
      expect(find.text('A beautifully crafted test product.'), findsOneWidget);
    });

    testWidgets('does not submit empty description', (tester) async {
      String? receivedDescription;
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onDescriptionChanged: (d) => receivedDescription = d),
      );

      await tester.tap(find.byTooltip('Edit description'));
      await tester.pump();

      // Clear the field and try to submit.
      await tester.enterText(find.byType(TextField), '');
      await tester.tap(find.byTooltip('Save description'));
      await tester.pump();

      // Should not have called the callback.
      expect(receivedDescription, isNull);
      // Should still be in edit mode.
      expect(find.byType(TextField), findsOneWidget);
    });
  });

  // ── Inline validation error messages (Stage 2B) ─────────────────────

  group('inline validation errors', () {
    testWidgets('shows error when submitting empty name', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onNameChanged: (_) {}));

      await tester.tap(find.byTooltip('Edit name'));
      await tester.pump();

      await tester.enterText(find.byType(TextField), '');
      await tester.tap(find.byTooltip('Save name'));
      await tester.pump();

      expect(find.text('Name cannot be empty.'), findsOneWidget);
    });

    testWidgets('clears name error on cancel', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onNameChanged: (_) {}));

      await tester.tap(find.byTooltip('Edit name'));
      await tester.pump();

      // Trigger the error.
      await tester.enterText(find.byType(TextField), '');
      await tester.tap(find.byTooltip('Save name'));
      await tester.pump();
      expect(find.text('Name cannot be empty.'), findsOneWidget);

      // Cancel should clear the error and exit edit mode.
      await tester.tap(find.byTooltip('Cancel'));
      await tester.pump();
      expect(find.text('Name cannot be empty.'), findsNothing);
      expect(find.byType(TextField), findsNothing);
    });

    testWidgets('shows error when submitting invalid price', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onPriceChanged: (_) {}));

      await tester.tap(find.byIcon(Icons.edit));
      await tester.pump();

      // Clear the field (empty string is not a valid price).
      await tester.enterText(find.byType(TextField), '');
      await tester.tap(find.byIcon(Icons.check));
      await tester.pump();

      expect(find.text('Enter a valid price.'), findsOneWidget);
    });

    testWidgets('clears price error on cancel', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onPriceChanged: (_) {}));

      await tester.tap(find.byIcon(Icons.edit));
      await tester.pump();

      await tester.enterText(find.byType(TextField), '');
      await tester.tap(find.byIcon(Icons.check));
      await tester.pump();
      expect(find.text('Enter a valid price.'), findsOneWidget);

      await tester.tap(find.byIcon(Icons.close));
      await tester.pump();
      expect(find.text('Enter a valid price.'), findsNothing);
    });

    testWidgets('shows error when submitting empty description', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onDescriptionChanged: (_) {}));

      await tester.tap(find.byTooltip('Edit description'));
      await tester.pump();

      await tester.enterText(find.byType(TextField), '');
      await tester.tap(find.byTooltip('Save description'));
      await tester.pump();

      expect(find.text('Description cannot be empty.'), findsOneWidget);
    });

    testWidgets('clears description error on cancel', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onDescriptionChanged: (_) {}));

      await tester.tap(find.byTooltip('Edit description'));
      await tester.pump();

      await tester.enterText(find.byType(TextField), '');
      await tester.tap(find.byTooltip('Save description'));
      await tester.pump();
      expect(find.text('Description cannot be empty.'), findsOneWidget);

      await tester.tap(find.byTooltip('Cancel description edit'));
      await tester.pump();
      expect(find.text('Description cannot be empty.'), findsNothing);
    });

    testWidgets('shows error when submitting empty category', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onCategoryChanged: (_) {}));

      await tester.tap(find.byTooltip('Edit category'));
      await tester.pump();

      await tester.enterText(find.byType(TextField), '');
      await tester.tap(find.byTooltip('Save category'));
      await tester.pump();

      expect(find.text('Category cannot be empty.'), findsOneWidget);
    });

    testWidgets('clears category error on cancel', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onCategoryChanged: (_) {}));

      await tester.tap(find.byTooltip('Edit category'));
      await tester.pump();

      await tester.enterText(find.byType(TextField), '');
      await tester.tap(find.byTooltip('Save category'));
      await tester.pump();
      expect(find.text('Category cannot be empty.'), findsOneWidget);

      await tester.tap(find.byTooltip('Cancel'));
      await tester.pump();
      expect(find.text('Category cannot be empty.'), findsNothing);
    });

    testWidgets('valid input clears previous error', (tester) async {
      String? receivedName;
      await tester.pumpWidget(buildTestWidget(sampleDraft, onNameChanged: (n) => receivedName = n));

      await tester.tap(find.byTooltip('Edit name'));
      await tester.pump();

      // Trigger error first.
      await tester.enterText(find.byType(TextField), '');
      await tester.tap(find.byTooltip('Save name'));
      await tester.pump();
      expect(find.text('Name cannot be empty.'), findsOneWidget);

      // Now enter valid input and submit.
      await tester.enterText(find.byType(TextField), 'Valid Name');
      await tester.tap(find.byTooltip('Save name'));
      await tester.pump();

      expect(find.text('Name cannot be empty.'), findsNothing);
      expect(receivedName, 'Valid Name');
    });
  });

  // ── Touch target sizing (Stage 6B) ──────────────────────────────────

  group('touch target sizing', () {
    // Material Design minimum touch target is 48×48 dp.
    // We verify the rendered size of each IconButton meets this.
    const minTarget = 48.0;

    Finder iconButtonAncestor(String tooltip) =>
        find.ancestor(of: find.byTooltip(tooltip), matching: find.byType(IconButton));

    testWidgets('edit name button has adequate touch target', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onNameChanged: (_) {}));
      final size = tester.getSize(iconButtonAncestor('Edit name'));
      expect(size.width, greaterThanOrEqualTo(minTarget));
      expect(size.height, greaterThanOrEqualTo(minTarget));
    });

    testWidgets('edit price button has adequate touch target', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onPriceChanged: (_) {}));
      final size = tester.getSize(iconButtonAncestor('Edit price'));
      expect(size.width, greaterThanOrEqualTo(minTarget));
      expect(size.height, greaterThanOrEqualTo(minTarget));
    });

    testWidgets('edit category button has adequate touch target', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onCategoryChanged: (_) {}));
      final size = tester.getSize(iconButtonAncestor('Edit category'));
      expect(size.width, greaterThanOrEqualTo(minTarget));
      expect(size.height, greaterThanOrEqualTo(minTarget));
    });

    testWidgets('edit description button has adequate touch target', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onDescriptionChanged: (_) {}));
      final size = tester.getSize(iconButtonAncestor('Edit description'));
      expect(size.width, greaterThanOrEqualTo(minTarget));
      expect(size.height, greaterThanOrEqualTo(minTarget));
    });

    testWidgets('save/cancel name buttons have adequate touch targets', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onNameChanged: (_) {}));
      await tester.tap(find.byTooltip('Edit name'));
      await tester.pump();

      final saveSize = tester.getSize(iconButtonAncestor('Save name'));
      final cancelSize = tester.getSize(iconButtonAncestor('Cancel'));
      expect(saveSize.width, greaterThanOrEqualTo(minTarget));
      expect(saveSize.height, greaterThanOrEqualTo(minTarget));
      expect(cancelSize.width, greaterThanOrEqualTo(minTarget));
      expect(cancelSize.height, greaterThanOrEqualTo(minTarget));
    });

    testWidgets('price edit row uses flexible width for narrow screens', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onPriceChanged: (_) {}));
      await tester.tap(find.byIcon(Icons.edit));
      await tester.pump();

      // The TextField should be wrapped in Expanded, not a fixed-width SizedBox.
      // Verify the TextField exists and the edit row renders without overflow.
      expect(find.byType(TextField), findsOneWidget);
    });
  });

  // ── Disabled state during isUpdating (Stage 2B) ─────────────────────

  group('edit fields disabled during isUpdating', () {
    testWidgets('name text field disabled while updating', (tester) async {
      // Start with isUpdating = false to enter edit mode.
      await tester.pumpWidget(buildTestWidget(sampleDraft, onNameChanged: (_) {}));

      await tester.tap(find.byTooltip('Edit name'));
      await tester.pump();
      expect(find.byType(TextField), findsOneWidget);

      // Rebuild with isUpdating = true.
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onNameChanged: (_) {}, isUpdating: true),
      );
      await tester.pump();

      // The text field should be disabled.
      final textField = tester.widget<TextField>(find.byType(TextField));
      expect(textField.enabled, false);
    });

    testWidgets('price text field disabled while updating', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onPriceChanged: (_) {}));

      await tester.tap(find.byIcon(Icons.edit));
      await tester.pump();

      // Rebuild with isUpdating = true.
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onPriceChanged: (_) {}, isUpdating: true),
      );
      await tester.pump();

      final textField = tester.widget<TextField>(find.byType(TextField));
      expect(textField.enabled, false);
    });

    testWidgets('description text field disabled while updating', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onDescriptionChanged: (_) {}));

      await tester.tap(find.byTooltip('Edit description'));
      await tester.pump();

      // Rebuild with isUpdating = true.
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onDescriptionChanged: (_) {}, isUpdating: true),
      );
      await tester.pump();

      final textField = tester.widget<TextField>(find.byType(TextField));
      expect(textField.enabled, false);
    });

    testWidgets('category text field disabled while updating', (tester) async {
      await tester.pumpWidget(buildTestWidget(sampleDraft, onCategoryChanged: (_) {}));

      await tester.tap(find.byTooltip('Edit category'));
      await tester.pump();

      // Rebuild with isUpdating = true.
      await tester.pumpWidget(
        buildTestWidget(sampleDraft, onCategoryChanged: (_) {}, isUpdating: true),
      );
      await tester.pump();

      final textField = tester.widget<TextField>(find.byType(TextField));
      expect(textField.enabled, false);
    });
  });
}
