// Device-independent widget test of the eraser path (the user reported eraser
// reliability issues). A stylus drag through a committed stroke in eraser mode
// must fire onEraseStroke for that stroke.

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

import 'package:badnote/editor/canvas/pen_canvas.dart';
import 'package:badnote/editor/canvas/pen_stroke.dart';

void main() {
  const pageSize = Size(400, 600);

  // A horizontal stroke through the normalized center (0.5, 0.5).
  PenStroke centerStroke() => PenStroke(
        points: const [
          PenPoint(0.4, 0.5, 0.5),
          PenPoint(0.5, 0.5, 0.5),
          PenPoint(0.6, 0.5, 0.5),
        ],
        color: 0xFF000000,
        width: 0.004,
        kind: PenStrokeKind.pen,
      );

  Widget host({
    required List<PenStroke> strokes,
    required void Function(int, List<PenStroke>) onErase,
    required TransformationController controller,
  }) =>
      MaterialApp(
        home: Scaffold(
          body: Center(
            child: SizedBox(
              width: pageSize.width,
              height: pageSize.height,
              child: PenCanvas(
                pageWidget: Container(color: const Color(0xFFEEEEEE)),
                pageSize: pageSize,
                strokes: strokes,
                transformationController: controller,
                tool: CanvasTool.eraser,
                color: const Color(0xFF000000),
                strokeWidth: 0.004,
                onStrokeComplete: (_) {},
                onEraseStroke: onErase,
              ),
            ),
          ),
        ),
      );

  testWidgets('eraser tool: a stylus pass over a stroke fires onEraseStroke',
      (tester) async {
    final erased = <int>[];
    final controller = TransformationController();
    addTearDown(controller.dispose);

    await tester.pumpWidget(host(
      strokes: [centerStroke()],
      onErase: (i, _) => erased.add(i),
      controller: controller,
    ));

    // Drag a stylus vertically through the screen center (= normalized 0.5,0.5,
    // where the stroke sits).
    final center = tester.getCenter(find.byType(PenCanvas));
    final g = await tester.startGesture(center + const Offset(0, -20),
        kind: PointerDeviceKind.stylus);
    await g.moveBy(const Offset(0, 20));
    await g.moveBy(const Offset(0, 20));
    await g.up();
    await tester.pump();

    expect(erased, contains(0), reason: 'the center stroke should be erased');
  });

  testWidgets('eraser tool: a pass far from any stroke erases nothing',
      (tester) async {
    final erased = <int>[];
    final controller = TransformationController();
    addTearDown(controller.dispose);

    await tester.pumpWidget(host(
      strokes: [centerStroke()],
      onErase: (i, _) => erased.add(i),
      controller: controller,
    ));

    // Drag in the top-left corner, far from the centered stroke.
    final topLeft = tester.getTopLeft(find.byType(PenCanvas));
    final g = await tester.startGesture(topLeft + const Offset(10, 10),
        kind: PointerDeviceKind.stylus);
    await g.moveBy(const Offset(5, 5));
    await g.up();
    await tester.pump();

    expect(erased, isEmpty);
  });
}
