// Screen-level guard for the pen-first note editor: an existing note's ink
// strokes load onto the PenCanvas via the adapter, and a stylus pass commits a
// new stroke. Exercises the real PenNoteScreen (no DB needed — persistence only
// runs on save).

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

import 'package:badnote/editor/canvas/pen_canvas.dart';
import 'package:badnote/editor/canvas/pen_note_screen.dart';
import 'package:badnote/models/ink_point.dart';
import 'package:badnote/models/ink_stroke.dart';
import 'package:badnote/models/note.dart';
import 'package:badnote/models/pen_tool.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  Note noteWith(List<InkStroke> strokes) => Note(
        id: 'n1',
        title: 'Test',
        strokes: strokes,
        createdAt: DateTime.fromMillisecondsSinceEpoch(0),
        updatedAt: DateTime.fromMillisecondsSinceEpoch(0),
      );

  InkStroke freehand() => InkStroke(
        id: 's1',
        points: const [
          InkPoint(x: 100, y: 200, timestamp: 0),
          InkPoint(x: 300, y: 400, timestamp: 0),
          InkPoint(x: 500, y: 700, timestamp: 0),
        ],
        tool: PenTool.pen,
        createdAt: DateTime.fromMillisecondsSinceEpoch(0),
      );

  int canvasStrokeCount(WidgetTester tester) =>
      tester.widget<PenCanvas>(find.byType(PenCanvas)).strokes.length;

  testWidgets('loads an existing note\'s ink strokes onto the canvas',
      (tester) async {
    SharedPreferences.setMockInitialValues({});
    await tester.pumpWidget(ProviderScope(
      child: MaterialApp(home: PenNoteScreen(note: noteWith([freehand()]))),
    ));
    await tester.pump(); // let PenConfig load

    expect(find.byType(PenCanvas), findsOneWidget);
    expect(canvasStrokeCount(tester), 1,
        reason: 'the note\'s freehand stroke should load via the adapter');
  });

  testWidgets('a stylus pass commits a new stroke', (tester) async {
    SharedPreferences.setMockInitialValues({});
    await tester.pumpWidget(ProviderScope(
      child: MaterialApp(home: PenNoteScreen(note: noteWith([]))),
    ));
    await tester.pump();

    expect(canvasStrokeCount(tester), 0);

    final center = tester.getCenter(find.byType(PenCanvas));
    final g = await tester.startGesture(center, kind: PointerDeviceKind.stylus);
    await g.moveBy(const Offset(40, 30));
    await g.moveBy(const Offset(30, 20));
    await g.up();
    await tester.pump();

    expect(canvasStrokeCount(tester), 1,
        reason: 'the drawn stroke should be committed to the canvas');
  });
}
