import 'dart:async';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:sheetless/core/models/change.dart';
import 'package:sheetless/core/models/sheet.dart';
import 'package:sheetless/core/services/sync_service.dart';

import '../../../shared/widgets/edit_sheet_bottom_sheet.dart';
import 'sheet_list_item.dart';
import 'sheet_search_bar.dart';

/// Widget displaying a searchable list of sheets.
///
/// Features:
/// - Debounced search filtering by name and composer
/// - Long-press to edit sheet metadata
/// - Cross-platform scroll support (mouse and touch)
class SheetsList extends StatefulWidget {
  final List<Sheet> sheets;
  final ValueSetter<Sheet> onSheetSelected;
  final SyncService syncService;

  const SheetsList({
    super.key,
    required this.sheets,
    required this.onSheetSelected,
    required this.syncService,
  });

  @override
  State<SheetsList> createState() => _SheetsListState();
}

class _SheetsListState extends State<SheetsList> {
  static const _searchDebounceMs = 500;

  final _searchController = TextEditingController();
  Timer? _debounceTimer;
  late List<Sheet> _filteredSheets;

  @override
  void initState() {
    super.initState();
    _filteredSheets = widget.sheets;
    _searchController.addListener(_onSearchChanged);
  }

  @override
  void dispose() {
    _searchController.removeListener(_onSearchChanged);
    _searchController.dispose();
    _debounceTimer?.cancel();
    super.dispose();
  }

  // ---------------------------------------------------------------------------
  // Search
  // ---------------------------------------------------------------------------

  void _onSearchChanged() {
    _debounceTimer?.cancel();
    _debounceTimer = Timer(
      const Duration(milliseconds: _searchDebounceMs),
      _filterSheets,
    );
  }

  void _filterSheets() {
    final query = _searchController.text.toLowerCase().trim();

    if (query.isEmpty) {
      setState(() => _filteredSheets = widget.sheets);
      return;
    }

    // Split query into terms for multi-word search
    final terms = query.split(RegExp(r'\s+'));

    setState(() {
      _filteredSheets = widget.sheets.where((sheet) {
        final name = sheet.name.toLowerCase();
        final composer = sheet.composer.toLowerCase();

        // Each term must appear in either name or composer
        return terms.every(
          (term) => name.contains(term) || composer.contains(term),
        );
      }).toList();
    });
  }

  void _clearSearch() {
    _searchController.clear();
    setState(() => _filteredSheets = widget.sheets);
  }

  // ---------------------------------------------------------------------------
  // Edit Sheet
  // ---------------------------------------------------------------------------

  void _openEditSheet(BuildContext context, Sheet sheet) {
    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      builder: (_) => EditSheetBottomSheet(
        sheet: sheet,
        onSave: (newName, newComposer) =>
            _handleSheetEdit(sheet, newName, newComposer),
      ),
    );
  }

  void _handleSheetEdit(Sheet sheet, String newName, String newComposer) {
    // Queue changes for server sync (with timestamp for conflict resolution)
    if (newName != sheet.name) {
      widget.syncService.queueChange(
        Change(
          type: ChangeType.sheetNameChange,
          sheetUuid: sheet.uuid,
          value: newName,
        ),
      );
    }
    if (newComposer != sheet.composer) {
      widget.syncService.queueChange(
        Change(
          type: ChangeType.composerNameChange,
          sheetUuid: sheet.uuid,
          value: newComposer,
        ),
      );
    }

    // Update local state
    setState(() {
      sheet.name = newName;
      sheet.composer = newComposer;
    });

    // Update cached sheets
    widget.syncService.updateCachedSheets(widget.sheets);
  }

  // ---------------------------------------------------------------------------
  // Sheet Selection
  // ---------------------------------------------------------------------------

  void _handleSheetTap(Sheet sheet) {
    // Move selected sheet to top of list (most recently accessed)
    widget.sheets.remove(sheet);
    widget.sheets.insert(0, sheet);

    widget.onSheetSelected(sheet);
  }

  // ---------------------------------------------------------------------------
  // UI
  // ---------------------------------------------------------------------------

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SheetSearchBar(controller: _searchController, onClear: _clearSearch),
        Expanded(child: _buildList()),
      ],
    );
  }

  Widget _buildList() {
    // Enable both mouse and touch scrolling for web compatibility
    return ScrollConfiguration(
      behavior: ScrollConfiguration.of(context).copyWith(
        dragDevices: {PointerDeviceKind.touch, PointerDeviceKind.mouse},
      ),
      child: ListView.builder(
        physics: const AlwaysScrollableScrollPhysics(),
        itemCount: _filteredSheets.length,
        itemBuilder: (context, index) {
          final sheet = _filteredSheets[index];
          return SheetListItem(
            sheet: sheet,
            onTap: () => _handleSheetTap(sheet),
            onLongPress: () => _openEditSheet(context, sheet),
          );
        },
      ),
    );
  }
}
