using HelloLib;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using WinIsland.Core;

namespace HelloPlugin;

public sealed class HelloPlugin : IslandPluginBase
{
    private HelloModel _model = null!;
    private IslandLiveContent? _content;
    private TextBlock? _compactText;
    private TextBlock? _expandedText;
    private bool _enabled;
    private int _ticks;

    protected override Task OnInitializeAsync()
    {
        _enabled = Settings.Get("enabled", true);
        _model = new HelloModel();
        Log.Info($"初始化开始:{_model.Describe()};插件目录 = {PluginDirectory};宿主版本 = {HostVersion}");

        Context.Island.AddSettingsPage(new SettingsPageDescriptor(
            "hello", Manifest.Name, Manifest.IconGlyph ?? "\uE8BD", BuildSettingsPage, 200));

        _content = BuildContent();
        if (_enabled)
        {
            SetContent(_content);
        }

        Context.CreateTimer(TimeSpan.FromSeconds(10), repeat: true, OnTick);
        Context.OnSettingsChanged("enabled", () =>
        {
            _enabled = Settings.Get("enabled", true);
            SetContent(_enabled ? _content : null);
        });
        Context.Register(new ActionDisposable(() => Log.Info("注册项已全部撤销(scope 清理完成)")));

        Log.Info("初始化完成,常驻内容已注册");
        return Task.CompletedTask;
    }

    protected override Task OnShutdownAsync()
    {
        Log.Info($"收到停用通知(累计心跳 {_ticks} 次)");
        return Task.CompletedTask;
    }

    private void OnTick()
    {
        if (Settings.Get("boom", false))
        {
            Settings.Set("boom", false);
            throw new InvalidOperationException("来自 Hello 插件的受管测试异常(定时器回调内抛出)");
        }

        _ticks++;
        Log.Info($"心跳 #{_ticks}");
        if (_compactText != null) _compactText.Text = $"运行中 · {_ticks} 次心跳";
        if (_expandedText != null) _expandedText.Text = $"已运行 {_ticks} 个心跳周期";
    }

    private IslandLiveContent BuildContent()
    {
        _compactText = NewText("运行中 · 0 次心跳");
        _expandedText = NewText("已运行 0 个心跳周期");

        var icon = new FontIcon
        {
            Glyph = Manifest.IconGlyph ?? "\uE8BD",
            FontSize = 16,
            Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 76, 194, 255)),
            VerticalAlignment = VerticalAlignment.Center,
        };

        var compact = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            Spacing = 10,
            Padding = new Thickness(16, 0, 16, 0),
            VerticalAlignment = VerticalAlignment.Center,
        };
        compact.Children.Add(icon);
        compact.Children.Add(_compactText);

        var expanded = new StackPanel
        {
            Spacing = 6,
            Padding = new Thickness(18, 14, 18, 14),
        };
        expanded.Children.Add(new TextBlock
        {
            Text = Manifest.Name,
            FontSize = 15,
            FontWeight = Microsoft.UI.Text.FontWeights.SemiBold,
            Foreground = new SolidColorBrush(Microsoft.UI.Colors.White),
        });
        expanded.Children.Add(new TextBlock
        {
            Text = $"示例插件 · {Manifest.Version} · 私有依赖 {_model.Describe()}",
            FontSize = 12,
            Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(200, 255, 255, 255)),
            TextWrapping = TextWrapping.Wrap,
        });
        expanded.Children.Add(_expandedText);
        expanded.Children.Add(new TextBlock
        {
            Text = "禁用后:内容清空、设置页移除、定时器停止、程序集尝试回收(见日志)",
            FontSize = 12,
            Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(160, 255, 255, 255)),
            TextWrapping = TextWrapping.Wrap,
        });

        return new IslandLiveContent
        {
            Priority = Settings.Get("priority", 10),
            OwnerLabel = Manifest.Name,
            OwnerGlyph = Manifest.IconGlyph,
            OwnerAccent = Windows.UI.Color.FromArgb(255, 76, 194, 255),
            CompactContent = compact,
            ExpandedContent = expanded,
            CompactSize = new Windows.Foundation.Size(240, 40),
            ExpandedSize = new Windows.Foundation.Size(400, 118),
        };
    }

    private UIElement BuildSettingsPage()
    {
        var panel = new StackPanel { Spacing = 10 };
        panel.Children.Add(new TextBlock
        {
            Text = Manifest.Name,
            Style = (Style)Application.Current.Resources["TitleTextBlockStyle"],
        });
        panel.Children.Add(new TextBlock
        {
            Text = $"Id:{Manifest.Id} · 版本 {Manifest.Version} · 目录:{PluginDirectory}",
            FontSize = 12,
            TextWrapping = TextWrapping.Wrap,
            Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(180, 255, 255, 255)),
        });

        var toggle = new ToggleSwitch
        {
            Header = "启用常驻内容",
            IsOn = Settings.Get("enabled", true),
        };
        toggle.Toggled += (_, _) => Settings.Set("enabled", toggle.IsOn);
        panel.Children.Add(new Border
        {
            Style = (Style)Application.Current.Resources["SettingsCardStyle"],
            Child = toggle,
        });

        var logButton = new Button { Content = "写一条插件日志" };
        logButton.Click += (_, _) => Log.Info($"来自设置页的日志(初始化后已心跳 {_ticks} 次)");
        panel.Children.Add(logButton);

        var boomButton = new Button { Content = "触发一次受管异常" };
        boomButton.Click += (_, _) =>
        {
            Settings.Set("boom", true);
            Log.Warn("已请求在下一次心跳时抛出受管异常。");
        };
        panel.Children.Add(boomButton);

        panel.Children.Add(new TextBlock
        {
            Text = "受管异常会在下一次心跳(最多 10 秒后)由宿主捕获,记入日志并计数;累计 5 次会自动停用插件。",
            FontSize = 12,
            TextWrapping = TextWrapping.Wrap,
            Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(160, 255, 255, 255)),
        });

        return panel;
    }

    private static TextBlock NewText(string text) => new()
    {
        Text = text,
        FontSize = 13,
        Foreground = new SolidColorBrush(Microsoft.UI.Colors.White),
        VerticalAlignment = VerticalAlignment.Center,
    };
}