// 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/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'widgets_app_tester.dart';

void main() {
  testWidgets('Controller expands and collapses the widget', (WidgetTester tester) async {
    final controller = ExpansibleController();
    await tester.pumpWidget(
      TestWidgetsApp(
        home: Expansible(
          controller: controller,
          bodyBuilder: (BuildContext context, Animation<double> animation) => const Text('Body'),
          headerBuilder: (BuildContext context, Animation<double> animation) => GestureDetector(
            onTap: controller.isExpanded ? controller.collapse : controller.expand,
            child: const Text('Header'),
          ),
        ),
      ),
    );

    expect(find.text('Body'), findsNothing);
    controller.expand();
    await tester.pumpAndSettle();
    expect(find.text('Body'), findsOneWidget);

    controller.collapse();
    await tester.pumpAndSettle();
    expect(find.text('Body'), findsNothing);

    controller.dispose();
  });

  testWidgets('Can listen to the expansion state', (WidgetTester tester) async {
    final controller = ExpansibleController();
    bool? expansionState;
    controller.addListener(() {
      expansionState = controller.isExpanded;
    });

    await tester.pumpWidget(
      TestWidgetsApp(
        home: Expansible(
          controller: controller,
          bodyBuilder: (BuildContext context, Animation<double> animation) => const Text('Body'),
          headerBuilder: (BuildContext context, Animation<double> animation) => GestureDetector(
            onTap: controller.isExpanded ? controller.collapse : controller.expand,
            child: const Text('Header'),
          ),
        ),
      ),
    );

    // Tap on the header to toggle the expansion.
    await tester.tap(find.text('Header'));
    await tester.pumpAndSettle();
    expect(expansionState, true);

    await tester.tap(find.text('Header'));
    await tester.pumpAndSettle();
    expect(expansionState, false);

    // Use the controller to toggle the expansion.
    controller.expand();
    await tester.pumpAndSettle();
    expect(expansionState, true);

    controller.collapse();
    await tester.pumpAndSettle();
    expect(expansionState, false);

    controller.dispose();
  });

  testWidgets('Can set expansible to be initially expanded', (WidgetTester tester) async {
    final controller = ExpansibleController();
    controller.expand();
    await tester.pumpWidget(
      TestWidgetsApp(
        home: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              Expansible(
                controller: controller,
                bodyBuilder: (BuildContext context, Animation<double> animation) =>
                    const Text('Body'),
                headerBuilder: (BuildContext context, Animation<double> animation) =>
                    GestureDetector(
                      onTap: controller.isExpanded ? controller.collapse : controller.expand,
                      child: const Text('Header'),
                    ),
              ),
            ],
          ),
        ),
      ),
    );

    expect(find.text('Body'), findsOneWidget);

    await tester.tap(find.text('Header'));
    await tester.pumpAndSettle();

    expect(find.text('Body'), findsNothing);

    controller.dispose();
  });

  testWidgets('Can compose header and body with expansibleBuilder', (WidgetTester tester) async {
    final controller = ExpansibleController();
    await tester.pumpWidget(
      TestWidgetsApp(
        home: Expansible(
          controller: controller,
          bodyBuilder: (BuildContext context, Animation<double> animation) => const Text('Body'),
          headerBuilder: (BuildContext context, Animation<double> animation) => GestureDetector(
            onTap: controller.isExpanded ? controller.collapse : controller.expand,
            child: const Text('Header'),
          ),
          expansibleBuilder:
              (BuildContext context, Widget header, Widget body, Animation<double> animation) {
                return header;
              },
        ),
      ),
    );

    // Tap on the header to toggle the expansion.
    await tester.tap(find.text('Header'));
    await tester.pumpAndSettle();
    expect(find.text('Header'), findsOneWidget);
    expect(find.text('Body'), findsNothing);

    await tester.tap(find.text('Header'));
    await tester.pumpAndSettle();
    expect(find.text('Header'), findsOneWidget);
    expect(find.text('Body'), findsNothing);

    // Use the controller to toggle the expansion.
    controller.expand();
    await tester.pumpAndSettle();
    expect(find.text('Header'), findsOneWidget);
    expect(find.text('Body'), findsNothing);

    controller.collapse();
    await tester.pumpAndSettle();
    expect(find.text('Header'), findsOneWidget);
    expect(find.text('Body'), findsNothing);

    controller.dispose();
  });

  testWidgets('Respects maintainState', (WidgetTester tester) async {
    final controller1 = ExpansibleController();
    final controller2 = ExpansibleController();
    await tester.pumpWidget(
      TestWidgetsApp(
        home: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              Expansible(
                controller: controller1,
                maintainState: false,
                bodyBuilder: (BuildContext context, Animation<double> animation) =>
                    const Text('Maintaining State'),
                headerBuilder: (BuildContext context, Animation<double> animation) =>
                    GestureDetector(
                      onTap: controller1.isExpanded ? controller1.collapse : controller1.expand,
                      child: const Text('Header'),
                    ),
              ),
              Expansible(
                controller: controller2,
                bodyBuilder: (BuildContext context, Animation<double> animation) =>
                    const Text('Discarding State'),
                headerBuilder: (BuildContext context, Animation<double> animation) =>
                    GestureDetector(
                      onTap: controller2.isExpanded ? controller2.collapse : controller2.expand,
                      child: const Text('Header'),
                    ),
              ),
            ],
          ),
        ),
      ),
    );

    // This text is not offstage while the expansible widget is collapsed.
    expect(find.text('Maintaining State', skipOffstage: false), findsNothing);
    expect(find.text('Maintaining State'), findsNothing);
    // This text is not displayed while the expansible widget is collapsed.
    expect(find.text('Discarding State'), findsNothing);

    controller1.dispose();
    controller2.dispose();
  });

  testWidgets('Respects animation duration and curves', (WidgetTester tester) async {
    final controller = ExpansibleController();
    await tester.pumpWidget(
      TestWidgetsApp(
        home: Expansible(
          controller: controller,
          duration: const Duration(milliseconds: 120),
          curve: Curves.easeOut,
          reverseCurve: Curves.easeIn,
          bodyBuilder: (BuildContext context, Animation<double> animation) =>
              const SizedBox(height: 50.0, child: Placeholder()),
          headerBuilder: (BuildContext context, Animation<double> animation) => GestureDetector(
            onTap: controller.isExpanded ? controller.collapse : controller.expand,
            child: const Text('Header'),
          ),
        ),
      ),
    );

    expect(find.byType(Placeholder), findsNothing);

    await tester.tap(find.text('Header'));

    // Check that the curve is respected.
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 60));
    expect(tester.getBottomLeft(find.byType(Placeholder)).dy, 56.08984375);

    // The animation has completed.
    await tester.pump(const Duration(milliseconds: 60) + const Duration(microseconds: 1));
    expect(tester.getBottomLeft(find.byType(Placeholder)).dy, 64.0);

    // Since the animation has completed, the vertical position doesn't change.
    await tester.pump(const Duration(milliseconds: 60));
    expect(tester.getBottomLeft(find.byType(Placeholder)).dy, 64.0);

    await tester.pumpAndSettle();
    await tester.tap(find.text('Header'));

    // Check that the reverse curve is respected.
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 60));
    expect(tester.getBottomLeft(find.byType(Placeholder)).dy, 46.91015625);

    // The animation has completed.
    await tester.pump(const Duration(milliseconds: 60) + const Duration(microseconds: 1));
    expect(find.byType(Placeholder), findsNothing);

    controller.dispose();
  });

  testWidgets('ExpansionTile can accept a new controller', (WidgetTester tester) async {
    final controller1 = ExpansibleController();
    final controller2 = ExpansibleController();
    addTearDown(() {
      controller1.dispose();
      controller2.dispose();
    });

    await tester.pumpWidget(
      TestWidgetsApp(
        home: Expansible(
          controller: controller1,
          headerBuilder: (_, _) => const Text('Header'),
          bodyBuilder: (_, _) => const Text('Body'),
        ),
      ),
    );

    expect(find.text('Body'), findsNothing);
    expect(controller1.isExpanded, isFalse);

    controller1.expand();
    expect(controller1.isExpanded, isTrue);
    await tester.pumpAndSettle();
    expect(find.text('Body'), findsOne);

    controller1.collapse();
    expect(controller1.isExpanded, isFalse);
    await tester.pumpAndSettle();
    expect(find.text('Body'), findsNothing);

    await tester.pumpWidget(
      TestWidgetsApp(
        home: Expansible(
          controller: controller2,
          headerBuilder: (_, _) => const Text('Header'),
          bodyBuilder: (_, _) => const Text('Body'),
        ),
      ),
    );

    expect(find.text('Body'), findsNothing);
    expect(controller2.isExpanded, isFalse);

    controller2.expand();
    expect(controller2.isExpanded, isTrue);
    await tester.pumpAndSettle();
    expect(find.text('Body'), findsOne);

    controller2.collapse();
    expect(controller2.isExpanded, isFalse);
    await tester.pumpAndSettle();
    expect(find.text('Body'), findsNothing);
  });

  testWidgets('Expansible can accept a new controller with a different state', (
    WidgetTester tester,
  ) async {
    final controller1 = ExpansibleController();
    final controller2 = ExpansibleController();
    addTearDown(() {
      controller1.dispose();
      controller2.dispose();
    });

    await tester.pumpWidget(
      TestWidgetsApp(
        home: Expansible(
          controller: controller1,
          headerBuilder: (_, _) => const Text('Header'),
          bodyBuilder: (_, _) => const Text('Body'),
        ),
      ),
    );

    expect(find.text('Body'), findsNothing);
    expect(controller1.isExpanded, isFalse);

    controller1.expand();
    expect(controller1.isExpanded, isTrue);
    await tester.pumpAndSettle();
    expect(find.text('Body'), findsOne);

    await tester.pumpWidget(
      TestWidgetsApp(
        home: Expansible(
          controller: controller2,
          headerBuilder: (_, _) => const Text('Header'),
          bodyBuilder: (_, _) => const Text('Body'),
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(controller2.isExpanded, isFalse);
    expect(find.text('Body'), findsNothing);

    controller2.expand();
    expect(controller2.isExpanded, isTrue);
    await tester.pumpAndSettle();
    expect(find.text('Body'), findsOne);

    controller2.collapse();
    expect(controller2.isExpanded, isFalse);
    await tester.pumpAndSettle();
    expect(find.text('Body'), findsNothing);
  });

  testWidgets('Respects animationStyle duration and curves', (WidgetTester tester) async {
    final controller = ExpansibleController();
    await tester.pumpWidget(
      TestWidgetsApp(
        home: Expansible(
          controller: controller,
          animationStyle: const AnimationStyle(
            duration: Duration(milliseconds: 120),
            curve: Curves.easeOut,
            reverseCurve: Curves.easeIn,
          ),
          bodyBuilder: (BuildContext context, Animation<double> animation) =>
              const SizedBox(height: 50.0, child: Placeholder()),
          headerBuilder: (BuildContext context, Animation<double> animation) => GestureDetector(
            onTap: controller.isExpanded ? controller.collapse : controller.expand,
            child: const Text('Header'),
          ),
        ),
      ),
    );

    expect(find.byType(Placeholder), findsNothing);

    await tester.tap(find.text('Header'));

    // Check that the curve is respected.
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 60));
    expect(tester.getBottomLeft(find.byType(Placeholder)).dy, 56.08984375);

    // The animation has completed.
    await tester.pump(const Duration(milliseconds: 60) + const Duration(microseconds: 1));
    expect(tester.getBottomLeft(find.byType(Placeholder)).dy, 64.0);

    // Since the animation has completed, the vertical position doesn't change.
    await tester.pump(const Duration(milliseconds: 60));
    expect(tester.getBottomLeft(find.byType(Placeholder)).dy, 64.0);

    await tester.pumpAndSettle();
    await tester.tap(find.text('Header'));

    // Check that the reverse curve is respected.
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 60));
    expect(tester.getBottomLeft(find.byType(Placeholder)).dy, 46.91015625);

    // The animation has completed.
    await tester.pump(const Duration(milliseconds: 60) + const Duration(microseconds: 1));
    expect(find.byType(Placeholder), findsNothing);

    controller.dispose();
  });

  testWidgets('AnimationStyle takes precedence over deprecated properties', (
    WidgetTester tester,
  ) async {
    final controller = ExpansibleController();
    await tester.pumpWidget(
      TestWidgetsApp(
        home: Expansible(
          controller: controller,
          animationStyle: const AnimationStyle(
            duration: Duration(milliseconds: 100),
            curve: Curves.linear,
          ),
          bodyBuilder: (BuildContext context, Animation<double> animation) =>
              const SizedBox(height: 50.0, child: Placeholder()),
          headerBuilder: (BuildContext context, Animation<double> animation) => GestureDetector(
            onTap: controller.isExpanded ? controller.collapse : controller.expand,
            child: const Text('Header'),
          ),
        ),
      ),
    );

    expect(find.byType(Placeholder), findsNothing);

    await tester.tap(find.text('Header'));

    // Check that the animationStyle duration (100ms) is used
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50));
    // With linear curve at 50ms out of 100ms, should be at approximately 50% height
    final double midAnimationY = tester.getBottomLeft(find.byType(Placeholder)).dy;
    // Should be more than base (14.0) and less than fully expanded (64.0)
    expect(midAnimationY, greaterThan(14.0));
    expect(midAnimationY, lessThan(64.0));

    // Animation should complete at 100ms
    await tester.pump(const Duration(milliseconds: 50) + const Duration(microseconds: 1));
    expect(tester.getBottomLeft(find.byType(Placeholder)).dy, 64.0);

    controller.dispose();
  });

  testWidgets('AnimationStyle.noAnimation disables animation', (WidgetTester tester) async {
    final controller = ExpansibleController();
    await tester.pumpWidget(
      TestWidgetsApp(
        home: Expansible(
          controller: controller,
          animationStyle: AnimationStyle.noAnimation,
          bodyBuilder: (BuildContext context, Animation<double> animation) => const Text('Body'),
          headerBuilder: (BuildContext context, Animation<double> animation) => GestureDetector(
            onTap: controller.isExpanded ? controller.collapse : controller.expand,
            child: const Text('Header'),
          ),
        ),
      ),
    );

    expect(find.text('Body'), findsNothing);

    controller.expand();
    await tester.pump();

    expect(find.text('Body'), findsOneWidget);

    controller.collapse();
    await tester.pump();

    expect(find.text('Body'), findsNothing);

    controller.dispose();
  });

  testWidgets('Expansible does not crash at zero area', (WidgetTester tester) async {
    tester.view.physicalSize = Size.zero;
    final controller = ExpansibleController();
    addTearDown(tester.view.reset);
    addTearDown(controller.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: Expansible(
            headerBuilder: (_, _) => const Text('X'),
            bodyBuilder: (_, _) => const Text('Y'),
            controller: controller,
          ),
        ),
      ),
    );
    expect(tester.getSize(find.byType(Expansible)), Size.zero);
    controller.expand();
    await tester.pump();
  });

  testWidgets('Controller can be toggled', (WidgetTester tester) async {
    final controller = ExpansibleController();
    addTearDown(controller.dispose);

    await tester.pumpWidget(
      TestWidgetsApp(
        home: Expansible(
          controller: controller,
          bodyBuilder: (BuildContext context, Animation<double> animation) => const Text('Body'),
          headerBuilder: (BuildContext context, Animation<double> animation) =>
              GestureDetector(onTap: controller.toggle, child: const Text('Header')),
        ),
      ),
    );

    expect(find.text('Body'), findsNothing);
    controller.toggle();
    await tester.pumpAndSettle();
    expect(find.text('Body'), findsOneWidget);

    controller.toggle();
    await tester.pumpAndSettle();
    expect(find.text('Body'), findsNothing);

    expect(find.text('Body'), findsNothing);
    controller.toggle();
    await tester.pumpAndSettle();
    expect(find.text('Body'), findsOneWidget);
  });
}
