using Ink_Canvas.Helpers;
using Ink_Canvas.Properties;
using iNKORE.UI.WPF.Modern.Common.IconKeys;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
using FontIcon = iNKORE.UI.WPF.Modern.Controls.FontIcon;
using NavigationView = iNKORE.UI.WPF.Modern.Controls.NavigationView;
using NavigationViewItem = iNKORE.UI.WPF.Modern.Controls.NavigationViewItem;
using NavigationViewSelectionChangedEventArgs = iNKORE.UI.WPF.Modern.Controls.NavigationViewSelectionChangedEventArgs;
using Screen = System.Windows.Forms.Screen;

namespace Ink_Canvas.Windows
{
    /// <summary>
    /// 首次启动体验(OOBE)窗口。使用 iNKORE.UI.WPF.Modern 的 NavigationView 作为左侧导航,
    /// 引导用户依次完成欢迎页、8 个配置步骤与完成摘要页。
    /// </summary>
    public partial class OobeWindow : Window
    {
        private readonly Settings _settings;

        // 视图状态: -1 = 欢迎; 0..7 = 步骤; 8 = 完成
        private const int WelcomeIndex = -1;
        private const int FinishIndex = 8;
        private const int StepCount = 8;
        private const int MaxStepIndex = StepCount - 1;

        private int _currentStep = WelcomeIndex;
        private bool _suppressNavSelection;

        private FrameworkElement[] _stepPanels;
        private NavigationViewItem[] _navItems;

        private static readonly TimeSpan SlideDuration = TimeSpan.FromMilliseconds(280);
        private static readonly IEasingFunction SlideEase = new CubicEase { EasingMode = EasingMode.EaseOut };

        public OobeWindow(Settings settings)
        {
            if (settings == null) throw new ArgumentNullException(nameof(settings));

            _settings = settings;
            InitializeComponent();
            WindowBackdropHelper.Apply(this, _settings);

            Opacity = 0;

            _stepPanels = new FrameworkElement[]
            {
                StepTelemetryPanel,
                StepCanvasPanel,
                StepGesturesPanel,
                StepAppearancePanel,
                StepPPTPanel,
                StepAutomationPanel,
                StepLuckyRandomPanel,
                StepAdvancedPanel,
            };

            _navItems = new[]
            {
                NavItemTelemetry,
                NavItemCanvas,
                NavItemGestures,
                NavItemAppearance,
                NavItemPPT,
                NavItemAutomation,
                NavItemLuckyRandom,
                NavItemAdvanced,
            };

            InitializeFromSettings();
            UpdateView(animateDirection: 0, instant: true);
            SyncNavSelection();
        }

        #region Settings IO

