using Android.Graphics.Fonts;
using BookReader.Models;
using BookReader.Services;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace BookReader.ViewModels;

[QueryProperty(nameof(Book), "Book")]
public partial class ReaderViewModel : BaseViewModel
{
    private readonly IDatabaseService _databaseService;
    private readonly ISettingsService _settingsService;

    [ObservableProperty]
    private Book? _book;

    [ObservableProperty]
    private bool _isMenuVisible;

    [ObservableProperty]
    private bool _isChapterListVisible;

    [ObservableProperty]
    private int _fontSize;

    [ObservableProperty]
    private string _fontFamily = "serif";

    [ObservableProperty]
    private List<string> _chapters = new();

    [ObservableProperty]
    private string? _selectedChapter;

    [ObservableProperty]
    private int _chapterCurrentPage = 1;

    [ObservableProperty]
    private int _chapterTotalPages = 1;

    [ObservableProperty]
    private int _currentPage = 1;

    [ObservableProperty]
    private int _totalPages = 1;

    // Это свойство будет обновляться автоматически при изменении любого из полей выше
    public string ChapterProgressText => $"{ChapterCurrentPage} из {ChapterTotalPages}";

    // Это свойство будет обновляться автоматически при изменении любого из полей выше
    public string ProgressText => $"{CurrentPage} из {TotalPages}";

    // Чтобы ChapterProgressText уведомлял интерфейс, добавим частичные методы (особенность Toolkit)
    partial void OnChapterCurrentPageChanged(int value) => OnPropertyChanged(nameof(ChapterProgressText));
    partial void OnChapterTotalPagesChanged(int value) => OnPropertyChanged(nameof(ChapterProgressText));

    // Чтобы ProgressText уведомлял интерфейс, добавим частичные методы (особенность Toolkit)
    partial void OnCurrentPageChanged(int value) => OnPropertyChanged(nameof(ProgressText));
    partial void OnTotalPagesChanged(int value) => OnPropertyChanged(nameof(ProgressText));

    public List<string> AvailableFonts { get; } = new()
    {
        "serif",
        "sans-serif",
        "monospace",
        "Georgia",
        "Palatino",
        "Times New Roman",
        "Arial",
        "Verdana",
        "Courier New"
    };

    public List<int> AvailableFontSizes { get; } = new()
    {
        12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 36, 40
    };

    // Events for the view to subscribe to
    public event Action<string>? OnJavaScriptRequested;
    public event Action? OnBookReady;

    public ReaderViewModel(IDatabaseService databaseService, ISettingsService settingsService)
    {
        _databaseService = databaseService;
        _settingsService = settingsService;
        _fontSize = 18;
    }

    public async Task InitializeAsync()
    {
        var savedFontSize = await _settingsService.GetIntAsync(SettingsKeys.DefaultFontSize, 18);
        var savedFontFamily = await _settingsService.GetAsync(SettingsKeys.DefaultFontFamily, "serif");

        FontSize = savedFontSize;
        FontFamily = savedFontFamily;
    }

    [RelayCommand]
    public void ToggleMenu()
    {
        IsMenuVisible = !IsMenuVisible;
        if (!IsMenuVisible)
            IsChapterListVisible = false;
    }

    [RelayCommand]
    public void HideMenu()
    {
        IsMenuVisible = false;
        IsChapterListVisible = false;
    }

    [RelayCommand]
    public void ToggleChapterList()
    {
        IsChapterListVisible = !IsChapterListVisible;
    }

    [RelayCommand]
    public void ChangeFontSize(int size)
    {
        FontSize = size;
        OnJavaScriptRequested?.Invoke($"setFontSize({size})");
        _ = _settingsService.SetIntAsync(SettingsKeys.DefaultFontSize, size);
    }

    [RelayCommand]
    public void ChangeFontFamily(string family)
    {
        FontFamily = family;
        OnJavaScriptRequested?.Invoke($"setFontFamily('{family}')");
        _ = _settingsService.SetAsync(SettingsKeys.DefaultFontFamily, family);
    }

    [RelayCommand]
    public void GoToChapter(string chapter)
    {
        if (string.IsNullOrEmpty(chapter)) return;
        OnJavaScriptRequested?.Invoke($"goToChapter('{EscapeJs(chapter)}')");
        IsChapterListVisible = false;
        IsMenuVisible = false;
    }

    public async Task SaveLocationsAsync(string locations)
    {
        if (Book == null) return;
        Book.Locations = locations;
        // Сохраняем в базу данных
        await _databaseService.UpdateBookAsync(Book);
    }

    public async Task SaveProgressAsync(double progress, string? cfi, string? chapter, int currentPage, int totalPages)
    {
        if (Book == null) return;

        // Важно: если CFI пустой, не перезаписываем старый прогресс (защита от багов JS)
        if (string.IsNullOrEmpty(cfi) && progress <= 0) return;

        Book.ReadingProgress = progress;
        Book.LastCfi = cfi;
        Book.LastChapter = chapter;
        Book.CurrentPage = currentPage;
        Book.TotalPages = totalPages;
        Book.LastRead = DateTime.UtcNow;

        // Сохраняем в базу данных
        await _databaseService.UpdateBookAsync(Book);

        await _databaseService.SaveProgressAsync(new ReadingProgress
        {
            BookId = Book.Id,
            Cfi = cfi,
            Progress = progress,
            CurrentPage = currentPage,
            ChapterTitle = chapter
        });
    }

    public string GetBookFilePath()
    {
        return Book?.FilePath ?? string.Empty;
    }

    public string GetBookFormat()
    {
        return Book?.Format ?? "epub";
    }

    public string? GetLastCfi()
    {
        return Book?.LastCfi;
    }

    public string? GetLocations()
    {
        return Book?.Locations;
    }

    private static string EscapeJs(string value)
    {
        return value.Replace("\\", "\\\\").Replace("'", "\\'").Replace("\n", "\\n").Replace("\r", "\\r");
    }
}