import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/document.dart';
import '../models/note.dart';
import '../providers/document_provider.dart';
import '../providers/note_provider.dart';
import '../providers/ocr_provider.dart';
import '../editor/pdf/spike_launcher.dart';
import '../services/pdf_service.dart';
import '../services/pptx_service.dart';
import 'note_editor_screen.dart';
import 'pdf_annotator_screen.dart';
import 'ppt_annotator_screen.dart';
import 'search_screen.dart';
import 'settings_screen.dart';
import 'split_view_screen.dart';

// [M1] Relative date helper — no new package dependencies.
String _formatDate(DateTime d) {
  final now = DateTime.now();
  final diff = now.difference(d);
  if (diff.inSeconds < 60) return 'Just now';
  if (diff.inMinutes < 60) return '${diff.inMinutes}m ago';
  if (diff.inHours < 24) return '${diff.inHours}h ago';
  if (diff.inDays == 1 || (diff.inDays == 0 && now.day != d.day)) {
    return 'Yesterday';
  }
  return '${d.month}/${d.day}/${d.year} ${d.hour}:${d.minute.toString().padLeft(2, '0')}';
}

class HomeScreen extends ConsumerWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final notesAsync = ref.watch(noteListProvider);

    return Scaffold(
      appBar: AppBar(
        title: const Text('BadNote'),
        centerTitle: true,
        actions: [
          IconButton(
            icon: const Icon(Icons.settings),
            tooltip: 'Settings',
            onPressed: () {
              Navigator.of(
                context,
              ).push(MaterialPageRoute(builder: (_) => const SettingsScreen()));
            },
          ),
          IconButton(
            icon: const Icon(Icons.picture_as_pdf),
            tooltip: 'Import PDF',
            onPressed: () => _importPdf(context),
          ),
          IconButton(
            icon: const Icon(Icons.slideshow),
            tooltip: 'Import PPT',
            onPressed: () => _importPptx(context),
          ),
          IconButton(
            icon: const Icon(Icons.search),
            tooltip: 'Search',
            onPressed: () {
              Navigator.of(
                context,
              ).push(MaterialPageRoute(builder: (_) => const SearchScreen()));
            },
          ),
          // New pen-first canvas editor (beta).
          IconButton(
            icon: const Icon(Icons.draw_outlined),
            tooltip: 'Pen Canvas (beta)',
            onPressed: () => openM1Spike(context),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => _createAndOpenNote(context, ref),
        child: const Icon(Icons.add),
      ),
      body: notesAsync.when(
        loading: () => const Center(child: CircularProgressIndicator()),
        error: (e, _) => Center(child: Text('Error: $e')),
        data: (notes) {
          final documentsAsync = ref.watch(documentListProvider);
          final documents = documentsAsync.valueOrNull ?? [];

          if (notes.isEmpty && documents.isEmpty) {
            return _buildEmptyState(context, ref);
          }
          return RefreshIndicator(
            onRefresh: () async {
              await Future.wait([
                ref.read(noteListProvider.notifier).loadNotes(),
                ref.read(documentListProvider.notifier).loadDocuments(),
              ]);
            },
            child: CustomScrollView(
              slivers: [
                // Notes section header always shown when documents exist
                SliverToBoxAdapter(
                  child: Padding(
                    padding: const EdgeInsets.fromLTRB(16, 12, 16, 4),
                    child: Text(
                      'Notes',
                      style: Theme.of(context).textTheme.titleMedium?.copyWith(
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                ),
                if (notes.isNotEmpty)
                  SliverList(
                    delegate: SliverChildBuilderDelegate(
                      (context, index) => _NoteTile(note: notes[index]),
                      childCount: notes.length,
                    ),
                  )
                else
                  // [M2] Per-section empty hint when documents exist but notes don't
                  SliverToBoxAdapter(
                    child: Padding(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 16,
                        vertical: 12,
                      ),
                      child: Center(
                        child: Text(
                          'No ink notes yet — tap + to create one',
                          style: Theme.of(context).textTheme.bodyMedium
                              ?.copyWith(
                                color: Theme.of(
                                  context,
                                ).colorScheme.onSurfaceVariant,
                              ),
                        ),
                      ),
                    ),
                  ),
                // Documents section header always shown when notes exist
                SliverToBoxAdapter(
                  child: Padding(
                    padding: const EdgeInsets.fromLTRB(16, 16, 16, 4),
                    child: Text(
                      'Recent Documents',
                      style: Theme.of(context).textTheme.titleMedium?.copyWith(
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                ),
                if (documents.isNotEmpty)
                  SliverList(
                    delegate: SliverChildBuilderDelegate(
                      (context, index) =>
                          _DocumentTile(document: documents[index]),
                      childCount: documents.length,
                    ),
                  )
                else
                  // [M2] Per-section empty hint when notes exist but documents don't
                  SliverToBoxAdapter(
                    child: Padding(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 16,
                        vertical: 12,
                      ),
                      child: Center(
                        child: Text(
                          'No documents yet — import a PDF or PPT',
                          style: Theme.of(context).textTheme.bodyMedium
                              ?.copyWith(
                                color: Theme.of(
                                  context,
                                ).colorScheme.onSurfaceVariant,
                              ),
                        ),
                      ),
                    ),
                  ),
                const SliverToBoxAdapter(child: SizedBox(height: 80)),
              ],
            ),
          );
        },
      ),
    );
  }

  Future<void> _createAndOpenNote(BuildContext context, WidgetRef ref) async {
    final note = await ref.read(noteListProvider.notifier).createNote();
    if (context.mounted) {
      Navigator.of(
        context,
      ).push(MaterialPageRoute(builder: (_) => NoteEditorScreen(note: note)));
    }
  }

  Future<void> _importPdf(BuildContext context) async {
    final pdfService = PdfService();
    final filePath = await pdfService.pickPdfFile();
    if (filePath != null && context.mounted) {
      Navigator.of(context).push(
        MaterialPageRoute(
          builder: (_) => PdfAnnotatorScreen(filePath: filePath),
        ),
      );
    }
  }

  Future<void> _importPptx(BuildContext context) async {
    final pptxService = PptxService();
    final filePath = await pptxService.openPptxFile();
    if (filePath == null || !context.mounted) return;

    if (context.mounted) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(const SnackBar(content: Text('Processing PPTX...')));
    }

    final slideImages = await pptxService.convertToImages(filePath);
    final extractedText = await pptxService.extractText(filePath);

    if (context.mounted) {
      Navigator.of(context).push(
        MaterialPageRoute(
          builder: (_) => PptAnnotatorScreen(
            filePath: filePath,
            slideImagePaths: slideImages,
            extractedText: extractedText.isEmpty ? null : extractedText,
          ),
        ),
      );
    }
  }

  Widget _buildEmptyState(BuildContext context, WidgetRef ref) {
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(
            Icons.edit_note,
            size: 80,
            color: Theme.of(context).colorScheme.primary,
          ),
          const SizedBox(height: 24),
          Text(
            'No notes yet',
            style: Theme.of(
              context,
            ).textTheme.headlineSmall?.copyWith(fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 8),
          Text(
            'Create your first note',
            style: Theme.of(context).textTheme.bodyLarge?.copyWith(
              color: Theme.of(context).colorScheme.onSurfaceVariant,
            ),
          ),
          const SizedBox(height: 32),
          FilledButton.icon(
            onPressed: () => _createAndOpenNote(context, ref),
            icon: const Icon(Icons.add),
            label: const Text('New Note'),
          ),
          const SizedBox(height: 12),
          OutlinedButton.icon(
            onPressed: () => _importPdf(context),
            icon: const Icon(Icons.picture_as_pdf),
            label: const Text('Import PDF'),
          ),
          const SizedBox(height: 12),
          OutlinedButton.icon(
            onPressed: () => _importPptx(context),
            icon: const Icon(Icons.slideshow),
            label: const Text('Import PPT'),
          ),
        ],
      ),
    );
  }
}

class _NoteTile extends ConsumerStatefulWidget {
  final Note note;
  const _NoteTile({required this.note});

  @override
  ConsumerState<_NoteTile> createState() => _NoteTileState();
}

class _NoteTileState extends ConsumerState<_NoteTile> {
  bool _hovering = false;

  @override
  Widget build(BuildContext context) {
    final note = widget.note;
    // [M1] Use relative date helper
    final dateStr = _formatDate(note.updatedAt);

    final ocrStatusMap = ref.watch(ocrStatusProvider);
    final ocrStatus = ocrStatusMap[note.id] ?? OcrStatus.none;

    final subtleColor = Theme.of(context).colorScheme.onSurfaceVariant;

    // [H2] Right-click context menu via GestureDetector + MouseRegion for hover
    return GestureDetector(
      onSecondaryTapDown: (details) =>
          _showContextMenu(context, details.globalPosition),
      child: MouseRegion(
        onEnter: (_) => setState(() => _hovering = true),
        onExit: (_) => setState(() => _hovering = false),
        child: ListTile(
          title: Row(
            children: [
              Expanded(
                child: Text(
                  note.title.isEmpty ? 'Untitled' : note.title,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
              _OcrStatusBadge(status: ocrStatus),
            ],
          ),
          subtitle: Padding(
            padding: const EdgeInsets.only(top: 4),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '${note.strokes.length} stroke${note.strokes.length == 1 ? '' : 's'} · $dateStr',
                  style: Theme.of(context).textTheme.bodySmall,
                ),
                if (note.tags.isNotEmpty)
                  Padding(
                    padding: const EdgeInsets.only(top: 4),
                    child: Wrap(
                      spacing: 4,
                      children: note.tags
                          .map(
                            (t) => Chip(
                              label: Text(
                                t,
                                style: const TextStyle(fontSize: 11),
                              ),
                              visualDensity: VisualDensity.compact,
                              padding: EdgeInsets.zero,
                              materialTapTargetSize:
                                  MaterialTapTargetSize.shrinkWrap,
                            ),
                          )
                          .toList(),
                    ),
                  ),
              ],
            ),
          ),
          // [H2] Trailing delete button — always visible with subdued color, brighter on hover
          trailing: IconButton(
            icon: Icon(
              Icons.delete_outline,
              color: _hovering
                  ? Theme.of(context).colorScheme.error
                  : subtleColor.withValues(alpha: 0.4),
            ),
            tooltip: 'Delete note',
            onPressed: () => _confirmDelete(context),
          ),
          onTap: () {
            Navigator.of(context).push(
              MaterialPageRoute(builder: (_) => NoteEditorScreen(note: note)),
            );
          },
          onLongPress: () => _confirmDelete(context),
        ),
      ),
    );
  }

  void _showContextMenu(BuildContext context, Offset position) async {
    final result = await showMenu<String>(
      context: context,
      position: RelativeRect.fromLTRB(
        position.dx,
        position.dy,
        position.dx + 1,
        position.dy + 1,
      ),
      items: [
        PopupMenuItem(
          value: 'open',
          child: Row(
            children: const [
              Icon(Icons.edit_outlined),
              SizedBox(width: 8),
              Text('Open'),
            ],
          ),
        ),
        PopupMenuItem(
          value: 'delete',
          child: Row(
            children: [
              Icon(
                Icons.delete_outline,
                color: Theme.of(context).colorScheme.error,
              ),
              const SizedBox(width: 8),
              Text(
                'Delete',
                style: TextStyle(color: Theme.of(context).colorScheme.error),
              ),
            ],
          ),
        ),
      ],
    );
    if (!mounted) return;
    if (result == 'open') {
      Navigator.of(this.context).push(
        MaterialPageRoute(builder: (_) => NoteEditorScreen(note: widget.note)),
      );
    } else if (result == 'delete') {
      _confirmDelete(this.context);
    }
  }

  void _confirmDelete(BuildContext context) {
    showDialog(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Delete note?'),
        content: Text(
          'Delete "${widget.note.title.isEmpty ? 'Untitled' : widget.note.title}"?',
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(ctx),
            child: const Text('Cancel'),
          ),
          TextButton(
            onPressed: () {
              ref.read(noteListProvider.notifier).deleteNote(widget.note.id);
              Navigator.pop(ctx);
            },
            child: const Text('Delete'),
          ),
        ],
      ),
    );
  }
}

