// 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' show kPressTimeout;
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/rendering.dart';

bool confirmCalled = false;
bool cancelCalled = false;

class TestInkSplash extends InkSplash {
  TestInkSplash({
    required MaterialInkController controller,
    required RenderBox referenceBox,
    Offset? position,
    required Color color,
    bool containedInkWell = false,
    RectCallback? rectCallback,
    BorderRadius? borderRadius,
    ShapeBorder? customBorder,
    double? radius,
    VoidCallback? onRemoved,
    required TextDirection textDirection,
  }) : super(
    controller: controller,
    referenceBox: referenceBox,
    position: position,
    color: color,
    containedInkWell: containedInkWell,
    rectCallback: rectCallback,
    borderRadius: borderRadius,
    customBorder: customBorder,
    radius: radius,
    onRemoved: onRemoved,
    textDirection: textDirection,
  );

  @override
  void confirm() {
    confirmCalled = true;
    super.confirm();
  }

  @override
  void cancel() {
    cancelCalled = true;
    super.cancel();
  }
}

class TestInkSplashFactory extends InteractiveInkFeatureFactory {
  const TestInkSplashFactory();

  @override
  InteractiveInkFeature create({
    required MaterialInkController controller,
    required RenderBox referenceBox,
    Offset? position,
    required Color color,
    bool containedInkWell = false,
    RectCallback? rectCallback,
    BorderRadius? borderRadius,
    ShapeBorder? customBorder,
    double? radius,
    VoidCallback? onRemoved,
    required TextDirection textDirection,
  }) {
    return TestInkSplash(
      controller: controller,
      referenceBox: referenceBox,
      position: position,
      color: color,
      containedInkWell: containedInkWell,
      rectCallback: rectCallback,
      borderRadius: borderRadius,
      customBorder: customBorder,
      radius: radius,
      onRemoved: onRemoved,
      textDirection: textDirection,
    );
  }
}

void main() {
  setUp(() {
    confirmCalled = false;
    cancelCalled = false;
  });

  testWidgets('Tapping should never cause a splash', (WidgetTester tester) async {
    final Key textField1 = UniqueKey();
    final Key textField2 = UniqueKey();

    await tester.pumpWidget(
      MaterialApp(
        home: Theme(
          data: ThemeData.light().copyWith(splashFactory: const TestInkSplashFactory()),
          child: Material(
            child: Container(
              alignment: Alignment.topLeft,
              child: Column(
                children: <Widget>[
                  TextField(
                    key: textField1,
                    decoration: const InputDecoration(
                      labelText: 'label',
                    ),
                  ),
                  TextField(
                    key: textField2,
                    decoration: const InputDecoration(
                      labelText: 'label',
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.byKey(textField1));
    await tester.pumpAndSettle();
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);

    await tester.tap(find.byKey(textField1));
    await tester.pumpAndSettle();
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);

    await tester.tap(find.byKey(textField2));
    await tester.pumpAndSettle();
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);

    await tester.tapAt(tester.getTopLeft(find.byKey(textField1)));
    await tester.pumpAndSettle();
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);

    await tester.tap(find.byKey(textField2));
    await tester.pumpAndSettle();
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
  });

  testWidgets('Splash should never be created or canceled', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Theme(
          data: ThemeData.light().copyWith(splashFactory: const TestInkSplashFactory()),
          child: Material(
            child: ListView(
              children: <Widget>[
                const TextField(
                  decoration: InputDecoration(
                    labelText: 'label1',
                  ),
                ),
                const TextField(
                  decoration: InputDecoration(
                    labelText: 'label2',
                  ),
                ),
                Container(
                  height: 1000.0,
                  color: const Color(0xFF00FF00),
                ),
              ],
            ),
          ),
        ),
      ),
    );

    // If there were a splash, this would cancel the splash.
    final TestGesture gesture1 = await tester.startGesture(tester.getCenter(find.text('label1')));

    await tester.pump(kPressTimeout);

    await gesture1.moveTo(const Offset(400.0, 300.0));
    await gesture1.up();
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);

    // Pointer is dragged upwards causing a scroll, splash would be canceled.
    final TestGesture gesture2 = await tester.startGesture(tester.getCenter(find.text('label2')));
    await tester.pump(kPressTimeout);
    await gesture2.moveBy(const Offset(0.0, -200.0));
    await gesture2.up();
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
  });
}