        private void InitializeFromSettings()
        {
            try
            {
                if (_settings.Startup != null)
                {
                    ComboBoxTelemetryUploadLevel.SelectedIndex = (int)_settings.Startup.TelemetryUploadLevel;
                    CardFoldAtStartup.IsOn = _settings.Startup.IsFoldAtStartup;
                    CardAutoUpdate.IsOn = _settings.Startup.IsAutoUpdate;
                    int crashAction = _settings.Startup.CrashAction;
                    if (crashAction < 0 || crashAction > 2) crashAction = 0;
                    ComboBoxCrashAction.SelectedIndex = crashAction;
                    CheckBoxPrivacyAccepted.IsChecked = _settings.Startup.HasAcceptedTelemetryPrivacy;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.Canvas != null)
                {
                    CardShowCursor.IsOn = _settings.Canvas.IsShowCursor;
                    CardDisablePressure.IsOn = _settings.Canvas.DisablePressure;
                    CardHideStrokeWhenSelecting.IsOn = _settings.Canvas.HideStrokeWhenSelecting;
                    CardEnablePalmEraser.IsOn = _settings.Canvas.EnablePalmEraser;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.Gesture != null)
                {
                    CardTwoFingerZoom.IsOn = _settings.Gesture.IsEnableTwoFingerZoom;
                    CardTwoFingerTranslate.IsOn = _settings.Gesture.IsEnableTwoFingerTranslate;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.InkToShape != null)
                {
                    CardInkToShapeEnabled.IsOn = _settings.InkToShape.IsInkToShapeEnabled;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.Appearance != null)
                {
                    int themeIndex = _settings.Appearance.Theme;
                    if (themeIndex < 0 || themeIndex > 2) themeIndex = 2;
                    ComboBoxTheme.SelectedIndex = themeIndex;
                    SelectComboBoxItemByTag(ComboBoxWindowBackdrop, _settings.Appearance.WindowBackdrop);
                    CardEnableSplashScreen.IsOn = _settings.Appearance.EnableSplashScreen;
                    CardEnableTrayIcon.IsOn = _settings.Appearance.EnableTrayIcon;
                    CardShowQuickPanel.IsOn = _settings.Appearance.IsShowQuickPanel;
                    CardEnableHotkeysInMouseMode.IsOn = _settings.Appearance.EnableHotkeysInMouseMode;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.PowerPointSettings != null)
                {
                    CardPPTSupport.IsOn = _settings.PowerPointSettings.PowerPointSupport;
                    CardPPTAutoSaveStrokes.IsOn = _settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint;
                    CardPPTAutoSaveScreenshots.IsOn = _settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint;
                    CardPPTTimeCapsule.IsOn = _settings.PowerPointSettings.EnablePPTTimeCapsule;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.Automation != null)
                {
                    CardAutoFoldInPPTSlideShow.IsOn = _settings.Automation.IsAutoFoldInPPTSlideShow;
                    CardEnableAutoSaveStrokes.IsOn = _settings.Automation.IsEnableAutoSaveStrokes;
                    if (_settings.Automation.FloatingWindowInterceptor != null)
                    {
                        CardFloatingWindowInterceptor.IsOn = _settings.Automation.FloatingWindowInterceptor.IsEnabled;
                    }
                    CardAutoSaveStrokesAtClear.IsOn = _settings.Automation.IsAutoSaveScreenshotAtClear;
                    CardSaveScreenshotsInDateFolders.IsOn = _settings.Automation.IsSaveScreenshotsInDateFolders;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.RandSettings != null)
                {
                    CardShowRandomAndSingleDraw.IsOn = _settings.RandSettings.ShowRandomAndSingleDraw;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.Advanced != null)
                {
                    CardIsLogEnabled.IsOn = _settings.Advanced.IsLogEnabled;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }
        }

        private void ApplySelection()
        {
            try
            {
                if (_settings.Startup != null)
                {
                    int level = ComboBoxTelemetryUploadLevel.SelectedIndex;
                    if (level < 0) level = 0;
                    _settings.Startup.TelemetryUploadLevel = (TelemetryUploadLevel)level;
                    _settings.Startup.IsFoldAtStartup = CardFoldAtStartup.IsOn;
                    _settings.Startup.IsAutoUpdate = CardAutoUpdate.IsOn;
                    int crashAction = ComboBoxCrashAction.SelectedIndex;
                    if (crashAction < 0 || crashAction > 2) crashAction = 0;
                    _settings.Startup.CrashAction = crashAction;
                    _settings.Startup.HasAcceptedTelemetryPrivacy = CheckBoxPrivacyAccepted.IsChecked == true;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.Canvas != null)
                {
                    _settings.Canvas.IsShowCursor = CardShowCursor.IsOn;
                    _settings.Canvas.DisablePressure = CardDisablePressure.IsOn;
                    _settings.Canvas.HideStrokeWhenSelecting = CardHideStrokeWhenSelecting.IsOn;
                    _settings.Canvas.EnablePalmEraser = CardEnablePalmEraser.IsOn;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.Gesture != null)
                {
                    _settings.Gesture.IsEnableTwoFingerZoom = CardTwoFingerZoom.IsOn;
                    _settings.Gesture.IsEnableTwoFingerTranslate = CardTwoFingerTranslate.IsOn;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.InkToShape != null)
                {
                    _settings.InkToShape.IsInkToShapeEnabled = CardInkToShapeEnabled.IsOn;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.Appearance != null)
                {
                    int themeIndex = ComboBoxTheme.SelectedIndex;
                    if (themeIndex < 0) themeIndex = 2;
                    _settings.Appearance.Theme = themeIndex;
                    _settings.Appearance.WindowBackdrop = GetSelectedComboBoxTag(ComboBoxWindowBackdrop, "None");
                    _settings.Appearance.EnableSplashScreen = CardEnableSplashScreen.IsOn;
                    _settings.Appearance.EnableTrayIcon = CardEnableTrayIcon.IsOn;
                    _settings.Appearance.IsShowQuickPanel = CardShowQuickPanel.IsOn;
                    _settings.Appearance.EnableHotkeysInMouseMode = CardEnableHotkeysInMouseMode.IsOn;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.PowerPointSettings != null)
                {
                    _settings.PowerPointSettings.PowerPointSupport = CardPPTSupport.IsOn;
                    _settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint = CardPPTAutoSaveStrokes.IsOn;
                    _settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint = CardPPTAutoSaveScreenshots.IsOn;
                    _settings.PowerPointSettings.EnablePPTTimeCapsule = CardPPTTimeCapsule.IsOn;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.Automation != null)
                {
                    _settings.Automation.IsAutoFoldInPPTSlideShow = CardAutoFoldInPPTSlideShow.IsOn;
                    _settings.Automation.IsEnableAutoSaveStrokes = CardEnableAutoSaveStrokes.IsOn;
                    _settings.Automation.IsAutoSaveScreenshotAtClear = CardAutoSaveStrokesAtClear.IsOn;
                    _settings.Automation.IsSaveScreenshotsInDateFolders = CardSaveScreenshotsInDateFolders.IsOn;
                    if (_settings.Automation.FloatingWindowInterceptor != null)
                    {
                        _settings.Automation.FloatingWindowInterceptor.IsEnabled = CardFloatingWindowInterceptor.IsOn;
                    }
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.RandSettings != null)
                {
                    _settings.RandSettings.ShowRandomAndSingleDraw = CardShowRandomAndSingleDraw.IsOn;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

            try
            {
                if (_settings.Advanced != null)
                {
                    _settings.Advanced.IsLogEnabled = CardIsLogEnabled.IsOn;
                }
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }
        }

        private static void SelectComboBoxItemByTag(ComboBox comboBox, string tag)
        {
            if (comboBox == null) return;

            var selectedItem = comboBox.Items
                .OfType<ComboBoxItem>()
                .FirstOrDefault(item => string.Equals(item.Tag?.ToString(), tag, StringComparison.OrdinalIgnoreCase))
                ?? comboBox.Items.OfType<ComboBoxItem>().FirstOrDefault();

            comboBox.SelectedItem = selectedItem;
        }

        private static string GetSelectedComboBoxTag(ComboBox comboBox, string fallback)
        {
            return (comboBox?.SelectedItem as ComboBoxItem)?.Tag?.ToString() ?? fallback;
        }

        private void ComboBoxWindowBackdrop_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (ComboBoxWindowBackdrop == null) return;
            WindowBackdropHelper.Apply(this, GetSelectedComboBoxTag(ComboBoxWindowBackdrop, "None"));
        }

        #endregion

        #region Navigation

        private void BtnStartWelcome_Click(object sender, RoutedEventArgs e)
        {
            NavigateTo(0, direction: 1);
        }

        private void BtnUsePreset_Click(object sender, RoutedEventArgs e)
        {
            var presetWindow = new OobePresetWindow { Owner = this };
            bool? result = presetWindow.ShowDialog();
            if (result != true) return;

            switch (presetWindow.SelectedPreset)
            {
                case OobePresetWindow.PresetKind.Standard:
                    OobePresetWindow.ApplyStandard(_settings);
                    break;
                case OobePresetWindow.PresetKind.Lite:
                    OobePresetWindow.ApplyLite(_settings);
                    break;
                default:
                    return;
            }

            DialogResult = true;
            Close();
        }

        private void BtnConfirm_Click(object sender, RoutedEventArgs e)
        {
            if (_currentStep == FinishIndex)
            {
                ApplySelection();
                DialogResult = true;
                Close();
                return;
            }

            NavigateTo(_currentStep + 1, direction: 1);
        }

        private void BtnPreviousStep_Click(object sender, RoutedEventArgs e)
        {
            if (_currentStep <= WelcomeIndex) return;
            NavigateTo(_currentStep - 1, direction: -1);
        }

        private void NavView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
        {
            if (_suppressNavSelection) return;

            int target = ResolveTargetFromNavItem(args.SelectedItem as NavigationViewItem);
            if (target == _currentStep) return;

            int direction = target > _currentStep ? 1 : -1;
            NavigateTo(target, direction);
        }

        private int ResolveTargetFromNavItem(NavigationViewItem item)
        {
            if (item == null) return _currentStep;
            if (item == NavItemWelcome) return WelcomeIndex;
            if (item == NavItemFinish) return FinishIndex;
            for (int i = 0; i < _navItems.Length; i++)
            {
                if (_navItems[i] == item) return i;
            }
            return _currentStep;
        }

        private void NavigateTo(int target, int direction)
        {
            if (target < WelcomeIndex) target = WelcomeIndex;
            if (target > FinishIndex) target = FinishIndex;
            _currentStep = target;
            UpdateView(direction);
            SyncNavSelection();
        }

        private void SyncNavSelection()
        {
            _suppressNavSelection = true;
            try
            {
                if (_currentStep == WelcomeIndex)
                    NavView.SelectedItem = NavItemWelcome;
                else if (_currentStep == FinishIndex)
                    NavView.SelectedItem = NavItemFinish;
                else
                    NavView.SelectedItem = _navItems[_currentStep];
            }
            finally
            {
                _suppressNavSelection = false;
            }
        }

        private void CheckBoxPrivacyAccepted_Changed(object sender, RoutedEventArgs e)
        {
            UpdateConfirmEnabled();
        }

        private bool _privacyDialogShown;

        private void HyperlinkPrivacy_Click(object sender, RoutedEventArgs e)
        {
            e.Handled = true;
            if (_privacyDialogShown) return;
            _privacyDialogShown = true;
            try
            {
                var dialog = new PrivacyAgreementWindow { Owner = this };
                bool? result = dialog.ShowDialog();
                if (result == true && dialog.UserAccepted)
                {
                    CheckBoxPrivacyAccepted.IsChecked = true;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
            }
            finally
            {
                Dispatcher.BeginInvoke(new Action(() => _privacyDialogShown = false),
                    System.Windows.Threading.DispatcherPriority.Background);
            }
        }

        private void UpdateConfirmEnabled()
        {
            if (BtnConfirm == null) return;
            BtnConfirm.IsEnabled = true;
        }

        #endregion

        #region 高DPI/多屏自适应窗口控制

        private HwndSource _hwndSource;

        private void GetWorkAreaSize(out double workAreaWidthDip, out double workAreaHeightDip, out double screenLeftDip, out double screenTopDip)
        {
            var windowHandle = new WindowInteropHelper(this).Handle;
            var currentScreen = Screen.FromHandle(windowHandle);
            var workingArea = currentScreen.WorkingArea;
            var screenBounds = currentScreen.Bounds;

            var source = PresentationSource.FromVisual(this);
            double dpiScaleX = 1.0;
            double dpiScaleY = 1.0;

            if (source?.CompositionTarget != null)
            {
                dpiScaleX = source.CompositionTarget.TransformToDevice.M11;
                dpiScaleY = source.CompositionTarget.TransformToDevice.M22;
            }

            workAreaWidthDip = workingArea.Width / dpiScaleX;
            workAreaHeightDip = workingArea.Height / dpiScaleY;
            screenLeftDip = screenBounds.Left / dpiScaleX;
            screenTopDip = screenBounds.Top / dpiScaleY;
        }

        private void SetMaxSizeAndCenter()
        {
            if (!this.IsLoaded) return;

            GetWorkAreaSize(out double workAreaWidthDip, out double workAreaHeightDip, out double screenLeftDip, out double screenTopDip);

            this.MaxWidth = workAreaWidthDip;
            this.MaxHeight = workAreaHeightDip;

            this.Left = screenLeftDip + (workAreaWidthDip - this.ActualWidth) / 2;
            this.Top = screenTopDip + (workAreaHeightDip - this.ActualHeight) / 2;
        }

        private void RegisterDpiChangedListener()
        {
            _hwndSource = PresentationSource.FromVisual(this) as HwndSource;
            _hwndSource?.AddHook(DpiChangedWndProc);
        }

        private void UnregisterDpiChangedListener()
        {
            _hwndSource?.RemoveHook(DpiChangedWndProc);
            _hwndSource = null;
        }

        private IntPtr DpiChangedWndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            const int WM_DPICHANGED = 0x02E0;
            if (msg == WM_DPICHANGED)
            {
                SetMaxSizeAndCenter();
                handled = true;
            }
            return IntPtr.Zero;
        }

        #endregion

        private void OobeWindow_OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            UnregisterDpiChangedListener();
        }

        private void OobeWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            try
            {
                var animation = new DoubleAnimation
                {
                    From = 0,
                    To = 1,
                    Duration = TimeSpan.FromMilliseconds(260),
                    EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
                };
                BeginAnimation(OpacityProperty, animation);
            }
            catch
            {
                Opacity = 1;
            }

            SetMaxSizeAndCenter();
            RegisterDpiChangedListener();
        }

