// Guards the two eraser modes (the "优化橡皮擦工具" work): the default point
// eraser cuts a stroke into surviving segments, while the new stroke-eraser
// mode removes the entire stroke on contact. Both are driven by the same
// stylus pass; only the eraserWholeStroke flag differs.

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 long horizontal stroke spanning the page through the vertical center.
  PenStroke longStroke() => PenStroke(
        points: const [
          PenPoint(0.1, 0.5, 0.5),
          PenPoint(0.3, 0.5, 0.5),
          PenPoint(0.5, 0.5, 0.5),
          PenPoint(0.7, 0.5, 0.5),
          PenPoint(0.9, 0.5, 0.5),
        ],
        color: 0xFF000000,
        width: 0.004,
        kind: PenStrokeKind.pen,
      );

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

  // Drag the eraser vertically through the page center (normalized 0.5, 0.5),
  // grazing the MIDDLE of the long horizontal stroke.
  Future<void> erasePass(WidgetTester tester) async {
    final center = tester.getCenter(find.byType(PenCanvas));
    final g = await tester.startGesture(center + const Offset(0, -15),
        kind: PointerDeviceKind.stylus);
    await g.moveBy(const Offset(0, 15));
    await g.moveBy(const Offset(0, 15));
    await g.up();
    await tester.pump();
  }

  testWidgets('point eraser (default) splits the stroke into surviving pieces',
      (tester) async {
    List<PenStroke>? replacement;
    await tester.pumpWidget(host(
      onErase: (_, pieces) => replacement = pieces,
      wholeStroke: false,
    ));
    await erasePass(tester);

    expect(replacement, isNotNull, reason: 'an erase should have fired');
    // Grazing the middle leaves the two ends as surviving sub-strokes.
    expect(replacement!.length, greaterThanOrEqualTo(1));
    expect(replacement, isNotEmpty,
        reason: 'point eraser keeps the untouched ends');
  });

  testWidgets('stroke eraser removes the entire stroke on contact',
      (tester) async {
    List<PenStroke>? replacement;
    await tester.pumpWidget(host(
      onErase: (_, pieces) => replacement = pieces,
      wholeStroke: true,
    ));
    await erasePass(tester);

    expect(replacement, isNotNull, reason: 'an erase should have fired');
    expect(replacement, isEmpty,
        reason: 'stroke eraser deletes the whole stroke, leaving no pieces');
  });
}
