// Copyright 2019 The Fuchsia 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 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fuchsia_logger/logger.dart';
import 'package:mockito/mockito.dart';

// ignore_for_file: implementation_imports
import 'package:simple_browser/src/blocs/tabs_bloc.dart';
import 'package:simple_browser/src/blocs/webpage_bloc.dart';
import 'package:simple_browser/src/models/tabs_action.dart';
import 'package:simple_browser/src/services/simple_browser_navigation_event_listener.dart';
import 'package:simple_browser/src/services/simple_browser_web_service.dart';
import 'package:simple_browser/src/widgets/history_buttons.dart';
import 'package:simple_browser/src/widgets/navigation_bar.dart';
import 'package:simple_browser/src/widgets/navigation_field.dart';

void main() {
  setupLogger(name: 'navigation_bar_test');

  WebPageBloc? webPageBloc;
  MockSimpleBrowserWebService mockWebService;
  MockSimpleBrowserNavigationEventListener mockEventListener;

  ValueNotifier backStateNotifier = ValueNotifier<bool>(false);
  ValueNotifier forwardStateNotifier = ValueNotifier<bool>(false);
  ValueNotifier urlNotifier = ValueNotifier<String>('');
  ValueNotifier pageTypeNotifier = ValueNotifier<PageType>(PageType.empty);
  ValueNotifier isLoadedStateNotifier = ValueNotifier<bool>(true);

  group('The bloc is null.', () {
    testWidgets('Should create two empty containers and one + button.',
        (WidgetTester tester) async {
      await _setUpNavigationBar(tester, webPageBloc, () {});

      const reasonSuffix =
          'when the NavigationBar widget has a null webPageBloc.';

      expect(find.byType(Container), findsNWidgets(3),
          reason: 'Expected three containers $reasonSuffix');

      // Sees if there are two empty Containers.
      expect(
          find.byWidgetPredicate(
            (Widget widget) => widget is Container && widget.child == null,
            description: 'Empty containers.',
          ),
          findsNWidgets(2),
          reason: 'Expected two of those containers were empty $reasonSuffix');

      // Sees if there are one + button.
      expect(_findNewTabButton(), findsOneWidget,
          reason:
              'Expected one of those containers was a + button $reasonSuffix');
    });
  });

  group('The bloc is not null.', () {
    setUp(() {
      mockEventListener = MockSimpleBrowserNavigationEventListener();
      when(mockEventListener.backStateNotifier)
          .thenAnswer((_) => backStateNotifier);
      when(mockEventListener.forwardStateNotifier)
          .thenAnswer((_) => forwardStateNotifier);
      when(mockEventListener.urlNotifier).thenAnswer((_) => urlNotifier);
      when(mockEventListener.isLoadedStateNotifier)
          .thenAnswer((_) => isLoadedStateNotifier);

      when(mockEventListener.backState)
          .thenAnswer((_) => backStateNotifier.value);
      when(mockEventListener.forwardState)
          .thenAnswer((_) => forwardStateNotifier.value);
      when(mockEventListener.pageType)
          .thenAnswer((_) => pageTypeNotifier.value);
      when(mockEventListener.isLoadedState)
          .thenAnswer((_) => isLoadedStateNotifier.value);

      mockWebService = MockSimpleBrowserWebService();
      when(mockWebService.navigationEventListener)
          .thenAnswer((_) => mockEventListener);
      webPageBloc = WebPageBloc(
        webService: mockWebService,
      );
    });

    testWidgets(
        'Should create one HistoryButtons, one URL field and one + button.',
        (WidgetTester tester) async {
      await _setUpNavigationBar(tester, webPageBloc, () {});

      const reasonSuffix =
          'when the NavigationBar widget has a non-null webPageBloc.';

      expect(find.byType(HistoryButtons), findsOneWidget,
          reason: 'Expected a HistoryButtons widget $reasonSuffix');
      expect(find.byType(NavigationField), findsOneWidget,
          reason: 'Expected a NavigationField widget $reasonSuffix');
      expect(_findNewTabButton(), findsOneWidget,
          reason: 'Expected a + button $reasonSuffix');
    });

    testWidgets('''Should show a progress bar when the page has not been loaded,
        and should not show it anymore when the page loading is complete.''',
        (WidgetTester tester) async {
      await _setUpNavigationBar(tester, webPageBloc, () {});
      isLoadedStateNotifier.value = false;
      await tester.pump();
      expect(find.byType(LinearProgressIndicator), findsOneWidget,
          reason: 'Expected a progress bar when loading has not finished.');

      isLoadedStateNotifier.value = true;
      await tester.pumpAndSettle();
      expect(find.byType(LinearProgressIndicator), findsNothing,
          reason: 'Expected no progress bars when loading has completed.');
    });

    testWidgets('Should call the newTab callback when the + button is tapped.',
        (WidgetTester tester) async {
      TabsBloc tb = TabsBloc(
        // TODO(https://fxbug.dev/71711): Figure out why `dart analyze`
        // complains about this.
        tabFactory: () => MockWebPageBloc(), // ignore: unnecessary_lambdas
        disposeTab: (tab) => tab.dispose(),
      );

      await _setUpNavigationBar(
          tester, webPageBloc, () => tb.request.add(NewTabAction()));

      expect(tb.tabs.length, 0,
          reason:
              'Expected no tabs in the tabsBloc when none has been added to it.');

      final newTabBtn = _findNewTabButton();
      expect(newTabBtn, findsOneWidget,
          reason: 'Expected one + button on the NavigationBar.');
      await tester.tap(newTabBtn);
      await tester.pumpAndSettle();
      expect(tb.tabs.length, 1,
          reason:
              'Expected a tab in the tabsBloc when the + button was tapped.');
    });
  });
}

Future<void> _setUpNavigationBar(
    WidgetTester tester, WebPageBloc? bloc, VoidCallback callback) async {
  await tester.pumpWidget(
    MaterialApp(
      home: Scaffold(
        body: BrowserNavigationBar(
          bloc: bloc,
          newTab: callback,
          fieldFocus: FocusNode(),
        ),
      ),
    ),
  );
}

Finder _findNewTabButton() => find.byKey(Key('new_tab'));

class MockSimpleBrowserNavigationEventListener extends Mock
    implements SimpleBrowserNavigationEventListener {}

class MockSimpleBrowserWebService extends Mock
    implements SimpleBrowserWebService {}

class MockWebPageBloc extends Mock implements WebPageBloc {}
