// 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/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_test/flutter_test.dart';

class CountButton extends StatefulWidget {
  const CountButton({super.key});

  @override
  State<CountButton> createState() => _CountButtonState();
}

class _CountButtonState extends State<CountButton> {
  int counter = 0;
  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      child: Text('Counter $counter'),
      onPressed: () {
        setState(() {
          counter += 1;
        });
      },
    );
  }
}

class AnimateSample extends StatefulWidget {
  const AnimateSample({super.key});

  @override
  State<AnimateSample> createState() => _AnimateSampleState();
}

class _AnimateSampleState extends State<AnimateSample>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 1),
    )..forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (BuildContext context, _) => Text('Value: ${_controller.value}'),
    );
  }
}

void main() {
  test('Test pump on LiveWidgetController', () async {
    runApp(const MaterialApp(home: Center(child: CountButton())));

    await SchedulerBinding.instance.endOfFrame;
    final WidgetController controller =
        LiveWidgetController(WidgetsBinding.instance);
    await controller.tap(find.text('Counter 0'));
    expect(find.text('Counter 0'), findsOneWidget);
    expect(find.text('Counter 1'), findsNothing);
    await controller.pump();
    expect(find.text('Counter 0'), findsNothing);
    expect(find.text('Counter 1'), findsOneWidget);
  });

  test('Test pumpAndSettle on LiveWidgetController', () async {
    runApp(const MaterialApp(home: Center(child: AnimateSample())));
    await SchedulerBinding.instance.endOfFrame;
    final WidgetController controller =
        LiveWidgetController(WidgetsBinding.instance);
    expect(find.text('Value: 1.0'), findsNothing);
    await controller.pumpAndSettle();
    expect(find.text('Value: 1.0'), findsOneWidget);
  });

  test('Input event array on LiveWidgetController', () async {
    final List<String> logs = <String>[];
    runApp(
      MaterialApp(
        home: Listener(
          onPointerDown: (PointerDownEvent event) => logs.add('down ${event.buttons}'),
          onPointerMove: (PointerMoveEvent event) => logs.add('move ${event.buttons}'),
          onPointerUp: (PointerUpEvent event) => logs.add('up ${event.buttons}'),
          child: const Text('test'),
        ),
      ),
    );
    await SchedulerBinding.instance.endOfFrame;
    final WidgetController controller =
        LiveWidgetController(WidgetsBinding.instance);

    final Offset location = controller.getCenter(find.text('test'));
    final List<PointerEventRecord> records = <PointerEventRecord>[
      PointerEventRecord(Duration.zero, <PointerEvent>[
        // Typically PointerAddedEvent is not used in testers, but for records
        // captured on a device it is usually what start a gesture.
        PointerAddedEvent(
          position: location,
        ),
        PointerDownEvent(
          position: location,
          buttons: kSecondaryMouseButton,
          pointer: 1,
        ),
      ]),
      ...<PointerEventRecord>[
        for (Duration t = const Duration(milliseconds: 5);
             t < const Duration(milliseconds: 80);
             t += const Duration(milliseconds: 16))
          PointerEventRecord(t, <PointerEvent>[
            PointerMoveEvent(
              timeStamp: t - const Duration(milliseconds: 1),
              position: location,
              buttons: kSecondaryMouseButton,
              pointer: 1,
            ),
          ]),
      ],
      PointerEventRecord(const Duration(milliseconds: 80), <PointerEvent>[
        PointerUpEvent(
          timeStamp: const Duration(milliseconds: 79),
          position: location,
          buttons: kSecondaryMouseButton,
          pointer: 1,
        ),
      ]),
    ];
    final List<Duration> timeDiffs =
        await controller.handlePointerEventRecord(records);

    expect(timeDiffs.length, records.length);
    for (final Duration diff in timeDiffs) {
      // Allow some freedom of time delay in real world.
      // TODO(pdblasi-google): The expected wiggle room should be -1, but occassional
      // results were reaching -6. This assert has been adjusted to reduce flakiness,
      // but the root cause is still unknown. (https://github.com/flutter/flutter/issues/109638)
      assert(diff.inMilliseconds > -7, 'timeDiffs were: $timeDiffs (offending time was ${diff.inMilliseconds}ms)');
    }

    const String b = '$kSecondaryMouseButton';
    expect(logs.first, 'down $b');
    for (int i = 1; i < logs.length - 1; i++) {
      expect(logs[i], 'move $b');
    }
    expect(logs.last, 'up $b');
  });
}
