import 'package:flutter/material.dart';
import 'package:flutter_fullscreen/flutter_fullscreen.dart';
import 'package:logging/logging.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:sheetless/core/models/config.dart';
import 'package:sheetless/core/models/sheet.dart';
import 'package:sheetless/core/services/api_client.dart';
import 'package:sheetless/core/services/storage_service.dart';
import 'package:sheetless/core/services/sync_service.dart';

import '../../app.dart';
import '../auth/login_page.dart';
import '../sheet_viewer/sheet_viewer_page.dart';
import 'widgets/app_drawer.dart';
import 'widgets/sheets_list.dart';

/// Main home page displaying the list of sheet music.
///
/// Features:
/// - Pull-to-refresh sheet list
/// - Shuffle mode for random practice
/// - Navigation to sheet viewer
/// - Logout functionality
class HomePage extends StatefulWidget {
  final Config config;

  const HomePage({super.key, required this.config});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with RouteAware {
  final _log = Logger('HomePage');
  final _storageService = StorageService();

  ApiClient? _apiClient;
  SyncService? _syncService;
  late Future<SyncResult> _syncFuture;
  List<Sheet> _sheets = [];
  bool _isShuffling = false;
  bool _isOnline = true;
  String? _appName;
  String? _appVersion;

  @override
  void initState() {
    super.initState();

    // Exit fullscreen when entering home page
    if (FullScreen.isFullScreen) {
      FullScreen.setFullScreen(false);
    }

    // Subscribe to route changes
    WidgetsBinding.instance.addPostFrameCallback((_) {
      routeObserver.subscribe(this, ModalRoute.of(context)!);
    });

    _loadAppInfo();
    _syncFuture = _loadSheets();
  }

  @override
  void dispose() {
    routeObserver.unsubscribe(this);
    super.dispose();
  }

  // ---------------------------------------------------------------------------
  // Route Aware (Fullscreen Management)
  // ---------------------------------------------------------------------------

  @override
  void didPush() {
    // Exit fullscreen when entering home page
    if (FullScreen.isFullScreen) {
      FullScreen.setFullScreen(false);
    }
    super.didPush();
  }

  @override
  void didPopNext() {
    // Exit fullscreen when returning to home page
    if (FullScreen.isFullScreen) {
      FullScreen.setFullScreen(false);
    }
    super.didPopNext();
  }

  // ---------------------------------------------------------------------------
  // Data Loading
  // ---------------------------------------------------------------------------

  Future<void> _loadAppInfo() async {
    final info = await PackageInfo.fromPlatform();
    setState(() {
      _appName = info.appName;
      _appVersion = info.version;
    });
  }

  Future<SyncResult> _loadSheets() async {
    final url = await _storageService.readSecure(SecureStorageKey.url);
    final refreshToken = await _storageService.readSecure(
      SecureStorageKey.refreshToken,
    );

    _apiClient = ApiClient(baseUrl: url!, refreshToken: refreshToken);
    _syncService = SyncService(
      apiClient: _apiClient!,
      storageService: _storageService,
    );

    // Perform sync (fetches sheets, uploads pending changes/annotations)
    final result = await _syncService!.sync();
    _log.info(
      '${result.sheets.length} sheets loaded (online: ${result.isOnline}, '
      'changes synced: ${result.changesSynced}, '
      'annotations synced: ${result.annotationsSynced})',
    );

    // Sort and store sheets
    _sheets = await _sortSheetsByRecency(result.sheets);
    setState(() {
      _isOnline = result.isOnline;
    });

    for (var sheet in _sheets) {
      sheet.availableOffline = await _apiClient!.isPdfFileCached(sheet.uuid);
    }

    return result;
  }

  Future<List<Sheet>> _sortSheetsByRecency(List<Sheet> sheets) async {
    final accessTimes = await _storageService.readSheetAccessTimes();

    sheets.sort((a, b) {
      // Use local access time if available and more recent than server update
      var dateA = accessTimes[a.uuid];
      var dateB = accessTimes[b.uuid];

      if (dateA == null || a.updatedAt.isAfter(dateA)) {
        dateA = a.updatedAt;
      }
      if (dateB == null || b.updatedAt.isAfter(dateB)) {
        dateB = b.updatedAt;
      }

      return dateB.compareTo(dateA); // Most recent first
    });

    return sheets;
  }

  Future<void> _refreshSheets() async {
    setState(() {
      _syncFuture = _loadSheets();
    });
  }

  // ---------------------------------------------------------------------------
  // Actions
  // ---------------------------------------------------------------------------

  void _handleShuffleChanged(bool enabled) async {
    if (enabled) {
      _sheets.shuffle();
    } else {
      await _sortSheetsByRecency(_sheets);
    }

    setState(() => _isShuffling = enabled);
  }

  Future<void> _handleLogout() async {
    await _storageService.clearAllUserData();
    await _apiClient!.logout();

    if (!mounted) return;

    Navigator.of(
      context,
    ).pushReplacement(MaterialPageRoute(builder: (_) => const LoginPage()));
  }

  void _openSheet(Sheet sheet) {
    // Record access time for recency sorting
    _storageService.writeSheetAccessTime(sheet.uuid, DateTime.now());

    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (_) => SheetViewerPage(
          sheet: sheet,
          apiClient: _apiClient!,
          config: widget.config,
        ),
      ),
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text('Sheetless'),
            if (!_isOnline)
              const Padding(
                padding: EdgeInsets.only(left: 8),
                child: Icon(Icons.cloud_off, color: Colors.orange, size: 20),
              ),
          ],
        ),
      ),
      endDrawer: AppDrawer(
        isShuffling: _isShuffling,
        onShuffleChanged: _handleShuffleChanged,
        onLogout: _handleLogout,
        appName: _appName,
        appVersion: _appVersion,
        syncFuture: _syncFuture,
      ),
      body: RefreshIndicator(onRefresh: _refreshSheets, child: _buildBody()),
    );
  }

  Widget _buildBody() {
    return FutureBuilder<SyncResult>(
      future: _syncFuture,
      builder: (context, snapshot) {
        if (snapshot.connectionState != ConnectionState.done) {
          return const Center(child: CircularProgressIndicator());
        }

        if (snapshot.hasError) {
          _log.warning('Error loading sheets', snapshot.error);
          return _buildError(snapshot.error.toString());
        }

        if (snapshot.hasData) {
          return SheetsList(
            sheets: _sheets,
            onSheetSelected: _openSheet,
            syncService: _syncService!,
          );
        }

        return const Center(child: CircularProgressIndicator());
      },
    );
  }

  Widget _buildError(String message) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Text(
          message,
          style: Theme.of(
            context,
          ).textTheme.titleMedium?.copyWith(color: Colors.red),
          textAlign: TextAlign.center,
        ),
      ),
    );
  }
}
