using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.UI.Text;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Imaging;
using Windows.Media.Core;
using Windows.Media.Playback;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using WinRT.Interop;
using YMhut.Box.Core.App;
using YMhut.Box.Core.Logging;
using YMhut.Box.Core.Media;
using YMhut.Box.Core.Tools;
using YMhut.Box.WinUI.Services;
using YMhut.Box.WinUI.ViewModels.Tools;

namespace YMhut.Box.WinUI.Views.Tools;

public class RandomCinemaPage : ToolPageBase
{
    private readonly Action? _goBack;
    private readonly AppPaths _appPaths = AppServices.GetRequiredService<AppPaths>();
    private readonly IRemoteMediaCatalogService _catalogService = AppServices.GetRequiredService<IRemoteMediaCatalogService>();
    private readonly IRemoteMediaResolver _mediaResolver = AppServices.GetRequiredService<IRemoteMediaResolver>();
    private readonly AdaptiveToolViewModel _viewModel;
    private readonly Grid _root = new();
    private readonly StackPanel _contentHost = new() { Spacing = 16 };
    private readonly Grid _fullscreenOverlay = new() { Visibility = Visibility.Collapsed };
    private readonly Grid _fullscreenStage = new();
    private readonly TextBlock _statusText = ModernUi.Text(AppLocalizer.T("正在读取远程媒体配置...", "Loading remote media configuration..."), 14, foreground: ModernUi.TextSecondary);
    private readonly ProgressRing _progress = new()
    {
        Width = 24,
        Height = 24,
        IsActive = true,
        Visibility = Visibility.Visible
    };

    private RemoteMediaCatalog? _catalog;
    private byte[]? _currentMediaBytes;
    private Uri? _currentMediaUri;
    private string? _currentMediaCachePath;
    private InMemoryRandomAccessStream? _currentImageStream;
    private string _currentFileName = "media";
    private string _currentExtension = ".bin";
    private RemoteMediaCategory? _activeCategory;
    private RemoteMediaSource? _activeSource;
    private UIElement? _activeMediaView;
    private Panel? _activeMediaHost;
    private bool _inlineFullscreen;

    public RandomCinemaPage(IToolModule module, AdaptiveToolViewModel viewModel, Action? goBack = null)
    {
        _goBack = goBack;
        _viewModel = viewModel;
        Background = ModernUi.AppBackground;
        BindModule(module);
        Content = BuildContent(module);
        Loaded += async (_, _) => await LoadRemoteConfigAsync();
        Unloaded += (_, _) => DisposeCurrentImageStream();
    }

    private UIElement BuildContent(IToolModule module)
    {
        _root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        _root.RowDefinitions.Add(new RowDefinition());

        var header = BuildHeader(module);
        Grid.SetRow(header, 0);
        _root.Children.Add(header);

        var bodyStack = new StackPanel
        {
            Spacing = 16,
            HorizontalAlignment = HorizontalAlignment.Stretch,
            Children = { _contentHost }
        };

        var body = new ScrollViewer
        {
            Margin = new Thickness(32, 0, 32, 32),
            Padding = new Thickness(0, 0, 8, 0),
            VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
            HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
            Content = bodyStack
        };
        body.SizeChanged += (_, e) => bodyStack.Width = Math.Max(280, e.NewSize.Width - 16);
        Grid.SetRow(body, 1);
        _root.Children.Add(body);

        BuildFullscreenOverlay();
        Grid.SetRowSpan(_fullscreenOverlay, 2);
        _root.Children.Add(_fullscreenOverlay);
        return _root;
    }

    private void BuildFullscreenOverlay()
    {
        var exit = ModernUi.PillButton(AppLocalizer.T("退出全屏", "Exit fullscreen"), "\uE73F", ExitInlineFullscreen, primary: true);
        var title = ModernUi.Text(AppLocalizer.T("媒体预览", "Media preview"), 18, FontWeights.SemiBold, ModernUi.Brush("#FFFFFFFF"), maxLines: 1);
        var topBar = new Grid
        {
            Padding = new Thickness(22, 18, 22, 12),
            Background = ModernUi.Brush("#DD111111"),
            ColumnDefinitions =
            {
                new ColumnDefinition(),
                new ColumnDefinition { Width = GridLength.Auto }
            },
            Children =
            {
                title,
                WithColumn(exit, 1)
            }
        };

        _fullscreenStage.Background = ModernUi.Brush("#FF050505");
        _fullscreenStage.Padding = new Thickness(24);
        _fullscreenOverlay.Background = ModernUi.Brush("#F2050505");
        _fullscreenOverlay.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        _fullscreenOverlay.RowDefinitions.Add(new RowDefinition());
        _fullscreenOverlay.Children.Add(topBar);
        Grid.SetRow(_fullscreenStage, 1);
        _fullscreenOverlay.Children.Add(_fullscreenStage);
    }

