// Copyright 2014 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 'package:flutter/material.dart';
import 'package:flutter_api_samples/widgets/gesture_detector/gesture_detector.2.dart'
    as example;
import 'package:flutter_test/flutter_test.dart';

void main() {

  void expectBorders(
    WidgetTester tester, {
    required bool expectGreenHasBorder,
    required bool expectYellowHasBorder,
  }) {
    final Finder containerFinder = find.byType(Container);
    final Finder greenFinder = containerFinder.first;
    final Finder yellowFinder = containerFinder.last;

    final Container greenContainer = tester.firstWidget<Container>(greenFinder);
    final BoxDecoration? greenDecoration = greenContainer.decoration as BoxDecoration?;
    expect(greenDecoration?.border, expectGreenHasBorder ? isNot(null) : null);

    final Container yellowContainer = tester.firstWidget<Container>(yellowFinder);
    final BoxDecoration? yellowDecoration = yellowContainer.decoration as BoxDecoration?;
    expect(yellowDecoration?.border, expectYellowHasBorder ? isNot(null) : null);
  }

  void expectInnerGestureDetectorBehavior(WidgetTester tester, HitTestBehavior behavior) {
    // Note that there is a third GestureDetector added by Scaffold
    final Finder innerGestureDetectorFinder = find.byType(GestureDetector).at(1);
    final GestureDetector innerGestureDetector = tester.firstWidget<GestureDetector>(innerGestureDetectorFinder);
    expect(innerGestureDetector.behavior, behavior);
  }

  testWidgets('Only the green Container shows a red border when tapped', (WidgetTester tester) async {
    await tester.pumpWidget(
      const example.NestedGestureDetectorsApp(),
    );

    final Finder greenFinder = find.byType(Container).first;
    final Offset greenTopLeftCorner = tester.getTopLeft(greenFinder);
    await tester.tapAt(greenTopLeftCorner);
    await tester.pumpAndSettle();
    expectBorders(tester, expectGreenHasBorder: true, expectYellowHasBorder: false);

    // Tap on the button to toggle inner GestureDetector.behavior
    final Finder toggleBehaviorFinder = find.byType(ElevatedButton).last;
    await tester.tap(toggleBehaviorFinder);
    await tester.pump();
    expectInnerGestureDetectorBehavior(tester, HitTestBehavior.translucent);

    // Tap again on the green container, expect nothing changed
    await tester.tapAt(greenTopLeftCorner);
    await tester.pump();
    expectBorders(tester, expectGreenHasBorder: true, expectYellowHasBorder: false);

    // Tap on the reset button
    final Finder resetFinder = find.byType(ElevatedButton).first;
    await tester.tap(resetFinder);
    await tester.pump();
    expectInnerGestureDetectorBehavior(tester, HitTestBehavior.opaque);
  });

  testWidgets('Only the yellow Container shows a red border when tapped', (WidgetTester tester) async {
    await tester.pumpWidget(
      const example.NestedGestureDetectorsApp(),
    );

    final Finder yellowFinder = find.byType(Container).last;
    final Offset yellowTopLeftCorner = tester.getTopLeft(yellowFinder);
    await tester.tapAt(yellowTopLeftCorner);
    await tester.pump();
    expectBorders(tester, expectGreenHasBorder: false, expectYellowHasBorder: true);

    // Tap on the button to toggle inner GestureDetector.behavior
    final Finder toggleBehaviorFinder = find.byType(ElevatedButton).last;
    await tester.tap(toggleBehaviorFinder);
    await tester.pump();
    expectInnerGestureDetectorBehavior(tester, HitTestBehavior.translucent);

    // Tap again on the yellow container, expect nothing changed
    await tester.tapAt(yellowTopLeftCorner);
    await tester.pump();
    expectBorders(tester, expectGreenHasBorder: false, expectYellowHasBorder: true);

    // Tap on the reset button
    final Finder resetFinder = find.byType(ElevatedButton).first;
    await tester.tap(resetFinder);
    await tester.pump();
    expectInnerGestureDetectorBehavior(tester, HitTestBehavior.opaque);
  });
}
