// lib/models/scratch_link.dart
//
// A PDF-anchored scratch link: a sticky-note "tab" placed at a normalized
// position (nx, ny in [0,1]) on a specific page of a document. Tapping the
// anchor opens a split view whose right pane is an infinite freehand scratchpad
// that BELONGS TO THIS ANCHOR (keyed by [id]).
//
// Plain immutable value class (no freezed codegen) so it compiles without a
// build_runner step. Equality is by value so anchors can be diffed in lists.

import 'package:flutter/foundation.dart';

@immutable
class ScratchLink {
  const ScratchLink({
    required this.id,
    required this.documentId,
    required this.pageIndex,
    required this.nx,
    required this.ny,
  });

  /// Stable anchor id (uuid). Doubles as the scratchpad storage key so each
  /// anchor gets its own private infinite scratchpad.
  final String id;

  /// The owning document (the editor's stable document-id for the PDF path).
  final String documentId;

  /// 0-based page the anchor sits on.
  final int pageIndex;

  /// Normalized horizontal position on the page, in [0, 1].
  final double nx;

  /// Normalized vertical position on the page, in [0, 1].
  final double ny;

  ScratchLink copyWith({
    String? id,
    String? documentId,
    int? pageIndex,
    double? nx,
    double? ny,
  }) =>
      ScratchLink(
        id: id ?? this.id,
        documentId: documentId ?? this.documentId,
        pageIndex: pageIndex ?? this.pageIndex,
        nx: nx ?? this.nx,
        ny: ny ?? this.ny,
      );

  Map<String, dynamic> toJson() => {
        'id': id,
        'documentId': documentId,
        'pageIndex': pageIndex,
        'nx': nx,
        'ny': ny,
      };

  factory ScratchLink.fromJson(Map<String, dynamic> json) => ScratchLink(
        id: json['id'] as String,
        documentId: json['documentId'] as String,
        pageIndex: (json['pageIndex'] as num).toInt(),
        nx: (json['nx'] as num).toDouble(),
        ny: (json['ny'] as num).toDouble(),
      );

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is ScratchLink &&
          runtimeType == other.runtimeType &&
          id == other.id &&
          documentId == other.documentId &&
          pageIndex == other.pageIndex &&
          nx == other.nx &&
          ny == other.ny;

  @override
  int get hashCode => Object.hash(id, documentId, pageIndex, nx, ny);

  @override
  String toString() =>
      'ScratchLink(id: $id, documentId: $documentId, pageIndex: $pageIndex, '
      'nx: $nx, ny: $ny)';
}
