using System.Diagnostics;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Platform;
using Avalonia.Platform.Storage;
using OF_DL.Gui.ViewModels;

namespace OF_DL.Gui.Views;

public partial class MainWindow : Window
{
    private const string DiscordInviteUrl = "https://discord.com/invite/6bUW8EJ53j";
    private const string DocumentationUrl = "https://docs.ofdl.tools/";
    private bool _hasInitialized;
    public MainWindowViewModel? ViewModel => DataContext as MainWindowViewModel;

    public MainWindow()
    {
        InitializeComponent();
        Icon = new WindowIcon(AssetLoader.Open(new Uri("avares://OF DL.Gui/Assets/icon.ico")));
        Opened += OnOpened;
    }

    private async void OnOpened(object? sender, EventArgs e)
    {
        if (_hasInitialized)
        {
            return;
        }

        _hasInitialized = true;
        if (DataContext is MainWindowViewModel vm)
        {
            await vm.InitializeAsync();
        }
    }

    private async void OnBrowseFfmpegPathClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is not MainWindowViewModel vm)
        {
            return;
        }

        TopLevel? topLevel = GetTopLevel(this);
        if (topLevel?.StorageProvider == null)
        {
            return;
        }

        IReadOnlyList<IStorageFile> selectedFiles = await topLevel.StorageProvider.OpenFilePickerAsync(
            new FilePickerOpenOptions { Title = "Select FFmpeg executable", AllowMultiple = false });

        IStorageFile? selectedFile = selectedFiles.FirstOrDefault();
        if (selectedFile == null)
        {
            return;
        }

        string? localPath = selectedFile.TryGetLocalPath();
        if (!string.IsNullOrWhiteSpace(localPath))
        {
            vm.SetFfmpegPath(localPath);
            return;
        }

        vm.SetFfmpegPath(selectedFile.Name);
    }

    private async void OnBrowseFfprobePathClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is not MainWindowViewModel vm)
        {
            return;
        }

        TopLevel? topLevel = GetTopLevel(this);
        if (topLevel?.StorageProvider == null)
        {
            return;
        }

        IReadOnlyList<IStorageFile> selectedFiles = await topLevel.StorageProvider.OpenFilePickerAsync(
            new FilePickerOpenOptions { Title = "Select FFprobe executable", AllowMultiple = false });

        IStorageFile? selectedFile = selectedFiles.FirstOrDefault();
        if (selectedFile == null)
        {
            return;
        }

        string? localPath = selectedFile.TryGetLocalPath();
        if (!string.IsNullOrWhiteSpace(localPath))
        {
            vm.SetFfprobePath(localPath);
            return;
        }

        vm.SetFfprobePath(selectedFile.Name);
    }

    private async void OnBrowseDownloadPathClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is not MainWindowViewModel vm)
        {
            return;
        }

        TopLevel? topLevel = GetTopLevel(this);
        if (topLevel?.StorageProvider == null)
        {
            return;
        }

        IReadOnlyList<IStorageFolder> selectedFolders = await topLevel.StorageProvider.OpenFolderPickerAsync(
            new FolderPickerOpenOptions { Title = "Select download folder", AllowMultiple = false });

        IStorageFolder? selectedFolder = selectedFolders.FirstOrDefault();
        if (selectedFolder == null)
        {
            return;
        }

        string? localPath = selectedFolder.TryGetLocalPath();
        if (!string.IsNullOrWhiteSpace(localPath))
        {
            vm.SetDownloadPath(localPath);
            return;
        }

        vm.SetDownloadPath(selectedFolder.Name);
    }

    private async void OnJoinDiscordClick(object? sender, RoutedEventArgs e) =>
        await OpenExternalUrlAsync(DiscordInviteUrl);

    private async void OnDocumentationClick(object? sender, RoutedEventArgs e) =>
        await OpenExternalUrlAsync(DocumentationUrl);

    private void OnFaqClick(object? sender, RoutedEventArgs e)
    {
        FaqWindow faqWindow = new();
        faqWindow.Show(this);
    }

    private void OnAboutClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is not MainWindowViewModel vm)
        {
            return;
        }

        AboutWindow aboutWindow = new(vm.ProgramVersion, vm.FfmpegVersion, vm.FfprobeVersion);
        aboutWindow.Show(this);
    }

    private async Task OpenExternalUrlAsync(string url)
    {
        try
        {
            ProcessStartInfo processStartInfo = new(url) { UseShellExecute = true };

            Process.Start(processStartInfo);
        }
        catch
        {
            await Task.CompletedTask;
        }
    }

    private void OnModalOverlayClicked(object? sender, PointerPressedEventArgs e)
    {
        // Only handle clicks on the overlay itself (the Grid background)
        if (DataContext is not MainWindowViewModel vm)
        {
            return;
        }

        // Execute cancel command on the modal
        vm.CreatorConfigEditor.ModalViewModel?.CancelCommand?.Execute(null);
    }

    private void OnModalContentClicked(object? sender, PointerPressedEventArgs e) =>
        // Stop the event from bubbling up to the overlay
        e.Handled = true;
}
