// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:io' as io;

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

import 'image_test_mocks.dart';
import 'utils.dart';

void main() => defineTests();

void defineTests() {
  group('Image', () {
    setUp(() {
      // Only needs to be done once since the HttpClient generated
      // by this override is cached as a static singleton.
      io.HttpOverrides.global = TestHttpOverrides();
    });

    testWidgets(
      'should not interrupt styling',
      (WidgetTester tester) async {
        const String data = '_textbefore ![alt](https://img) textafter_';
        await tester.pumpWidget(
          boilerplate(
            const Markdown(data: data),
          ),
        );

        final Iterable<RichText> texts =
            tester.widgetList(find.byType(RichText));
        final RichText firstTextWidget = texts.first;
        final TextSpan firstTextSpan = firstTextWidget.text as TextSpan;
        final Image image = tester.widget(find.byType(Image));
        final NetworkImage networkImage = image.image as NetworkImage;
        final RichText secondTextWidget = texts.last;
        final TextSpan secondTextSpan = secondTextWidget.text as TextSpan;

        expect(firstTextSpan.text, 'textbefore ');
        expect(firstTextSpan.style!.fontStyle, FontStyle.italic);
        expect(networkImage.url, 'https://img');
        expect(secondTextSpan.text, ' textafter');
        expect(secondTextSpan.style!.fontStyle, FontStyle.italic);
      },
    );

    testWidgets(
      'should work with a link',
      (WidgetTester tester) async {
        const String data = '![alt](https://img#50x50)';
        await tester.pumpWidget(
          boilerplate(
            const Markdown(data: data),
          ),
        );

        final Image image = tester.widget(find.byType(Image));
        final NetworkImage networkImage = image.image as NetworkImage;
        expect(networkImage.url, 'https://img');
        expect(image.width, 50);
        expect(image.height, 50);
      },
    );

    testWidgets(
      'should work with relative remote image',
      (WidgetTester tester) async {
        const String data = '![alt](/img.png)';
        await tester.pumpWidget(
          boilerplate(
            const Markdown(
              data: data,
              imageDirectory: 'https://localhost',
            ),
          ),
        );

        final Iterable<Widget> widgets = tester.allWidgets;
        final Image image =
            widgets.firstWhere((Widget widget) => widget is Image) as Image;

        expect(image.image is NetworkImage, isTrue);
        expect((image.image as NetworkImage).url, 'https://localhost/img.png');
      },
    );

    testWidgets(
      'local files should be files',
      (WidgetTester tester) async {
        const String data = '![alt](http.png)';
        await tester.pumpWidget(
          boilerplate(
            const Markdown(data: data),
          ),
        );

        final Iterable<Widget> widgets = tester.allWidgets;
        final Image image =
            widgets.firstWhere((Widget widget) => widget is Image) as Image;

        expect(image.image is FileImage, isTrue);
      },
    );

    testWidgets(
      'should work with resources',
      (WidgetTester tester) async {
        TestWidgetsFlutterBinding.ensureInitialized();
        const String data = '![alt](resource:assets/logo.png)';
        await tester.pumpWidget(
          boilerplate(
            MaterialApp(
              home: DefaultAssetBundle(
                bundle: TestAssetBundle(),
                child: Center(
                  child: Container(
                    color: Colors.white,
                    width: 500,
                    child: const Markdown(
                      data: data,
                    ),
                  ),
                ),
              ),
            ),
          ),
        );

        final Image image = tester.allWidgets
            .firstWhere((Widget widget) => widget is Image) as Image;

        expect(image.image is AssetImage, isTrue);
        expect((image.image as AssetImage).assetName, 'assets/logo.png');

        // Force the asset image to be rasterized so it can be compared.
        await tester.runAsync(() async {
          final Element element = tester.element(find.byType(Markdown));
          await precacheImage(image.image, element);
        });

        await tester.pumpAndSettle();

        await expectLater(
            find.byType(Container),
            matchesGoldenFile(
                'assets/images/golden/image_test/resource_asset_logo.png'));
      },
    );

    testWidgets(
      'should work with local image files',
      (WidgetTester tester) async {
        const String data = '![alt](img.png#50x50)';
        await tester.pumpWidget(
          boilerplate(
            const Markdown(data: data),
          ),
        );

        final Image image = tester.widget(find.byType(Image));
        final FileImage fileImage = image.image as FileImage;
        expect(fileImage.file.path, 'img.png');
        expect(image.width, 50);
        expect(image.height, 50);
      },
    );

    testWidgets(
      'should show properly next to text',
      (WidgetTester tester) async {
        const String data = 'Hello ![alt](img#50x50)';
        await tester.pumpWidget(
          boilerplate(
            const Markdown(data: data),
          ),
        );

        final RichText richText = tester.widget(find.byType(RichText));
        final TextSpan textSpan = richText.text as TextSpan;
        expect(textSpan.text, 'Hello ');
        expect(textSpan.style, isNotNull);
      },
    );

    testWidgets(
      'should work when nested in a link',
      (WidgetTester tester) async {
        final List<String> tapTexts = <String>[];
        final List<String?> tapResults = <String?>[];
        const String data = '[![alt](https://img#50x50)](href)';
        await tester.pumpWidget(
          boilerplate(
            Markdown(
              data: data,
              onTapLink: (String text, String? value, String title) {
                tapTexts.add(text);
                tapResults.add(value);
              },
            ),
          ),
        );

        final GestureDetector detector =
            tester.widget(find.byType(GestureDetector));
        detector.onTap!();

        expect(tapTexts.length, 1);
        expect(tapTexts, everyElement('alt'));
        expect(tapResults.length, 1);
        expect(tapResults, everyElement('href'));
      },
    );

    testWidgets(
      'should work when nested in a link with text',
      (WidgetTester tester) async {
        final List<String> tapTexts = <String>[];
        final List<String?> tapResults = <String?>[];
        const String data =
            '[Text before ![alt](https://img#50x50) text after](href)';
        await tester.pumpWidget(
          boilerplate(
            Markdown(
              data: data,
              onTapLink: (String text, String? value, String title) {
                tapTexts.add(text);
                tapResults.add(value);
              },
            ),
          ),
        );

        final GestureDetector detector =
            tester.widget(find.byType(GestureDetector));
        detector.onTap!();

        final Iterable<RichText> texts =
            tester.widgetList(find.byType(RichText));
        final RichText firstTextWidget = texts.first;
        final TextSpan firstSpan = firstTextWidget.text as TextSpan;
        (firstSpan.recognizer as TapGestureRecognizer?)!.onTap!();

        final RichText lastTextWidget = texts.last;
        final TextSpan lastSpan = lastTextWidget.text as TextSpan;
        (lastSpan.recognizer as TapGestureRecognizer?)!.onTap!();

        expect(firstSpan.children, null);
        expect(firstSpan.text, 'Text before ');
        expect(firstSpan.recognizer.runtimeType, equals(TapGestureRecognizer));

        expect(lastSpan.children, null);
        expect(lastSpan.text, ' text after');
        expect(lastSpan.recognizer.runtimeType, equals(TapGestureRecognizer));

        expect(tapTexts.length, 3);
        expect(tapTexts, everyElement('Text before alt text after'));
        expect(tapResults.length, 3);
        expect(tapResults, everyElement('href'));
      },
    );

    testWidgets(
      'should work alongside different links',
      (WidgetTester tester) async {
        final List<String> tapTexts = <String>[];
        final List<String?> tapResults = <String?>[];
        const String data =
            '[Link before](firstHref)[![alt](https://img#50x50)](imageHref)[link after](secondHref)';

        await tester.pumpWidget(
          boilerplate(
            Markdown(
              data: data,
              onTapLink: (String text, String? value, String title) {
                tapTexts.add(text);
                tapResults.add(value);
              },
            ),
          ),
        );

        final Iterable<RichText> texts =
            tester.widgetList(find.byType(RichText));
        final RichText firstTextWidget = texts.first;
        final TextSpan firstSpan = firstTextWidget.text as TextSpan;
        (firstSpan.recognizer as TapGestureRecognizer?)!.onTap!();

        final GestureDetector detector =
            tester.widget(find.byType(GestureDetector));
        detector.onTap!();

        final RichText lastTextWidget = texts.last;
        final TextSpan lastSpan = lastTextWidget.text as TextSpan;
        (lastSpan.recognizer as TapGestureRecognizer?)!.onTap!();

        expect(firstSpan.children, null);
        expect(firstSpan.text, 'Link before');
        expect(firstSpan.recognizer.runtimeType, equals(TapGestureRecognizer));

        expect(lastSpan.children, null);
        expect(lastSpan.text, 'link after');
        expect(lastSpan.recognizer.runtimeType, equals(TapGestureRecognizer));

        expect(tapTexts.length, 3);
        expect(tapTexts, <String>['Link before', 'alt', 'link after']);
        expect(tapResults.length, 3);
        expect(tapResults, <String>['firstHref', 'imageHref', 'secondHref']);
      },
    );

    testWidgets(
      'custom image builder',
      (WidgetTester tester) async {
        const String data = '![alt](https://img.png)';
        Widget builder(Uri uri, String? title, String? alt) =>
            Image.asset('assets/logo.png');

        await tester.pumpWidget(
          boilerplate(
            MaterialApp(
              home: DefaultAssetBundle(
                bundle: TestAssetBundle(),
                child: Center(
                  child: Container(
                    color: Colors.white,
                    width: 500,
                    child: Markdown(
                      data: data,
                      imageBuilder: builder,
                    ),
                  ),
                ),
              ),
            ),
          ),
        );

        final Iterable<Widget> widgets = tester.allWidgets;
        final Image image =
            widgets.firstWhere((Widget widget) => widget is Image) as Image;

        expect(image.image.runtimeType, AssetImage);
        expect((image.image as AssetImage).assetName, 'assets/logo.png');

        // Force the asset image to be rasterized so it can be compared.
        await tester.runAsync(() async {
          final Element element = tester.element(find.byType(Markdown));
          await precacheImage(image.image, element);
        });

        await tester.pumpAndSettle();

        await expectLater(
            find.byType(Container),
            matchesGoldenFile(
                'assets/images/golden/image_test/custom_builder_asset_logo.png'));
      },
    );
  });
}