        private void UpdateView(int animateDirection, bool instant = false)
        {
            try
            {
                bool isWelcome = _currentStep == WelcomeIndex;
                bool isFinish = _currentStep == FinishIndex;
                bool isStep = !isWelcome && !isFinish;

                WelcomePanel.Visibility = isWelcome ? Visibility.Visible : Visibility.Collapsed;
                StepScrollViewer.Visibility = isStep ? Visibility.Visible : Visibility.Collapsed;
                FinishPanel.Visibility = isFinish ? Visibility.Visible : Visibility.Collapsed;

                if (isStep)
                {
                    for (int i = 0; i < _stepPanels.Length; i++)
                    {
                        _stepPanels[i].Visibility = i == _currentStep ? Visibility.Visible : Visibility.Collapsed;
                    }

                    StepIndicatorText.Text = string.Format(Properties.OobeStrings.Oobe_StepFormat, _currentStep + 1, StepCount);
                    ApplyStepMeta(_currentStep);

                    if (StepScrollViewer != null) StepScrollViewer.ScrollToTop();
                }

                if (isFinish)
                {
                    BuildFinishSummary();
                }

                // 底部进度: 欢迎=0, 各步骤按比例, 完成=100
                double progress;
                if (isWelcome) progress = 0;
                else if (isFinish) progress = 100;
                else progress = (_currentStep + 1) / (double)(StepCount + 1) * 100.0;

                AnimateProgress(progress, instant);

                // Footer 步骤计数
                if (isWelcome) FooterStepText.Text = string.Empty;
                else if (isFinish) FooterStepText.Text = string.Format(Properties.OobeStrings.Oobe_StepFinishFormat, StepCount, StepCount);
                else FooterStepText.Text = $"{_currentStep + 1} / {StepCount}";

                // 上一步按钮: 欢迎页隐藏
                BtnPreviousStep.Visibility = isWelcome ? Visibility.Collapsed : Visibility.Visible;

                // 主按钮: 欢迎页隐藏(由欢迎页自身的"开始"按钮负责)
                BtnConfirm.Visibility = isWelcome ? Visibility.Collapsed : Visibility.Visible;
                if (isFinish)
                {
                    BtnConfirmText.Text = Properties.OobeStrings.Oobe_SaveAndStart;
                    BtnConfirmIcon.Icon = SegoeFluentIcons.Accept;
                }
                else
                {
                    BtnConfirmText.Text = Properties.OobeStrings.Oobe_Next;
                    BtnConfirmIcon.Icon = SegoeFluentIcons.ChevronRight;
                }

                UpdateConfirmEnabled();

                if (!instant && animateDirection != 0)
                {
                    AnimateContentSlide(animateDirection);
                }
                else
                {
                    StepHostTransform.X = 0;
                    StepHost.Opacity = 1;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
            }
        }

        private void ApplyStepMeta(int step)
        {
            string title; string subtitle;
            switch (step)
            {
                case 0:
                    title = Properties.OobeStrings.Oobe_Step1Title;
                    subtitle = Properties.OobeStrings.Oobe_Step1Subtitle;
                    break;
                case 1:
                    title = Properties.OobeStrings.Oobe_Step2Title;
                    subtitle = Properties.OobeStrings.Oobe_Step2Subtitle;
                    break;
                case 2:
                    title = Properties.OobeStrings.Oobe_Step3Title;
                    subtitle = Properties.OobeStrings.Oobe_Step3Subtitle;
                    break;
                case 3:
                    title = ThemeStrings.Theme_GroupTitle;
                    subtitle = Properties.OobeStrings.Oobe_Step4Subtitle;
                    break;
                case 4:
                    title = Properties.OobeStrings.Oobe_Step5Title;
                    subtitle = Properties.OobeStrings.Oobe_Step5Subtitle;
                    break;
                case 5:
                    title = Properties.OobeStrings.Oobe_Step6Title;
                    subtitle = Properties.OobeStrings.Oobe_Step6Subtitle;
                    break;
                case 6:
                    title = RandomStrings.Random_Title;
                    subtitle = Properties.OobeStrings.Oobe_Step7Subtitle;
                    break;
                case 7:
                    title = Properties.OobeStrings.Oobe_Step8Title;
                    subtitle = Properties.OobeStrings.Oobe_Step8Subtitle;
                    break;
                default:
                    title = string.Empty; subtitle = string.Empty;
                    break;
            }

            StepTitleText.Text = title;
            StepSubtitleText.Text = subtitle;
        }

        private void BuildFinishSummary()
        {
            FinishSummaryHost.Children.Clear();

            string telemetryText;
            switch (ComboBoxTelemetryUploadLevel.SelectedIndex)
            {
                case 0: telemetryText = Properties.OobeStrings.Oobe_TelemetryNone; break;
                case 1: telemetryText = Properties.OobeStrings.Oobe_TelemetryBasic; break;
                default: telemetryText = Properties.OobeStrings.Oobe_TelemetryOptional; break;
            }

            string themeText;
            string backdropText = GetSelectedComboBoxContent(ComboBoxWindowBackdrop, ThemeStrings.Theme_WindowBackdrop_None);
            switch (ComboBoxTheme.SelectedIndex)
            {
                case 0: themeText = Properties.OobeStrings.Oobe_ThemeLight; break;
                case 1: themeText = FloatingBarStrings.OldUI_Dark; break;
                default: themeText = ThemeStrings.Theme_System; break;
            }

            AddSummaryRow(SegoeFluentIcons.Shield, Properties.OobeStrings.Oobe_SummaryTelemetryLevel, telemetryText);
            AddSummaryRow(SegoeFluentIcons.Sync, UpdateStrings.Header_AutoUpdate, BoolText(CardAutoUpdate.IsOn));
            AddSummaryRow(SegoeFluentIcons.Personalize, Properties.OobeStrings.Oobe_SummaryAppTheme, themeText);
            AddSummaryRow(SegoeFluentIcons.FullScreen, ThemeStrings.Theme_WindowBackdrop, backdropText);
            AddSummaryRow(SegoeFluentIcons.Slideshow, Properties.OobeStrings.Oobe_SummaryPPTLink, BoolText(CardPPTSupport.IsOn));
            AddSummaryRow(SegoeFluentIcons.TouchPointer, Properties.OobeStrings.Oobe_SummaryTwoFingerZoom,
                $"{BoolText(CardTwoFingerZoom.IsOn)} / {BoolText(CardTwoFingerTranslate.IsOn)}");
            AddSummaryRow(SegoeFluentIcons.Pin, Properties.OobeStrings.Oobe_SummaryTrayIcon, BoolText(CardEnableTrayIcon.IsOn));
            AddSummaryRow(SegoeFluentIcons.Document, Properties.OobeStrings.Oobe_SummaryLogEnabled, BoolText(CardIsLogEnabled.IsOn));
        }

        private static string BoolText(bool value) => value ? Properties.OobeStrings.Oobe_BoolEnabled : Properties.OobeStrings.Oobe_BoolDisabled;

        private static string GetSelectedComboBoxContent(ComboBox comboBox, string fallback)
        {
            return (comboBox?.SelectedItem as ComboBoxItem)?.Content?.ToString() ?? fallback;
        }

        private void AddSummaryRow(FontIconData icon, string label, string value)
        {
            var grid = new Grid { Margin = new Thickness(0, 2, 0, 2) };
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(28) });
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(180) });
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

            var fontIcon = new FontIcon { Icon = icon, FontSize = 16, Opacity = 0.85 };
            Grid.SetColumn(fontIcon, 0);
            grid.Children.Add(fontIcon);

            var labelBlock = new TextBlock
            {
                Text = label,
                Opacity = 0.85,
                VerticalAlignment = VerticalAlignment.Center
            };
            Grid.SetColumn(labelBlock, 1);
            grid.Children.Add(labelBlock);

            var valueBlock = new TextBlock
            {
                Text = value,
                FontWeight = FontWeights.SemiBold,
                TextWrapping = TextWrapping.Wrap,
                VerticalAlignment = VerticalAlignment.Center
            };
            Grid.SetColumn(valueBlock, 2);
            grid.Children.Add(valueBlock);

            FinishSummaryHost.Children.Add(grid);
        }

        private void AnimateProgress(double targetPercent, bool instant)
        {
            try
            {
                if (StepProgressBar == null) return;

                if (instant)
                {
                    StepProgressBar.BeginAnimation(System.Windows.Controls.Primitives.RangeBase.ValueProperty, null);
                    StepProgressBar.Value = targetPercent;
                    return;
                }

                var anim = new DoubleAnimation
                {
                    To = targetPercent,
                    Duration = TimeSpan.FromMilliseconds(320),
                    EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
                };
                StepProgressBar.BeginAnimation(System.Windows.Controls.Primitives.RangeBase.ValueProperty, anim);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
            }
        }

        private void AnimateContentSlide(int direction)
        {
            // direction: 1 = 前进 (新内容从右滑入), -1 = 后退 (从左滑入)
            double from = direction > 0 ? 36 : -36;

            StepHostTransform.X = from;
            StepHost.Opacity = 0;

            var slide = new DoubleAnimation
            {
                From = from,
                To = 0,
                Duration = SlideDuration,
                EasingFunction = SlideEase
            };
            var fade = new DoubleAnimation
            {
                From = 0,
                To = 1,
                Duration = SlideDuration,
                EasingFunction = SlideEase
            };

            StepHostTransform.BeginAnimation(TranslateTransform.XProperty, slide);
            StepHost.BeginAnimation(OpacityProperty, fade);
        }
    }
}
