import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fotodocumentation/dto/customer_dto.dart' show CustomerDto;
import 'package:fotodocumentation/dto/picture_dto.dart';
import 'package:fotodocumentation/pages/customer/picture_widget.dart';
import 'package:fotodocumentation/pages/customer/picture_fullscreen_dialog.dart';
import 'package:fotodocumentation/utils/di_container.dart';
import 'package:fotodocumentation/utils/login_credentials.dart';

import '../testing/test_utils.dart';

// Minimal valid base64 encoded 1x1 pixel PNG image
const String _testImage =
    'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();
  DiContainer.instance.initState();
  DiContainer.instance.put(LoginCredentials, getDefaultLoginCredentials());

  late CustomerDto customerDto;
  late PictureDto pictureDto1;
  late PictureDto pictureDto2;
  late PictureDto pictureDto3;

  setUp(() {
    pictureDto1 = PictureDto(
      id: 1,
      comment: 'First picture comment',
      category: 'category1',
      image: _testImage,
      pictureDate: DateTime(2024, 1, 15),
      username: 'user1',
    );

    pictureDto2 = PictureDto(
      id: 2,
      comment: 'Second picture comment',
      category: 'category2',
      image: _testImage,
      pictureDate: DateTime(2024, 2, 20),
      username: 'user2',
    );

    pictureDto3 = PictureDto(
      id: 3,
      comment: null,
      category: 'category3',
      image: _testImage,
      pictureDate: DateTime(2024, 3, 25),
      username: 'user3',
    );

    customerDto = CustomerDto(
      id: 1,
      name: 'Test Apotheke',
      customerNumber: 'CUST001',
      pictures: [pictureDto1, pictureDto2, pictureDto3],
    );
  });

  group('PictureWidget', () {
    testWidgets('displays customer information correctly', (WidgetTester tester) async {
      setScreenSize(tester, 1024, 1024);

      await pumpApp(
        tester,
        PictureWidget(customerDto: customerDto, pictureDto: pictureDto1),
      );
      await tester.pumpAndSettle();

      // Verify that the header is displayed
      expect(find.text('INFORMATIONEN'), findsOneWidget);

      // Verify customer name is displayed
      expect(find.text('Test Apotheke'), findsOneWidget);

      // Verify customer number is displayed
      expect(find.text('CUST001'), findsOneWidget);

      // Verify labels are displayed
      expect(find.text('APOTHEKE'), findsOneWidget);
      expect(find.text('KUNDENNUMMER'), findsOneWidget);
      expect(find.text('DATUM'), findsOneWidget);
      expect(find.text('KOMMENTAR'), findsOneWidget);
    });

    testWidgets('displays picture comment', (WidgetTester tester) async {
      setScreenSize(tester, 1024, 1024);

      await pumpApp(
        tester,
        PictureWidget(customerDto: customerDto, pictureDto: pictureDto1),
      );
      await tester.pumpAndSettle();

      // Verify the comment is displayed
      expect(find.text('First picture comment'), findsOneWidget);
    });

    testWidgets('displays empty string when comment is null', (WidgetTester tester) async {
      setScreenSize(tester, 1024, 1024);

      await pumpApp(
        tester,
        PictureWidget(customerDto: customerDto, pictureDto: pictureDto3),
      );
      await tester.pumpAndSettle();

      // The comment field should be empty but the label should exist
      expect(find.text('KOMMENTAR'), findsOneWidget);
    });

    testWidgets('shows close button', (WidgetTester tester) async {
      setScreenSize(tester, 1024, 1024);

      await pumpApp(
        tester,
        PictureWidget(customerDto: customerDto, pictureDto: pictureDto1),
      );
      await tester.pumpAndSettle();

      // Verify close button icon exists
      expect(find.byIcon(Icons.close), findsOneWidget);
    });

    testWidgets('shows right navigation button when there are more pictures', (WidgetTester tester) async {
      setScreenSize(tester, 1024, 1024);

      await pumpApp(
        tester,
        PictureWidget(customerDto: customerDto, pictureDto: pictureDto1),
      );
      await tester.pumpAndSettle();

      // First picture should have right navigation (chevron_right), no left navigation
      expect(find.byIcon(Icons.chevron_right), findsOneWidget);
      expect(find.byIcon(Icons.chevron_left), findsNothing);
    });

    testWidgets('shows left navigation button when not on first picture', (WidgetTester tester) async {
      setScreenSize(tester, 1024, 1024);

      await pumpApp(
        tester,
        PictureWidget(customerDto: customerDto, pictureDto: pictureDto2),
      );
      await tester.pumpAndSettle();

      // Middle picture should have both navigation buttons
      expect(find.byIcon(Icons.chevron_left), findsOneWidget);
      expect(find.byIcon(Icons.chevron_right), findsOneWidget);
    });

    testWidgets('shows only left navigation on last picture', (WidgetTester tester) async {
      setScreenSize(tester, 1024, 1024);

      await pumpApp(
        tester,
        PictureWidget(customerDto: customerDto, pictureDto: pictureDto3),
      );
      await tester.pumpAndSettle();

      // Last picture should have left navigation, no right navigation
      expect(find.byIcon(Icons.chevron_left), findsOneWidget);
      expect(find.byIcon(Icons.chevron_right), findsNothing);
    });

    testWidgets('navigates to next picture when right button is tapped', (WidgetTester tester) async {
      setScreenSize(tester, 1024, 1024);

      await pumpApp(
        tester,
        PictureWidget(customerDto: customerDto, pictureDto: pictureDto1),
      );
      await tester.pumpAndSettle();

      // Verify first picture comment is shown
      expect(find.text('First picture comment'), findsOneWidget);

      // Tap right navigation button
      await tester.tap(find.byIcon(Icons.chevron_right));
      await tester.pumpAndSettle();

      // Verify second picture comment is now shown
      expect(find.text('Second picture comment'), findsOneWidget);
      expect(find.text('First picture comment'), findsNothing);
    });

    testWidgets('navigates to previous picture when left button is tapped', (WidgetTester tester) async {
      setScreenSize(tester, 1024, 1024);

      await pumpApp(
        tester,
        PictureWidget(customerDto: customerDto, pictureDto: pictureDto2),
      );
      await tester.pumpAndSettle();

      // Verify second picture comment is shown
      expect(find.text('Second picture comment'), findsOneWidget);

      // Tap left navigation button
      await tester.tap(find.byIcon(Icons.chevron_left));
      await tester.pumpAndSettle();

      // Verify first picture comment is now shown
      expect(find.text('First picture comment'), findsOneWidget);
      expect(find.text('Second picture comment'), findsNothing);
    });

    testWidgets('shows no navigation buttons when only one picture', (WidgetTester tester) async {
      setScreenSize(tester, 1024, 1024);

      final singlePictureCustomer = CustomerDto(
        id: 1,
        name: 'Test Apotheke',
        customerNumber: 'CUST001',
        pictures: [pictureDto1],
      );

      await pumpApp(
        tester,
        PictureWidget(customerDto: singlePictureCustomer, pictureDto: pictureDto1),
      );
      await tester.pumpAndSettle();

      // No navigation buttons should be shown
      expect(find.byIcon(Icons.chevron_left), findsNothing);
      expect(find.byIcon(Icons.chevron_right), findsNothing);
    });

    testWidgets('opens fullscreen dialog when image is tapped', (WidgetTester tester) async {
      setScreenSize(tester, 2048, 2048);

      await pumpApp(
        tester,
        PictureWidget(customerDto: customerDto, pictureDto: pictureDto1),
      );
      await tester.pumpAndSettle();

      // Find the GestureDetector with the image key
      final imageFinder = find.byKey(const Key("image"));
      expect(imageFinder, findsOneWidget);

      // Ensure the widget is visible first
      await tester.ensureVisible(imageFinder);
      await tester.pumpAndSettle();

      // Tap the image - use warnIfMissed: false since the Image.memory may have
      // rendering issues in test environment but the GestureDetector should still work
      await tester.tap(imageFinder, warnIfMissed: false);
      await tester.pumpAndSettle();

      // Verify fullscreen dialog is shown
      expect(find.byType(PictureFullscreenDialog), findsOneWidget);
    });
  });
}