    private Border BuildHeader(IToolModule module)
    {
        var back = ModernUi.IconButton("\uE72B", AppLocalizer.T("返回工具箱", "Back to toolbox"), () => _goBack?.Invoke());
        var refresh = ModernUi.PillButton(AppLocalizer.T("重新加载配置", "Reload sources"), "\uE895", async () => await LoadRemoteConfigAsync(forceRefresh: true), primary: true);

        var grid = new Grid { ColumnSpacing = 14 };
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        grid.ColumnDefinitions.Add(new ColumnDefinition());
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        grid.Children.Add(back);
        var icon = ModernUi.IconTile(module.Metadata.IconGlyph, 48, ModernUi.AccentSoft, ModernUi.Accent, 21);
        Grid.SetColumn(icon, 1);
        grid.Children.Add(icon);

        var title = new StackPanel
        {
            Spacing = 4,
            VerticalAlignment = VerticalAlignment.Center,
            Children =
            {
                ModernUi.Text(ToolText.Name(module), 24, FontWeights.SemiBold, maxLines: 1),
                ModernUi.Text(AppLocalizer.T("先选择随机图片或随机视频，再进入远程源加载媒体。", "Choose Random Images or Random Videos, then select a remote source."), 14, foreground: ModernUi.TextSecondary, maxLines: 2),
                _statusText
            }
        };
        Grid.SetColumn(title, 2);
        grid.Children.Add(title);

        var actions = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            Spacing = 10,
            VerticalAlignment = VerticalAlignment.Center,
            Children = { _progress, refresh }
        };
        Grid.SetColumn(actions, 3);
        grid.Children.Add(actions);
        return ModernUi.Card(grid, new Thickness(18), margin: new Thickness(32, 28, 32, 12), radius: 8);
    }

    private async Task LoadRemoteConfigAsync(bool forceRefresh = false)
    {
        _viewModel.IsBusy = true;
        _progress.IsActive = true;
        _progress.Visibility = Visibility.Visible;
        _contentHost.Children.Clear();
        _contentHost.Children.Add(ModernUi.Text(AppLocalizer.T("正在加载媒体源配置...", "Loading media source configuration..."), 14, foreground: ModernUi.TextSecondary));

        try
        {
            ExitInlineFullscreen();
            var result = await _catalogService.LoadAsync(forceRefresh);
            _catalog = result.Catalog;
            if (_catalog.Categories.Count == 0)
            {
                throw new InvalidOperationException(AppLocalizer.T("远程媒体配置为空。", "Remote media configuration is empty."));
            }

            _statusText.Text = AppLocalizer.T($"配置已重新加载 · {DateTime.Now:HH:mm:ss}", $"Configuration reloaded · {DateTime.Now:HH:mm:ss}");
            var source = result.Source == RemoteMediaCatalogLoadSource.Cache
                ? AppLocalizer.T("本地快照", "local snapshot")
                : AppLocalizer.T("远程配置", "remote configuration");
            _statusText.Text = AppLocalizer.T($"配置已同步 · {source} · {DateTime.Now:HH:mm:ss}", $"Configuration synced · {source} · {DateTime.Now:HH:mm:ss}");
            RenderChoiceCards();
            ToastService.Show(AppLocalizer.T("随机放映室配置已重新加载", "Random Cinema sources reloaded"), ToastKind.Success);
        }
        catch (Exception exception)
        {
            _statusText.Text = AppLocalizer.T("读取远程媒体配置失败。", "Failed to load remote media configuration.");
            _contentHost.Children.Clear();
            _contentHost.Children.Add(ModernUi.Card(new StackPanel
            {
                Spacing = 12,
                Children =
                {
                    ModernUi.Text(AppLocalizer.T("配置读取失败", "Configuration failed"), 18, FontWeights.SemiBold, ModernUi.Danger),
                    ModernUi.Text(FriendlyError(exception.Message), 13, foreground: ModernUi.TextSecondary),
                    ModernUi.PillButton(AppLocalizer.T("重试", "Retry"), "\uE895", async () => await LoadRemoteConfigAsync(), primary: true)
                }
            }, new Thickness(18), radius: 8));
            ToastService.Show(AppLocalizer.T("随机放映室配置读取失败", "Random Cinema configuration failed"), ToastKind.Error);
        }
        finally
        {
            _viewModel.IsBusy = false;
            _progress.IsActive = false;
            _progress.Visibility = Visibility.Collapsed;
        }
    }

    private void RenderChoiceCards()
    {
        _contentHost.Children.Clear();
        var categories = _catalog?.EnabledCategories.ToList() ?? [];
        if (categories.Count == 0)
        {
            _contentHost.Children.Add(BuildEmptyState(
                AppLocalizer.T("没有启用的媒体分类", "No enabled media categories"),
                AppLocalizer.T("远程配置已读取，但没有可展示的分类。请刷新配置或稍后重试。", "The remote configuration loaded, but no categories are enabled. Reload sources or try again later.")));
            return;
        }

        var grid = new VariableSizedWrapGrid
        {
            Orientation = Orientation.Horizontal,
            ItemWidth = 328,
            ItemHeight = 206
        };
        foreach (var category in categories.OrderBy(CategorySortKey).ThenBy(category => category.Id, StringComparer.OrdinalIgnoreCase))
        {
            grid.Children.Add(BuildChoiceCard(category));
        }

        _contentHost.Children.Add(grid);
    }

    private Button BuildChoiceCard(RemoteMediaCategory category)
    {
        var total = category.Subcategories.Count;
        var available = category.Subcategories.Count(source => source.IsAvailable);
        var enabled = total > 0;
        var top = new Grid { ColumnSpacing = 12 };
        top.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        top.ColumnDefinitions.Add(new ColumnDefinition());
        top.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        top.Children.Add(ModernUi.IconTile(CategoryGlyph(category), 46, ModernUi.AccentSoft, ModernUi.Accent, 20));
        top.Children.Add(WithColumn(ModernUi.SmallBadge(KindLabel(category), ModernUi.Accent, ModernUi.AccentSoft), 2));

        var button = new Button
        {
            Padding = new Thickness(18),
            CornerRadius = new CornerRadius(8),
            Background = ModernUi.Surface,
            BorderBrush = ModernUi.Stroke,
            BorderThickness = new Thickness(1),
            HorizontalContentAlignment = HorizontalAlignment.Stretch,
            VerticalContentAlignment = VerticalAlignment.Stretch,
            IsEnabled = enabled,
            Opacity = enabled ? 1 : 0.58,
            Content = new StackPanel
            {
                Spacing = 10,
                Children =
                {
                    top,
                    ModernUi.Text(DisplayCategoryName(category), 20, FontWeights.SemiBold, maxLines: 1),
                    ModernUi.Text(CategoryDescription(category), 13, foreground: ModernUi.TextSecondary, maxLines: 2),
                    new StackPanel
                    {
                        Orientation = Orientation.Horizontal,
                        Spacing = 8,
                        Children =
                        {
                            ModernUi.SmallBadge(AppLocalizer.T($"{available}/{total} 可用", $"{available}/{total} available"), enabled ? ModernUi.Success : ModernUi.TextSecondary, ModernUi.SurfaceAlt),
                            ModernUi.SmallBadge(PreviewVisibilityLabel(category), ModernUi.TextSecondary, ModernUi.SurfaceAlt),
                            ModernUi.SmallBadge(AppLocalizer.T($"{category.Layout.Columns} 列", $"{category.Layout.Columns} columns"), ModernUi.TextSecondary, ModernUi.SurfaceAlt)
                        }
                    }
                }
            }
        };
        if (enabled)
        {
            button.Click += (_, _) => RenderSourceCards(category);
        }

        return button;
    }

    private void RenderSourceCards(RemoteMediaCategory category)
    {
        _activeCategory = category;
        _contentHost.Children.Clear();
        _contentHost.Children.Add(BuildBreadcrumb(DisplayCategoryName(category), RenderChoiceCards));

        if (category.Subcategories.Count == 0)
        {
            _contentHost.Children.Add(BuildEmptyState(
                AppLocalizer.T("暂无资源源", "No media sources"),
                AppLocalizer.T("这个分类在远程配置中暂时没有子资源。", "This category does not currently contain any remote sources.")));
            return;
        }

        var wrap = new VariableSizedWrapGrid
        {
            Orientation = Orientation.Horizontal,
            ItemWidth = SourceCardWidth(category),
            ItemHeight = SourceCardHeight(category)
        };
        foreach (var source in category.Subcategories)
        {
            wrap.Children.Add(BuildSourceCard(category, source));
        }

        _contentHost.Children.Add(wrap);
    }

    private UIElement BuildBreadcrumb(string title, Action back)
    {
        var row = new Grid { ColumnSpacing = 10, Margin = new Thickness(0, 2, 0, 2) };
        row.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        row.ColumnDefinitions.Add(new ColumnDefinition());
        row.Children.Add(ModernUi.IconButton("\uE72B", AppLocalizer.T("返回上一级", "Back"), back));
        row.Children.Add(WithColumn(ModernUi.Text(title, 22, FontWeights.SemiBold, maxLines: 1), 1));
        return row;
    }

    private Button BuildSourceCard(RemoteMediaCategory category, RemoteMediaSource source)
    {
        var showPreview = category.Layout.ShowPreview;
        var available = source.IsAvailable;
        var content = new StackPanel
        {
            Spacing = 10,
            HorizontalAlignment = HorizontalAlignment.Stretch
        };

        if (showPreview)
        {
            var previewGrid = new Grid
            {
                Height = 138,
                Background = ModernUi.SurfaceAlt
            };
            previewGrid.Children.Add(new Image
            {
                Stretch = Stretch.UniformToFill,
                Source = Bitmap(source.ThumbnailUrl),
                HorizontalAlignment = HorizontalAlignment.Stretch,
                VerticalAlignment = VerticalAlignment.Stretch
            });
            var statusBadge = SourceStatusBadge(source);
            statusBadge.HorizontalAlignment = HorizontalAlignment.Right;
            statusBadge.VerticalAlignment = VerticalAlignment.Top;
            statusBadge.Margin = new Thickness(8);
            previewGrid.Children.Add(statusBadge);
            content.Children.Add(new Border
            {
                Height = 138,
                CornerRadius = new CornerRadius(8),
                Background = ModernUi.SurfaceAlt,
                Child = previewGrid
            });
        }
        else
        {
            var header = new Grid { ColumnSpacing = 10 };
            header.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
            header.ColumnDefinitions.Add(new ColumnDefinition());
            header.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
            header.Children.Add(ModernUi.IconTile(CategoryGlyph(category), 40, ModernUi.SurfaceAlt, ModernUi.Accent, 18));
            header.Children.Add(WithColumn(SourceStatusBadge(source), 2));
            content.Children.Add(header);
        }

        var name = DisplaySourceName(source);
        content.Children.Add(ModernUi.Text(name, 17, FontWeights.SemiBold, maxLines: 1));
        content.Children.Add(ModernUi.Text(DisplayDescription(source), 13, foreground: ModernUi.TextSecondary, maxLines: showPreview ? 2 : 3));
        content.Children.Add(BadgeRows(
            ModernUi.SmallBadge(FormatLabel(source), ModernUi.TextSecondary, ModernUi.SurfaceAlt),
            ModernUi.SmallBadge(IntervalLabel(source), ModernUi.TextSecondary, ModernUi.SurfaceAlt),
            ModernUi.SmallBadge(DownloadLabel(source), source.Downloadable ? ModernUi.Success : ModernUi.TextSecondary, ModernUi.SurfaceAlt)));

        var button = new Button
        {
            Padding = new Thickness(14),
            CornerRadius = new CornerRadius(8),
            Background = ModernUi.Surface,
            BorderBrush = ModernUi.Stroke,
            BorderThickness = new Thickness(1),
            HorizontalContentAlignment = HorizontalAlignment.Stretch,
            VerticalContentAlignment = VerticalAlignment.Stretch,
            IsEnabled = available,
            Opacity = available ? 1 : 0.58,
            Content = content
        };
        ToolTipService.SetToolTip(button, $"{name}\n{DisplayDescription(source)}");
        if (available)
        {
            button.Click += async (_, _) => await RenderMediaPageAsync(category, source);
        }

        return button;
    }

    private UIElement BuildEmptyState(string title, string description)
    {
        return ModernUi.Card(new StackPanel
        {
            Spacing = 10,
            HorizontalAlignment = HorizontalAlignment.Center,
            Children =
            {
                ModernUi.IconTile("\uE946", 48, ModernUi.SurfaceAlt, ModernUi.TextSecondary, 20),
                ModernUi.Text(title, 18, FontWeights.SemiBold, maxLines: 1),
                ModernUi.Text(description, 13, foreground: ModernUi.TextSecondary, maxLines: 2)
            }
        }, new Thickness(24), radius: 8, background: ModernUi.SurfaceAlt);
    }

    private static StackPanel BadgeRows(params UIElement[] badges)
    {
        var panel = new StackPanel { Spacing = 6 };
        for (var index = 0; index < badges.Length; index += 2)
        {
            var row = new StackPanel
            {
                Orientation = Orientation.Horizontal,
                Spacing = 8
            };
            row.Children.Add(badges[index]);
            if (index + 1 < badges.Length)
            {
                row.Children.Add(badges[index + 1]);
            }

            panel.Children.Add(row);
        }

        return panel;
    }

    private static int CategorySortKey(RemoteMediaCategory category)
    {
        return category.Kind switch
        {
            RemoteMediaKind.Image => 0,
            RemoteMediaKind.Video => 1,
            RemoteMediaKind.Audio => 2,
            _ => 3
        };
    }

    private static double SourceCardWidth(RemoteMediaCategory category)
    {
        return category.Layout.Columns switch
        {
            >= 4 => 250,
            3 => 292,
            2 => 346,
            _ => 430
        };
    }

    private static double SourceCardHeight(RemoteMediaCategory category)
        => category.Layout.ShowPreview ? 312 : 230;

    private static string CategoryGlyph(RemoteMediaCategory category)
    {
        if (!string.IsNullOrWhiteSpace(category.Icon) && category.Icon.Length <= 3)
        {
            return category.Icon;
        }

        return IsVideoCategory(category)
            ? "\uE714"
            : IsAudioCategory(category)
                ? "\uE8D6"
                : "\uEB9F";
    }

    private static string KindLabel(RemoteMediaCategory category)
    {
        return IsVideoCategory(category)
            ? AppLocalizer.T("视频", "Video")
            : IsAudioCategory(category)
                ? AppLocalizer.T("音频", "Audio")
                : AppLocalizer.T("图片", "Image");
    }

    private static string CategoryDescription(RemoteMediaCategory category)
    {
        var sourceCount = AppLocalizer.T($"{category.Subcategories.Count} 个远程源", $"{category.Subcategories.Count} remote sources");
        var playback = category.Layout.AutoPlay
            ? AppLocalizer.T("自动播放", "autoplay")
            : AppLocalizer.T("手动播放", "manual play");
        return AppLocalizer.T(
            $"{sourceCount}，{PreviewVisibilityLabel(category)}，{playback}。",
            $"{sourceCount}, {PreviewVisibilityLabel(category).ToLowerInvariant()}, {playback}.");
    }

    private static string PreviewVisibilityLabel(RemoteMediaCategory category)
        => category.Layout.ShowPreview
            ? AppLocalizer.T("显示预览", "Preview on")
            : AppLocalizer.T("隐藏预览", "Preview off");

    private static Border SourceStatusBadge(RemoteMediaSource source)
        => ModernUi.SmallBadge(
            source.IsAvailable ? AppLocalizer.T("可用", "Ready") : AppLocalizer.T("地址无效", "Invalid URL"),
            source.IsAvailable ? ModernUi.Success : ModernUi.Danger,
            ModernUi.SurfaceAlt);

    private static string FormatLabel(RemoteMediaSource source)
    {
        var formats = source.SupportedFormats.Take(3).ToArray();
        return formats.Length == 0
            ? AppLocalizer.T("格式未知", "Unknown format")
            : string.Join(" / ", formats);
    }

    private static string IntervalLabel(RemoteMediaSource source)
        => AppLocalizer.T($"{source.RefreshInterval} 秒刷新", $"{source.RefreshInterval}s refresh");

    private static string DownloadLabel(RemoteMediaSource source)
        => source.Downloadable
            ? AppLocalizer.T("可另存", "Downloadable")
            : AppLocalizer.T("不可另存", "No save");

    private async Task RenderMediaPageAsync(RemoteMediaCategory category, RemoteMediaSource source)
    {
        _activeCategory = category;
        _activeSource = source;
        ExitInlineFullscreen();
        DisposeCurrentImageStream();
        _currentMediaBytes = null;
        _currentMediaUri = null;
        _currentMediaCachePath = null;
        _currentFileName = $"{source.Id}_{DateTime.Now:yyyyMMdd_HHmmss}";
        _currentExtension = "." + (source.SupportedFormats.FirstOrDefault() ?? (IsVideoCategory(category) ? "mp4" : IsAudioCategory(category) ? "mp3" : "jpg")).TrimStart('.');

        _contentHost.Children.Clear();
        _contentHost.Children.Add(BuildBreadcrumb($"{DisplayCategoryName(category)} / {DisplaySourceName(source)}", () => RenderSourceCards(category)));

        var host = new Grid { MinHeight = 460 };
        var loadingText = ModernUi.Text(AppLocalizer.T("正在解析媒体地址...", "Resolving media address..."), 14, foreground: ModernUi.TextSecondary);
        var loadingProgress = new ProgressBar
        {
            Minimum = 0,
            Maximum = 100,
            Value = 4,
            Width = 280
        };
        var loading = new StackPanel
        {
            Spacing = 10,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Center,
            Children =
            {
                new ProgressRing { Width = 42, Height = 42, IsActive = true },
                loadingText,
                loadingProgress,
                ModernUi.Text(AppLocalizer.T("远程资源可能会重定向，加载时请稍候。", "Remote media may redirect; loading can take a moment."), 12, foreground: ModernUi.TextSecondary)
            }
        };
        host.Children.Add(loading);

        var actions = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 10 };
        actions.Children.Add(ModernUi.PillButton(AppLocalizer.T("重新加载", "Reload"), "\uE895", async () => await RenderMediaPageAsync(category, source), primary: true));
        actions.Children.Add(ModernUi.PillButton(AppLocalizer.T("全屏", "Fullscreen"), "\uE740", async () => await ShowFullscreenAsync()));
        var saveButton = ModernUi.PillButton(AppLocalizer.T("另存为", "Save as"), "\uE74E", async () => await SaveMediaAsync());
        saveButton.IsEnabled = source.Downloadable;
        saveButton.Opacity = source.Downloadable ? 1 : 0.5;
        actions.Children.Add(saveButton);

        _contentHost.Children.Add(ModernUi.Card(new StackPanel
        {
            Spacing = 14,
            Children =
            {
                host,
                actions
            }
        }, new Thickness(14), radius: 8));

        try
        {
            var progress = new Progress<double>(value =>
            {
                loadingProgress.Value = Math.Clamp(value, 0, 100);
                loadingText.Text = value >= 95
                    ? AppLocalizer.T("正在准备预览...", "Preparing preview...")
                    : AppLocalizer.T($"正在加载媒体... {value:0}%", $"Loading media... {value:0}%");
            });
            UIElement media = IsVideoCategory(category)
                ? await BuildVideoViewerAsync(category, source, progress)
                : IsAudioCategory(category)
                    ? await BuildAudioViewerAsync(category, source, progress)
                    : await BuildImageViewerAsync(source, progress);
            host.Children.Clear();
            host.Children.Add(media);
            _activeMediaHost = host;
            _activeMediaView = media;
            ToastService.Show(AppLocalizer.T("媒体已重新加载", "Media reloaded"), ToastKind.Success);
        }
        catch (Exception exception)
        {
            host.Children.Clear();
            host.Children.Add(new Border
            {
                Padding = new Thickness(16),
                CornerRadius = new CornerRadius(8),
                Background = ModernUi.SurfaceAlt,
                Child = new StackPanel
                {
                    Spacing = 8,
                    Children =
                    {
                        ModernUi.Text(AppLocalizer.T("媒体加载失败", "Media failed to load"), 18, FontWeights.SemiBold, ModernUi.Danger),
                        ModernUi.Text(FriendlyError(exception.Message), 13, foreground: ModernUi.TextSecondary)
                    }
                }
            });
            ToastService.Show(AppLocalizer.T("媒体加载失败", "Media failed to load"), ToastKind.Error);
        }
    }

    private async Task<Image> BuildImageViewerAsync(RemoteMediaSource source, IProgress<double>? progress)
    {
        var resolution = await _mediaResolver.ResolveMediaAsync(source.ApiUrl, RemoteMediaKind.Image, progress: progress);
        _currentMediaUri = resolution.Uri;
        _currentExtension = resolution.SuggestedExtension;
        progress?.Report(45);
        _currentMediaBytes = await _mediaResolver.DownloadBytesAsync(_currentMediaUri, progress);
        var bitmap = await BitmapFromBytesAsync(_currentMediaBytes);
        _currentImageStream = bitmap.Stream;
        progress?.Report(100);
        return new Image
        {
            MinHeight = 420,
            Stretch = Stretch.Uniform,
            Source = bitmap.Image,
            HorizontalAlignment = HorizontalAlignment.Stretch,
            VerticalAlignment = VerticalAlignment.Stretch
        };
    }

    private async Task<UIElement> BuildVideoViewerAsync(RemoteMediaCategory category, RemoteMediaSource source, IProgress<double>? progress)
    {
        var resolution = await _mediaResolver.ResolveMediaAsync(source.ApiUrl, RemoteMediaKind.Video, progress: progress);
        _currentMediaUri = resolution.Uri;
        _currentExtension = resolution.SuggestedExtension;
        progress?.Report(90);
        var media = new MediaPlayerElement
        {
            MinHeight = 420,
            AreTransportControlsEnabled = true,
            HorizontalAlignment = HorizontalAlignment.Stretch,
            VerticalAlignment = VerticalAlignment.Stretch
        };
        var player = CreateRemoteMediaPlayer(resolution);
        media.SetMediaPlayer(player);
        AttachPlaybackFallback(media, player, resolution, category, source);
        if (category.Layout.AutoPlay)
        {
            player.Play();
        }

        return WrapPlayableMedia(media, category, source);
    }

    private async Task<UIElement> BuildAudioViewerAsync(RemoteMediaCategory category, RemoteMediaSource source, IProgress<double>? progress)
    {
        var resolution = await _mediaResolver.ResolveMediaAsync(source.ApiUrl, RemoteMediaKind.Audio, progress: progress);
        _currentMediaUri = resolution.Uri;
        _currentExtension = resolution.SuggestedExtension;
        progress?.Report(90);
        var media = new MediaPlayerElement
        {
            MinHeight = 88,
            AreTransportControlsEnabled = true,
            HorizontalAlignment = HorizontalAlignment.Stretch,
            VerticalAlignment = VerticalAlignment.Center
        };
        var player = CreateRemoteMediaPlayer(resolution);
        media.SetMediaPlayer(player);
        AttachPlaybackFallback(media, player, resolution, category, source);
        if (category.Layout.AutoPlay)
        {
            player.Play();
        }

        return new StackPanel
        {
            Spacing = 16,
            HorizontalAlignment = HorizontalAlignment.Stretch,
            Children =
            {
                new Border
                {
                    Padding = new Thickness(18),
                    CornerRadius = new CornerRadius(8),
                    Background = ModernUi.SurfaceAlt,
                    Child = new StackPanel
                    {
                        Spacing = 12,
                        HorizontalAlignment = HorizontalAlignment.Center,
                        Children =
                        {
                            ModernUi.IconTile("\uE8D6", 72, ModernUi.AccentSoft, ModernUi.Accent, 30),
                            ModernUi.Text(DisplaySourceName(source), 18, FontWeights.SemiBold, maxLines: 1),
                            ModernUi.Text(AppLocalizer.T("音频已加载，使用下方控件播放、暂停和定位。", "Audio is loaded. Use the controls below to play, pause, and seek."), 13, foreground: ModernUi.TextSecondary, maxLines: 2)
                        }
                    }
                },
                WrapPlayableMedia(media, category, source)
            }
        };
    }

    private static MediaPlayer CreateRemoteMediaPlayer(RemoteMediaResolution resolution)
    {
        return new MediaPlayer
        {
            Source = MediaSource.CreateFromUri(resolution.Uri),
            Volume = 0.7
        };
    }

    private Grid WrapPlayableMedia(MediaPlayerElement media, RemoteMediaCategory category, RemoteMediaSource source)
    {
        var status = PlaybackStatusOverlay();
        var error = PlaybackErrorOverlay(category, source);
        media.Tag = new PlaybackOverlayState(status, error);
        return new Grid
        {
            Children =
            {
                media,
                status,
                error
            }
        };
    }

    private void AttachPlaybackFallback(
        MediaPlayerElement media,
        MediaPlayer player,
        RemoteMediaResolution resolution,
        RemoteMediaCategory category,
        RemoteMediaSource source)
    {
        var fallbackAttempted = false;
        player.MediaFailed += (failedPlayer, args) =>
        {
            DispatcherQueue.TryEnqueue(() =>
            {
                if (media.Tag is not PlaybackOverlayState overlays)
                {
                    return;
                }

                if (fallbackAttempted)
                {
                    ShowPlaybackFailure(overlays, args.ErrorMessage);
                    return;
                }

                fallbackAttempted = true;
                _ = SwitchToPlaybackCacheAsync(player, resolution, overlays, category, source);
            });
        };
    }

    private async Task SwitchToPlaybackCacheAsync(
        MediaPlayer player,
        RemoteMediaResolution resolution,
        PlaybackOverlayState overlays,
        RemoteMediaCategory category,
        RemoteMediaSource source)
    {
        try
        {
            SetPlaybackStatus(overlays, AppLocalizer.T("直连播放失败，正在缓存后重试...", "Direct playback failed. Caching media and retrying..."), true);
            var bytes = await _mediaResolver.DownloadBytesAsync(resolution.Uri);
            var path = await WritePlaybackCacheAsync(bytes, resolution.SuggestedExtension);
            _currentMediaCachePath = path;
            _currentMediaBytes = bytes;
            var file = await StorageFile.GetFileFromPathAsync(path);
            player.Source = MediaSource.CreateFromStorageFile(file);
            player.Volume = 0.7;
            SetPlaybackStatus(overlays, string.Empty, false);
            if (category.Layout.AutoPlay)
            {
                player.Play();
            }
        }
        catch (Exception exception)
        {
            ShowPlaybackFailure(overlays, $"{source.DisplayName}: {FriendlyError(exception.Message)}");
        }
    }

    private async Task<string> WritePlaybackCacheAsync(byte[] bytes, string extension)
    {
        var directory = Path.Combine(_appPaths.Cache, "remote-media", "playback");
        Directory.CreateDirectory(directory);
        var path = Path.Combine(directory, $"{_currentFileName}_{Guid.NewGuid():N}{NormalizeExtension(extension)}");
        await File.WriteAllBytesAsync(path, bytes);
        return path;
    }

    private static string NormalizeExtension(string extension)
    {
        var normalized = string.IsNullOrWhiteSpace(extension) ? ".bin" : extension.Trim();
        return normalized.StartsWith('.') ? normalized : "." + normalized;
    }

    private static Border PlaybackStatusOverlay()
    {
        return new Border
        {
            Visibility = Visibility.Collapsed,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Top,
            Margin = new Thickness(12),
            Padding = new Thickness(12, 7, 12, 8),
            CornerRadius = new CornerRadius(8),
            Background = ModernUi.Brush("#DD202020"),
            Child = ModernUi.Text(string.Empty, 13, FontWeights.SemiBold, ModernUi.Brush("#FFFFFFFF"), maxLines: 2)
        };
    }

    private Border PlaybackErrorOverlay(RemoteMediaCategory category, RemoteMediaSource source)
    {
        return new Border
        {
            Visibility = Visibility.Collapsed,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Center,
            MaxWidth = 460,
            Padding = new Thickness(18),
            CornerRadius = new CornerRadius(8),
            Background = ModernUi.Surface,
            BorderBrush = ModernUi.Stroke,
            BorderThickness = new Thickness(1),
            Child = new StackPanel
            {
                Spacing = 10,
                Children =
                {
                    ModernUi.Text(AppLocalizer.T("播放失败", "Playback failed"), 18, FontWeights.SemiBold, ModernUi.Danger),
                    ModernUi.Text(AppLocalizer.T("远程媒体暂时不可播放，可以重试或换一个媒体源。", "The remote media cannot be played right now. Retry or choose another source."), 13, foreground: ModernUi.TextSecondary, maxLines: 3),
                    ModernUi.PillButton(AppLocalizer.T("重试", "Retry"), "\uE895", async () => await RenderMediaPageAsync(category, source), primary: true)
                }
            }
        };
    }

    private static void SetPlaybackStatus(PlaybackOverlayState overlays, string text, bool visible)
    {
        if (overlays.Status.Child is TextBlock block)
        {
            block.Text = text;
        }

        overlays.Status.Visibility = visible ? Visibility.Visible : Visibility.Collapsed;
        overlays.Error.Visibility = Visibility.Collapsed;
    }

    private static void ShowPlaybackFailure(PlaybackOverlayState overlays, string message)
    {
        overlays.Status.Visibility = Visibility.Collapsed;
        if (overlays.Error.Child is StackPanel panel &&
            panel.Children.Count > 1 &&
            panel.Children[1] is TextBlock detail)
        {
            detail.Text = string.IsNullOrWhiteSpace(message)
                ? AppLocalizer.T("远程媒体暂时不可播放，可以重试或换一个媒体源。", "The remote media cannot be played right now. Retry or choose another source.")
                : FriendlyError(message);
        }

        overlays.Error.Visibility = Visibility.Visible;
    }

    private sealed record PlaybackOverlayState(Border Status, Border Error);

    private void EnterInlineFullscreen()
    {
        if (_activeMediaView is null || _activeMediaHost is null)
        {
            ToastService.Show(AppLocalizer.T("媒体尚未加载完成", "Media is not loaded yet"), ToastKind.Warning);
            return;
        }

        if (_inlineFullscreen)
        {
            return;
        }

        _activeMediaHost.Children.Remove(_activeMediaView);
        _fullscreenStage.Children.Clear();
        _fullscreenStage.Children.Add(_activeMediaView);
        _fullscreenOverlay.Visibility = Visibility.Visible;
        _inlineFullscreen = true;
    }

    private void ExitInlineFullscreen()
    {
        if (!_inlineFullscreen)
        {
            _fullscreenOverlay.Visibility = Visibility.Collapsed;
            return;
        }

        if (_activeMediaView is not null)
        {
            _fullscreenStage.Children.Remove(_activeMediaView);
            _activeMediaHost?.Children.Clear();
            _activeMediaHost?.Children.Add(_activeMediaView);
        }

        _fullscreenOverlay.Visibility = Visibility.Collapsed;
        _inlineFullscreen = false;
    }

    private async Task ShowFullscreenAsync()
    {
        EnterInlineFullscreen();
        await Task.CompletedTask;
    }

    private async Task SaveMediaAsync()
    {
        if (App.CurrentWindow is null || _activeSource is null)
        {
            return;
        }

        if (!_activeSource.Downloadable)
        {
            ToastService.Show(AppLocalizer.T("这个远程源不允许另存。", "This remote source does not allow saving."), ToastKind.Warning);
            return;
        }

        try
        {
            var picker = new FileSavePicker
            {
                SuggestedFileName = _currentFileName + _currentExtension
            };
            picker.FileTypeChoices.Add(AppLocalizer.T("媒体", "Media"), [_currentExtension]);
            InitializeWithWindow.Initialize(picker, WindowNative.GetWindowHandle(App.CurrentWindow));
            var target = await picker.PickSaveFileAsync();
            if (target is null)
            {
                return;
            }

            if (_currentMediaBytes is not null)
            {
                await FileIO.WriteBytesAsync(target, _currentMediaBytes);
            }
            else if (!string.IsNullOrWhiteSpace(_currentMediaCachePath) && File.Exists(_currentMediaCachePath))
            {
                var cachedFile = await StorageFile.GetFileFromPathAsync(_currentMediaCachePath);
                var buffer = await FileIO.ReadBufferAsync(cachedFile);
                await FileIO.WriteBufferAsync(target, buffer);
            }
            else if (_currentMediaUri is not null)
            {
                var bytes = await _mediaResolver.DownloadBytesAsync(_currentMediaUri);
                await FileIO.WriteBytesAsync(target, bytes);
            }
            else
            {
                ToastService.Show(AppLocalizer.T("媒体尚未加载完成", "Media is not loaded yet"), ToastKind.Warning);
                return;
            }

            ToastService.Show(AppLocalizer.T("媒体已保存", "Media saved"), ToastKind.Success);
        }
        catch (Exception exception)
        {
            ToastService.Show(AppLocalizer.T($"保存失败：{FriendlyError(exception.Message)}", $"Save failed: {FriendlyError(exception.Message)}"), ToastKind.Error, TimeSpan.FromSeconds(3));
        }
    }

    private static async Task<BitmapStreamResult> BitmapFromBytesAsync(byte[] bytes)
    {
        var stream = new InMemoryRandomAccessStream();
        await stream.WriteAsync(bytes.AsBuffer());
        stream.Seek(0);

        var bitmap = new BitmapImage();
        await bitmap.SetSourceAsync(stream);
        return new BitmapStreamResult(bitmap, stream);
    }

    private void DisposeCurrentImageStream()
    {
        try
        {
            _currentImageStream?.Dispose();
        }
        catch (Exception exception)
        {
            CrashLog.Write(exception);
        }
        finally
        {
            _currentImageStream = null;
        }
    }

    private sealed record BitmapStreamResult(BitmapImage Image, InMemoryRandomAccessStream Stream);

    private static bool IsVideoCategory(RemoteMediaCategory category)
    {
        return category.Kind == RemoteMediaKind.Video ||
            category.Id.Contains("video", StringComparison.OrdinalIgnoreCase) ||
            category.Subcategories.SelectMany(source => source.SupportedFormats).Any(IsVideoFormat);
    }

    private static bool IsAudioCategory(RemoteMediaCategory category)
    {
        return category.Kind == RemoteMediaKind.Audio ||
            category.Id.Contains("audio", StringComparison.OrdinalIgnoreCase) ||
            category.Subcategories.SelectMany(source => source.SupportedFormats).Any(IsAudioFormat);
    }

    private static bool IsImageCategory(RemoteMediaCategory category)
    {
        return !IsVideoCategory(category) && !IsAudioCategory(category);
    }

    private static bool IsVideoFormat(string format)
    {
        var ext = format.Trim().TrimStart('.').ToLowerInvariant();
        return ext is "mp4" or "mkv" or "webm" or "avi" or "mov" or "wmv" or "m4v";
    }

    private static bool IsAudioFormat(string format)
    {
        var ext = format.Trim().TrimStart('.').ToLowerInvariant();
        return ext is "mp3" or "wav" or "flac" or "aac" or "m4a" or "ogg" or "wma";
    }

    private static string DisplayCategoryName(RemoteMediaCategory category)
    {
        if (!string.IsNullOrWhiteSpace(category.DisplayName))
        {
            return category.DisplayName;
        }

        return IsVideoCategory(category)
            ? AppLocalizer.T("随机视频", "Random Videos")
            : IsAudioCategory(category)
                ? AppLocalizer.T("随机音频", "Random Audio")
                : AppLocalizer.T("随机图片", "Random Images");
    }

    private static string DisplaySourceName(RemoteMediaSource source)
    {
        if (!string.IsNullOrWhiteSpace(source.DisplayName))
        {
            return source.DisplayName;
        }

        if (!LooksBroken(source.Name))
        {
            return source.Name;
        }

        return source.Id switch
        {
            "xjj" => AppLocalizer.T("小姐姐", "Portrait"),
            "baisi" => AppLocalizer.T("白丝", "Light style"),
            "heisi" => AppLocalizer.T("黑丝", "Dark style"),
            "acg" => "ACG 4K",
            "miku" => AppLocalizer.T("初音未来", "Miku"),
            "wappller" => AppLocalizer.T("高清壁纸", "HD wallpaper"),
            "radom_xjj_leixing" => AppLocalizer.T("风格视频", "Style videos"),
            "radom_xjj_short" => AppLocalizer.T("短视频", "Short videos"),
            _ => source.Id
        };
    }

    private static string DisplayDescription(RemoteMediaSource source)
    {
        if (!string.IsNullOrWhiteSpace(source.DisplayDescription))
        {
            return source.DisplayDescription;
        }

        return LooksBroken(source.Description)
            ? AppLocalizer.T("远程随机媒体源，进入后可重新加载、预览和另存为。", "Remote random media source with reload, preview, and save support.")
            : source.Description;
    }

    private static BitmapImage Bitmap(string url)
    {
        return Uri.TryCreate(url, UriKind.Absolute, out var uri)
            ? new BitmapImage(uri)
            : new BitmapImage();
    }

    private static bool LooksBroken(string value)
    {
        return string.IsNullOrWhiteSpace(value)
            || value.Contains('�')
            || value.Contains("鐢", StringComparison.Ordinal)
            || value.Contains("闅", StringComparison.Ordinal)
            || value.Contains("鍥", StringComparison.Ordinal);
    }

    private static string FriendlyError(string message)
    {
        return AppLocalizer.SanitizeSensitiveText(message, 120);
    }

    private static T WithColumn<T>(T element, int column) where T : FrameworkElement
    {
        Grid.SetColumn(element, column);
        return element;
    }
}
