// lib/editor/canvas/sticky_note_overlay.dart
//
// Paper-sticky UX for PDF scratch links: a floating card on the viewer that
// inks into the SAME SidecarRepository the PDF editor holds (no second open,
// no split-view race). Collapsed = page marker; expanded = this overlay.

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';

import '../../models/ink_stroke.dart';
import '../../models/scratch_link.dart';
import '../../storage/badnote_sidecar.dart';
import '../engine/brush.dart';
import '../input/pen_config.dart' show kDefaultEraserRadius;
import '../notebook/ink_stroke_adapter.dart';
import '../persistence/sidecar_repository.dart';
import 'pen_canvas.dart';
import 'pen_palette_widgets.dart';
import 'pen_stroke.dart';

/// Default world size for a fresh sticky scratchpad (absolute px).
const Size kStickyWorldSize = Size(1200, 900);

/// Floating sticky-note card: write → autosave into [repo] under [link.id].
class StickyNoteOverlay extends StatefulWidget {
  const StickyNoteOverlay({
    super.key,
    required this.link,
    required this.repo,
    required this.onClose,
    required this.onDelete,
  });

  final ScratchLink link;
  final SidecarRepository repo;
  final VoidCallback onClose;
  final VoidCallback onDelete;

  @override
  State<StickyNoteOverlay> createState() => _StickyNoteOverlayState();
}

class _StickyNoteOverlayState extends State<StickyNoteOverlay> {
  static const _uuid = Uuid();

  final TransformationController _transform = TransformationController();
  List<InkStroke> _strokes = [];
  Size _world = kStickyWorldSize;
  CanvasTool _tool = CanvasTool.pen;
  BrushKind _brush = BrushKind.ballpoint; // ignore: prefer_final_fields — reserved for brush picker
  Color _color = kInkPalette.first;
  Timer? _saveTimer;
  bool _dirty = false;

  @override
  void initState() {
    super.initState();
    final pad = widget.repo.scratchpadFor(widget.link.id);
    if (pad != null) {
      _world = Size(pad.canvasWidth, pad.canvasHeight);
      _strokes = pad.strokes.where((s) => isFreehandTool(s.tool)).toList();
    }
  }

  @override
  void dispose() {
    _saveTimer?.cancel();
    // Best-effort sync save before leaving the overlay.
    if (_dirty) {
      widget.repo.scheduleScratchpadSave(
        widget.link.id,
        SidecarScratchpad(
          canvasWidth: _world.width,
          canvasHeight: _world.height,
          strokes: List<InkStroke>.of(_strokes),
        ),
      );
      widget.repo.flush();
    }
    _transform.dispose();
    super.dispose();
  }

  void _scheduleSave() {
    _dirty = true;
    _saveTimer?.cancel();
    _saveTimer = Timer(const Duration(milliseconds: 600), _saveNow);
  }

  Future<void> _saveNow() async {
    if (!_dirty) return;
    widget.repo.scheduleScratchpadSave(
      widget.link.id,
      SidecarScratchpad(
        canvasWidth: _world.width,
        canvasHeight: _world.height,
        strokes: List<InkStroke>.of(_strokes),
      ),
    );
    _dirty = false;
    await widget.repo.flush();
  }

  void _onStrokeComplete(PenStroke pen) {
    setState(() {
      _strokes = [
        ..._strokes,
        inkStrokeFromPen(pen, _world, id: _uuid.v4(), createdAt: DateTime.now()),
      ];
    });
    _scheduleSave();
  }

  void _onErase(int index, List<PenStroke> replacements) {
    if (index < 0 || index >= _strokes.length) return;
    setState(() {
      final next = List<InkStroke>.of(_strokes)..removeAt(index);
      for (final r in replacements) {
        next.insert(
          index,
          inkStrokeFromPen(r, _world, id: _uuid.v4(), createdAt: DateTime.now()),
        );
      }
      _strokes = next;
    });
    _scheduleSave();
  }

  Future<void> _close() async {
    _saveTimer?.cancel();
    await _saveNow();
    widget.onClose();
  }

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    return Material(
      elevation: 8,
      borderRadius: BorderRadius.circular(4),
      color: const Color(0xFFFFF8E1),
      child: SizedBox(
        width: 280,
        height: 340,
        child: Column(
          children: [
            Container(
              height: 36,
              padding: const EdgeInsets.symmetric(horizontal: 4),
              decoration: const BoxDecoration(
                color: Color(0xFFFFE082),
                borderRadius: BorderRadius.vertical(top: Radius.circular(4)),
              ),
              child: Row(
                children: [
                  const Icon(Icons.sticky_note_2, size: 18),
                  const SizedBox(width: 6),
                  const Expanded(
                    child: Text(
                      '便利贴',
                      style: TextStyle(
                        fontSize: 13,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ),
                  IconButton(
                    tooltip: '删除',
                    icon: const Icon(Icons.delete_outline, size: 18),
                    visualDensity: VisualDensity.compact,
                    onPressed: () async {
                      await _saveNow();
                      widget.onDelete();
                    },
                  ),
                  IconButton(
                    tooltip: '收起',
                    icon: const Icon(Icons.close, size: 18),
                    visualDensity: VisualDensity.compact,
                    onPressed: _close,
                  ),
                ],
              ),
            ),
            SizedBox(
              height: 32,
              child: ListView(
                scrollDirection: Axis.horizontal,
                padding: const EdgeInsets.symmetric(horizontal: 6),
                children: [
                  for (final c in kInkPalette)
                    GestureDetector(
                      onTap: () => setState(() => _color = c),
                      child: Container(
                        width: 18,
                        height: 18,
                        margin: const EdgeInsets.symmetric(
                            horizontal: 3, vertical: 7),
                        decoration: BoxDecoration(
                          color: c,
                          shape: BoxShape.circle,
                          border: Border.all(
                            color: _color == c ? cs.primary : cs.outlineVariant,
                            width: _color == c ? 2 : 1,
                          ),
                        ),
                      ),
                    ),
                ],
              ),
            ),
            Expanded(
              child: ClipRect(
                child: PenCanvas(
                  pageSize: _world,
                  strokes: penStrokesFromInk(_strokes, _world),
                  transformationController: _transform,
                  tool: _tool,
                  brush: _brush,
                  color: _color,
                  strokeWidth: 0.008,
                  eraserRadius: kDefaultEraserRadius,
                  minScale: 0.2,
                  maxScale: 4.0,
                  onStrokeComplete: _onStrokeComplete,
                  onEraseStroke: _onErase,
                  pageWidget: const ColoredBox(color: Color(0xFFFFFDE7)),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
              child: Row(
                children: [
                  IconButton(
                    tooltip: '笔',
                    icon: Icon(
                      Icons.edit,
                      size: 18,
                      color: _tool == CanvasTool.pen ? cs.primary : null,
                    ),
                    onPressed: () => setState(() => _tool = CanvasTool.pen),
                  ),
                  IconButton(
                    tooltip: '橡皮',
                    icon: Icon(
                      Icons.cleaning_services_outlined,
                      size: 18,
                      color: _tool == CanvasTool.eraser ? cs.primary : null,
                    ),
                    onPressed: () => setState(() => _tool = CanvasTool.eraser),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
