import 'dart:io';

import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../models/note.dart';
import '../services/vault_service.dart';
import 'document_provider.dart' show vaultServiceProvider;

/// The home-screen note list is now sourced from a VAULT SCAN of standalone
/// (free-ink) notebook folders — each a folder holding a `notebook.badnote.json`
/// and NO importable source file — NOT the SQLite `notes` table. The sidecar
/// that lives in the folder is the source of truth ("跟着文件走").
///
/// Each scanned note is adapted into the existing [Note] model the home screen
/// already renders: `id` = the synthetic note path (`<folder>/notebook`, also a
/// stable id), `title`, `updatedAt` = the sidecar mtime. Strokes are NOT loaded
/// here — they are hydrated lazily by the editor from the sidecar, so the list
/// stays cheap (one directory listing). Home tiles that show a stroke count will
/// therefore read 0 until the note is opened; the count is no longer cached.
final noteListProvider = AsyncNotifierProvider<NoteListNotifier, List<Note>>(
  NoteListNotifier.new,
);

class NoteListNotifier extends AsyncNotifier<List<Note>> {
  Future<VaultService> get _vault => ref.read(vaultServiceProvider.future);

  @override
  Future<List<Note>> build() async {
    return _scan();
  }

  Future<List<Note>> _scan() async {
    final vault = await _vault;
    final notes = await vault.scanNotes();
    return notes.map(_toNote).toList();
  }

  /// Adapt a scanned [VaultNote] into the [Note] shape the home tiles render.
  /// `id` is the synthetic note path so opening it re-keys the right sidecar.
  Note _toNote(VaultNote n) => Note(
        id: n.notePath,
        title: n.title,
        createdAt: n.modified,
        updatedAt: n.modified,
      );

  /// Re-scan the vault and publish the result. Used by pull-to-refresh and
  /// after a note is created or edited.
  Future<void> loadNotes() async {
    state = const AsyncLoading();
    state = await AsyncValue.guard(_scan);
  }

  /// Create an empty standalone notebook folder with [title] and return the
  /// adapted [Note] (whose `id` is the synthetic note path). The home screen
  /// opens the editor on it; persistence flows through the sidecar.
  Future<Note> createNote({String title = 'Untitled'}) async {
    final vault = await _vault;
    final notePath = await vault.createEmptyNotebook(title);
    final now = DateTime.now();
    final note = Note(
      id: notePath,
      title: title,
      createdAt: now,
      updatedAt: now,
    );
    state = AsyncData([note, ...state.value ?? []]);
    return note;
  }

  /// Delete a note by removing its notebook folder (the sidecar travels with
  /// it). [id] is the synthetic note path `<folder>/notebook`.
  Future<void> deleteNote(String id) async {
    final folder = Directory(File(id).parent.path);
    if (await folder.exists()) {
      await folder.delete(recursive: true);
    }
    final current = state.value ?? [];
    state = AsyncData(current.where((n) => n.id != id).toList());
  }
}