class _DocumentTile extends ConsumerStatefulWidget {
  final Document document;
  const _DocumentTile({required this.document});

  @override
  ConsumerState<_DocumentTile> createState() => _DocumentTileState();
}

class _DocumentTileState extends ConsumerState<_DocumentTile> {
  bool _hovering = false;

  @override
  Widget build(BuildContext context) {
    final document = widget.document;
    // [M1] Use relative date helper
    final dateStr = _formatDate(document.updatedAt);
    final isPdf = document.docType == 'pdf';

    final subtleColor = Theme.of(context).colorScheme.onSurfaceVariant;

    // [H2] Right-click context menu + MouseRegion + trailing action buttons
    return GestureDetector(
      onSecondaryTapDown: (details) =>
          _showContextMenu(context, details.globalPosition),
      child: MouseRegion(
        onEnter: (_) => setState(() => _hovering = true),
        onExit: (_) => setState(() => _hovering = false),
        child: ListTile(
          leading: Icon(
            isPdf ? Icons.picture_as_pdf : Icons.slideshow,
            color: isPdf ? Colors.red : Colors.orange,
          ),
          title: Text(
            document.filename,
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
          ),
          subtitle: Text(
            '${document.docType.toUpperCase()} · ${document.pageCount} pages · $dateStr',
            style: Theme.of(context).textTheme.bodySmall,
          ),
          // [H2] Trailing row: split-view (PDF only) + remove
          trailing: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              if (isPdf)
                IconButton(
                  icon: Icon(
                    Icons.vertical_split,
                    color: _hovering
                        ? Theme.of(context).colorScheme.primary
                        : subtleColor.withValues(alpha: 0.4),
                  ),
                  tooltip: 'Open in Split View',
                  onPressed: () => _openSplitView(context),
                ),
              IconButton(
                icon: Icon(
                  Icons.delete_outline,
                  color: _hovering
                      ? Theme.of(context).colorScheme.error
                      : subtleColor.withValues(alpha: 0.4),
                ),
                tooltip: 'Remove document',
                onPressed: () => _confirmDelete(context),
              ),
            ],
          ),
          // [L2] Routing bug fix: route by docType
          onTap: () => _openDocument(context),
          onLongPress: () => _showDocumentMenu(context),
        ),
      ),
    );
  }

  // [L2] Route by docType: pdf → PdfAnnotatorScreen, ppt/pptx → PptAnnotatorScreen
  Future<void> _openDocument(BuildContext context) async {
    final document = widget.document;
    final isPdf = document.docType == 'pdf';

    if (isPdf) {
      Navigator.of(context).push(
        MaterialPageRoute(
          builder: (_) => PdfAnnotatorScreen(filePath: document.filePath),
        ),
      );
    } else {
      // PPT/PPTX: convert to images then push PptAnnotatorScreen
      if (mounted) {
        ScaffoldMessenger.of(this.context).showSnackBar(
          const SnackBar(content: Text('Processing presentation...')),
        );
      }
      final pptxService = PptxService();
      final slideImages = await pptxService.convertToImages(document.filePath);
      final extractedText = await pptxService.extractText(document.filePath);
      if (!mounted) return;
      if (slideImages.isEmpty) {
        ScaffoldMessenger.of(this.context).showSnackBar(
          const SnackBar(content: Text('Could not open presentation.')),
        );
        return;
      }
      Navigator.of(this.context).push(
        MaterialPageRoute(
          builder: (_) => PptAnnotatorScreen(
            filePath: document.filePath,
            slideImagePaths: slideImages,
            extractedText: extractedText.isEmpty ? null : extractedText,
          ),
        ),
      );
    }
  }

  void _openSplitView(BuildContext context) {
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (_) => SplitViewScreen(
          filePath: widget.document.filePath,
          documentId: widget.document.id,
        ),
      ),
    );
  }

  void _showContextMenu(BuildContext context, Offset position) async {
    final isPdf = widget.document.docType == 'pdf';
    final result = await showMenu<String>(
      context: context,
      position: RelativeRect.fromLTRB(
        position.dx,
        position.dy,
        position.dx + 1,
        position.dy + 1,
      ),
      items: [
        PopupMenuItem(
          value: 'open',
          child: Row(
            children: const [
              Icon(Icons.open_in_new),
              SizedBox(width: 8),
              Text('Open'),
            ],
          ),
        ),
        if (isPdf)
          PopupMenuItem(
            value: 'split',
            child: Row(
              children: const [
                Icon(Icons.vertical_split),
                SizedBox(width: 8),
                Text('Open in Split View'),
              ],
            ),
          ),
        PopupMenuItem(
          value: 'remove',
          child: Row(
            children: [
              Icon(
                Icons.delete_outline,
                color: Theme.of(context).colorScheme.error,
              ),
              const SizedBox(width: 8),
              Text(
                'Remove',
                style: TextStyle(color: Theme.of(context).colorScheme.error),
              ),
            ],
          ),
        ),
      ],
    );
    if (!mounted) return;
    if (result == 'open') {
      _openDocument(this.context);
    } else if (result == 'split') {
      _openSplitView(this.context);
    } else if (result == 'remove') {
      _confirmDelete(this.context);
    }
  }

  void _showDocumentMenu(BuildContext context) {
    final isPdf = widget.document.docType == 'pdf';
    showModalBottomSheet(
      context: context,
      builder: (ctx) {
        return SafeArea(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              if (isPdf)
                ListTile(
                  leading: const Icon(Icons.vertical_split),
                  title: const Text('Open in Split View'),
                  subtitle: const Text('PDF reference + scratchpad'),
                  onTap: () {
                    Navigator.of(ctx).pop();
                    _openSplitView(context);
                  },
                ),
              ListTile(
                leading: const Icon(Icons.delete_outline, color: Colors.red),
                title: const Text(
                  'Remove document',
                  style: TextStyle(color: Colors.red),
                ),
                onTap: () {
                  Navigator.of(ctx).pop();
                  _confirmDelete(context);
                },
              ),
            ],
          ),
        );
      },
    );
  }

  void _confirmDelete(BuildContext context) {
    showDialog(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Remove document?'),
        content: Text(
          'Remove "${widget.document.filename}" from recent documents?',
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(ctx),
            child: const Text('Cancel'),
          ),
          TextButton(
            onPressed: () {
              ref
                  .read(documentListProvider.notifier)
                  .removeDocument(widget.document.id);
              Navigator.pop(ctx);
            },
            child: const Text('Remove'),
          ),
        ],
      ),
    );
  }
}

// [M3] OCR status badge with semantic theme colors and tooltips
class _OcrStatusBadge extends StatelessWidget {
  final OcrStatus status;
  const _OcrStatusBadge({required this.status});

  @override
  Widget build(BuildContext context) {
    switch (status) {
      case OcrStatus.none:
        return const SizedBox.shrink();
      case OcrStatus.processing:
        return Tooltip(
          message: 'Processing OCR…',
          child: const SizedBox(
            width: 16,
            height: 16,
            child: CircularProgressIndicator(strokeWidth: 1.5),
          ),
        );
      case OcrStatus.done:
        return Tooltip(
          message: 'OCR complete',
          child: Icon(
            Icons.check_circle,
            size: 16,
            color: Theme.of(context).colorScheme.primary,
          ),
        );
      case OcrStatus.failed:
        return Tooltip(
          message: 'OCR failed',
          child: Icon(
            Icons.error_outline,
            size: 16,
            color: Theme.of(context).colorScheme.error,
          ),
        );
    }
  }
}
