using Ink_Canvas.Controls;
using Ink_Canvas.Helpers;
using Microsoft.Win32;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using SystemEvents = Microsoft.Win32.SystemEvents;

namespace Ink_Canvas.Windows
{
    /// <summary>
    /// PPT侧滑快捷面板
    /// </summary>
    public partial class PPTQuickPanel : UserControl
    {
        // Windows Core Audio API
        [ComImport]
        [Guid("5CDF2C82-841E-4546-9722-0CF74078229A")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IAudioEndpointVolume
        {
            int NotImpl1();
            int NotImpl2();
            int GetChannelCount(out int channelCount);
            int SetMasterVolumeLevel(float level, Guid eventContext);
            int SetMasterVolumeLevelScalar(float level, Guid eventContext);
            int GetMasterVolumeLevel(out float level);
            int GetMasterVolumeLevelScalar(out float level);
            int SetChannelVolumeLevel(uint channelNumber, float level, Guid eventContext);
            int SetChannelVolumeLevelScalar(uint channelNumber, float level, Guid eventContext);
            int GetChannelVolumeLevel(uint channelNumber, out float level);
            int GetChannelVolumeLevelScalar(uint channelNumber, out float level);
            int SetMute([MarshalAs(UnmanagedType.Bool)] bool mute, Guid eventContext);
            int GetMute(out bool mute);
        }

        [ComImport]
        [Guid("D666063F-1587-4E43-81F1-B948E807363F")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IMMDevice
        {
            int Activate(ref Guid iid, int clsCtx, IntPtr activationParams, [MarshalAs(UnmanagedType.IUnknown)] out object interfacePointer);
            int OpenPropertyStore(int stgmAccess, out IPropertyStore propertyStore);
            int GetId([MarshalAs(UnmanagedType.LPWStr)] out string id);
            int GetState(out int state);
        }

        [ComImport]
        [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IMMDeviceEnumerator
        {
            int NotImpl1();
            int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice device);
        }

        [ComImport]
        [Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IPropertyStore
        {
            int GetCount(out int propertyCount);
            int GetAt(int propertyIndex, out Guid propertyKey);
            int GetValue(ref Guid propertyKey, out object value);
            int SetValue(ref Guid propertyKey, ref object value);
            int Commit();
        }

        private static class MMDeviceEnumeratorFactory
        {
            [ComImport]
            [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
            private class MMDeviceEnumerator
            {
            }

            public static IMMDeviceEnumerator CreateInstance()
            {
                return new MMDeviceEnumerator() as IMMDeviceEnumerator;
            }
        }

        private const int DEVICE_STATE_ACTIVE = 1;
        private const int eRender = 0;
        private const int eConsole = 0;

        private IAudioEndpointVolume _audioEndpointVolume;
        private bool _isExpanded = false;
        private bool _isDragging = false;
        private Point _dragStartPoint;
        private double _collapsedOffset = 200; // 折叠时的偏移量（隐藏内容区域）
        private MainWindow _mainWindow;

        private Dictionary<FrameworkElement, int> _pptImages = new Dictionary<FrameworkElement, int>();

        private Dictionary<int, List<string>> _pptImagePaths = new Dictionary<int, List<string>>();

        public PPTQuickPanel()
        {
            InitializeComponent();
            InitializeAudio();
            ApplyTheme();

            // 监听主题变化
            SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged;

            Loaded += PPTQuickPanel_Loaded;
            Unloaded += PPTQuickPanel_Unloaded;
            IsVisibleChanged += PPTQuickPanel_IsVisibleChanged;

            MagnifierWindow.Closed2 += OnMagnifierClosed;
        }

        private void OnMagnifierClosed(object sender, EventArgs e)
        {
            Dispatcher.BeginInvoke(new Action(SyncMagnifierButtonState));
        }

        private void SyncMagnifierButtonState()
        {
            if (MagnifierToggleButton == null) return;
            MagnifierToggleButton.Content = MagnifierWindow.HasInstance ? Properties.PPTStrings.PPTQuickPanel_CloseMagnifier : Properties.PPTStrings.PPTQuickPanel_OpenMagnifier;
        }

        private void PPTQuickPanel_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (Visibility == Visibility.Visible)
            {
                ApplyTheme();
                SyncMagnifierButtonState();
            }
        }

        private void PPTQuickPanel_Loaded(object sender, RoutedEventArgs e)
        {
            // 初始状态为折叠
            PanelTransform.X = _collapsedOffset;
            UpdateArrowRotation();

            // 获取MainWindow引用
            _mainWindow = Application.Current.MainWindow as MainWindow;

            SubscribeToPPTEvents();
            SubscribeToInkCanvasChildrenChanges();
            Dispatcher.BeginInvoke(new Action(() =>
            {
                UpdateVolumeDisplay();
            }), DispatcherPriority.Loaded);
        }

        private void SubscribeToInkCanvasChildrenChanges()
        {
            try
            {
                if (_mainWindow == null) return;

                System.Windows.Controls.InkCanvas inkCanvas = null;
                var inkCanvasField = _mainWindow.GetType().GetField("inkCanvas",
                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                if (inkCanvasField != null)
                {
                    inkCanvas = inkCanvasField.GetValue(_mainWindow) as System.Windows.Controls.InkCanvas;
                }
                if (inkCanvas == null)
                {
                    var inkCanvasProperty = _mainWindow.GetType().GetProperty("inkCanvas",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                    inkCanvas = inkCanvasProperty?.GetValue(_mainWindow) as System.Windows.Controls.InkCanvas;
                }

                if (inkCanvas != null && inkCanvas.Children is INotifyCollectionChanged notifyCollection)
                {
                    notifyCollection.CollectionChanged += InkCanvasChildren_CollectionChanged;
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"订阅inkCanvas.Children变化事件失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void InkCanvasChildren_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            try
            {
                if (e.Action == NotifyCollectionChangedAction.Remove)
                {
                    foreach (var item in e.OldItems)
                    {
                        if (item is FrameworkElement fe && _pptImages.ContainsKey(fe))
                        {
                            RemoveImageFromPPT(fe);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"处理inkCanvas.Children变化失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void RemoveImageFromPPT(FrameworkElement element)
        {
            try
            {
                if (element == null) return;

                if (_pptImages.ContainsKey(element))
                {
                    int slideNumber = _pptImages[element];
                    _pptImages.Remove(element);

                    if (_pptImagePaths.ContainsKey(slideNumber))
                    {
                        string imagePath = element.Tag as string;
                        if (!string.IsNullOrEmpty(imagePath) && _pptImagePaths[slideNumber].Contains(imagePath))
                        {
                            _pptImagePaths[slideNumber].Remove(imagePath);

                            if (_pptImagePaths[slideNumber].Count == 0)
                            {
                                _pptImagePaths.Remove(slideNumber);
                                DeletePPTImagePathsFile(slideNumber);
                            }
                            else
                            {
                                SavePPTImagePaths(slideNumber);
                            }

                            LogHelper.WriteLogToFile($"已从PPT页面{slideNumber}移除图片: {imagePath}");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"从PPT关联数据中移除图片失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void DeletePPTImagePathsFile(int slideIndex)
        {
            try
            {
                if (slideIndex <= 0) return;

                var folderPath = GetPresentationFolderPath();
                if (string.IsNullOrEmpty(folderPath) || !Directory.Exists(folderPath))
                    return;

                var jsonFilePath = Path.Combine(folderPath, slideIndex.ToString("0000") + ".images.json");
                if (File.Exists(jsonFilePath))
                {
                    File.Delete(jsonFilePath);
                    LogHelper.WriteLogToFile($"已删除第{slideIndex}页图片路径JSON文件: {jsonFilePath}");
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"删除PPT图片路径JSON文件失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void SubscribeToPPTEvents()
        {
            try
            {
                if (_mainWindow == null) return;

                // 获取PPTManager
                var pptManagerProperty = _mainWindow.GetType().GetProperty("PPTManager",
                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                var pptManager = pptManagerProperty?.GetValue(_mainWindow);

                if (pptManager != null)
                {
                    // 订阅PPT演示文稿打开事件
                    var presentationOpenEvent = pptManager.GetType().GetEvent("PresentationOpen");
                    if (presentationOpenEvent != null)
                    {
                        var openHandler = new Action<object>(OnPPTPresentationOpen);
                        presentationOpenEvent.AddEventHandler(pptManager, openHandler);
                    }

                    // 订阅PPT开始事件
                    var slideShowBeginEvent = pptManager.GetType().GetEvent("SlideShowBegin");
                    if (slideShowBeginEvent != null)
                    {
                        var beginHandler = new Action<object>(OnPPTSlideShowBegin);
                        slideShowBeginEvent.AddEventHandler(pptManager, beginHandler);
                    }

                    // 订阅PPT翻页事件
                    var slideShowNextSlideEvent = pptManager.GetType().GetEvent("SlideShowNextSlide");
                    if (slideShowNextSlideEvent != null)
                    {
                        var handler = new Action<object>(OnPPTSlideChanged);
                        slideShowNextSlideEvent.AddEventHandler(pptManager, handler);
                    }

                    // 订阅PPT结束事件
                    var slideShowEndEvent = pptManager.GetType().GetEvent("SlideShowEnd");
                    if (slideShowEndEvent != null)
                    {
                        var handler = new Action<object>(OnPPTSlideShowEnd);
                        slideShowEndEvent.AddEventHandler(pptManager, handler);
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"订阅PPT事件失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void OnPPTPresentationOpen(object presentation)
        {
            Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                try
                {
                    // PPT打开时，加载所有图片路径
                    LoadAllPPTImagePaths();
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLogToFile($"处理PPT打开事件失败: {ex.Message}", LogHelper.LogType.Error);
                }
            }), DispatcherPriority.Normal);
        }

        private void OnPPTSlideShowBegin(object window)
        {
            Application.Current.Dispatcher.BeginInvoke(new Action(async () =>
            {
                try
                {
                    // PPT开始时，加载所有图片路径并加载当前页面的图片
                    LoadAllPPTImagePaths();

                    if (_mainWindow == null) return;

                    // 获取当前PPT页面编号
                    var pptManagerProperty = _mainWindow.GetType().GetProperty("PPTManager",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                    var pptManager = pptManagerProperty?.GetValue(_mainWindow);

                    if (pptManager != null)
                    {
                        var getCurrentSlideNumberMethod = pptManager.GetType().GetMethod("GetCurrentSlideNumber");
                        int currentSlide = 0;
                        if (getCurrentSlideNumberMethod != null)
                        {
                            var result = getCurrentSlideNumberMethod.Invoke(pptManager, null);
                            if (result != null)
                            {
                                currentSlide = (int)result;
                            }
                        }

                        // 加载当前页面的图片
                        if (currentSlide > 0)
                        {
                            await LoadPPTImages(currentSlide);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLogToFile($"处理PPT开始事件失败: {ex.Message}", LogHelper.LogType.Error);
                }
            }), DispatcherPriority.Normal);
        }

        private void OnPPTSlideChanged(object window)
        {
            Application.Current.Dispatcher.BeginInvoke(new Action(async () =>
            {
                try
                {
                    if (_mainWindow == null) return;

                    // 获取当前PPT页面编号
                    var pptManagerProperty = _mainWindow.GetType().GetProperty("PPTManager",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                    var pptManager = pptManagerProperty?.GetValue(_mainWindow);

                    if (pptManager != null)
                    {
                        var getCurrentSlideNumberMethod = pptManager.GetType().GetMethod("GetCurrentSlideNumber");
                        int currentSlide = 0;
                        if (getCurrentSlideNumberMethod != null)
                        {
                            var result = getCurrentSlideNumberMethod.Invoke(pptManager, null);
                            if (result != null)
                            {
                                currentSlide = (int)result;
                            }
                        }

                        // 更新图片可见性
                        UpdatePPTImagesVisibility(currentSlide);

                        // 加载当前页面的图片（如果还没有加载）
                        if (currentSlide > 0 && (!_pptImagePaths.ContainsKey(currentSlide) || _pptImagePaths[currentSlide].Count == 0))
                        {
                            // 先加载图片路径
                            var imagePaths = LoadPPTImagePaths(currentSlide);
                            if (imagePaths != null && imagePaths.Count > 0)
                            {
                                _pptImagePaths[currentSlide] = imagePaths;

                                // 加载图片
                                await LoadPPTImages(currentSlide);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLogToFile($"处理PPT翻页事件失败: {ex.Message}", LogHelper.LogType.Error);
                }
            }), DispatcherPriority.Normal);
        }

        private void OnPPTSlideShowEnd(object presentation)
        {
            Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                try
                {
                    // PPT退出时隐藏所有图片
                    HideAllPPTImages();
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLogToFile($"处理PPT结束事件失败: {ex.Message}", LogHelper.LogType.Error);
                }
            }), DispatcherPriority.Normal);
        }

        private void UpdatePPTImagesVisibility(int currentSlide)
        {
            try
            {
                foreach (var kvp in _pptImages)
                {
                    var image = kvp.Key;
                    var slideNumber = kvp.Value;

                    // 如果图片在当前页面，显示；否则隐藏
                    image.Visibility = (slideNumber == currentSlide) ? Visibility.Visible : Visibility.Collapsed;
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"更新PPT图片可见性失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void HideAllPPTImages()
        {
            try
            {
                foreach (var image in _pptImages.Keys)
                {
                    image.Visibility = Visibility.Collapsed;
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"隐藏所有PPT图片失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void PPTQuickPanel_Unloaded(object sender, RoutedEventArgs e)
        {
            SystemEvents.UserPreferenceChanged -= SystemEvents_UserPreferenceChanged;
            UnsubscribeFromInkCanvasChildrenChanges();
        }

        private void UnsubscribeFromInkCanvasChildrenChanges()
        {
            try
            {
                if (_mainWindow == null) return;

                System.Windows.Controls.InkCanvas inkCanvas = null;
                var inkCanvasField = _mainWindow.GetType().GetField("inkCanvas",
                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                if (inkCanvasField != null)
                {
                    inkCanvas = inkCanvasField.GetValue(_mainWindow) as System.Windows.Controls.InkCanvas;
                }
                if (inkCanvas == null)
                {
                    var inkCanvasProperty = _mainWindow.GetType().GetProperty("inkCanvas",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                    inkCanvas = inkCanvasProperty?.GetValue(_mainWindow) as System.Windows.Controls.InkCanvas;
                }

                if (inkCanvas != null && inkCanvas.Children is INotifyCollectionChanged notifyCollection)
                {
                    notifyCollection.CollectionChanged -= InkCanvasChildren_CollectionChanged;
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"取消订阅inkCanvas.Children变化事件失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
        {
            Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                ApplyTheme();
            }), DispatcherPriority.Normal);
        }

        #region 音频控制

        private void InitializeAudio()
        {
            try
            {
                var deviceEnumerator = MMDeviceEnumeratorFactory.CreateInstance();
                IMMDevice device;
                deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, out device);

                Guid IID_IAudioEndpointVolume = new Guid("5CDF2C82-841E-4546-9722-0CF74078229A");
                object interfacePointer;
                device.Activate(ref IID_IAudioEndpointVolume, 0, IntPtr.Zero, out interfacePointer);
                _audioEndpointVolume = interfacePointer as IAudioEndpointVolume;
            }
            catch (Exception)
            {
            }
        }

        private float GetVolume()
        {
            if (_audioEndpointVolume == null) return 0.5f;
            try
            {
                float level;
                _audioEndpointVolume.GetMasterVolumeLevelScalar(out level);
                return level;
            }
            catch
            {
                return 0.5f;
            }
        }

        private void SetVolume(float volume)
        {
            if (_audioEndpointVolume == null) return;
            try
            {
                volume = Math.Max(0f, Math.Min(1f, volume));
                _audioEndpointVolume.SetMasterVolumeLevelScalar(volume, Guid.Empty);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"设置音量失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private bool GetMute()
        {
            if (_audioEndpointVolume == null) return false;
            try
            {
                bool mute;
                _audioEndpointVolume.GetMute(out mute);
                return mute;
            }
            catch
            {
                return false;
            }
        }

        private void SetMute(bool mute)
        {
            if (_audioEndpointVolume == null) return;
            try
            {
                _audioEndpointVolume.SetMute(mute, Guid.Empty);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"设置静音失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void UpdateVolumeDisplay()
        {
            if (_audioEndpointVolume == null) return;

            try
            {
                float volume = GetVolume();
                bool isMuted = GetMute();

                // 更新滑块值（不触发事件）
                VolumeSlider.ValueChanged -= VolumeSlider_ValueChanged;
                VolumeSlider.Value = volume * 100;
                VolumeSlider.ValueChanged += VolumeSlider_ValueChanged;

                // 更新文本显示
                VolumeValueText.Text = $"{(int)(volume * 100)}%";

                // 更新图标
                UpdateVolumeIcon(isMuted, volume);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"更新音量显示失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void UpdateVolumeIcon(bool isMuted, float volume)
        {
            // 清除描边
            VolumeIconPath.Stroke = null;
            VolumeIconPath.StrokeThickness = 0;
            VolumeIconPath2.Stroke = null;
            VolumeIconPath2.StrokeThickness = 0;

            // 默认隐藏第二个Path
            VolumeIconPath2.Visibility = Visibility.Collapsed;

            // 静音或音量为0%时显示静音图标
            if (isMuted || volume <= 0f)
            {
                // 静音图标：扬声器 + X
                // 扬声器部分
                var speakerGeometry = Geometry.Parse("M 7,1.00772 C 6.70313,1.00381 6.42188,1.13272 6.23048,1.35928 L 3,4.99991 H 2 C 0.906251,4.99991 0,5.84366 0,6.99991 V 8.99991 C 0,10.0898 0.910157,10.9999 2,10.9999 H 3 L 6.23048,14.6405 C 6.44141,14.8944 6.72266,15.0038 7,14.9999 V 1.00772 Z");
                // X部分
                var xGeometry = Geometry.Parse("M 10,5.00012 C 9.73441,5.00012 9.4805,5.10559 9.293,5.29309 C 8.90237,5.68372 8.90237,6.31653 9.293,6.70715 L 10.586,8.00013 L 9.293,9.2931 C 8.90237,9.68372 8.90237,10.3165 9.293,10.7072 C 9.68362,11.0978 10.3164,11.0978 10.7071,10.7072 L 12,9.41419 L 13.293,10.7072 C 13.6836,11.0978 14.3164,11.0978 14.7071,10.7072 C 15.0977,10.3165 15.0977,9.68372 14.7071,9.2931 L 13.4141,8.00013 L 14.7071,6.70715 C 15.0977,6.31653 15.0977,5.68372 14.7071,5.29309 C 14.5196,5.10559 14.2657,5.00012 14,5.00012 C 13.7344,5.00012 13.4805,5.10559 13.293,5.29309 L 12,6.58606 L 10.7071,5.29309 C 10.5196,5.10559 10.2657,5.00012 10,5.00012 Z");

                var group = new GeometryGroup();
                group.Children.Add(speakerGeometry);
                group.Children.Add(xGeometry);
                VolumeIconPath.Data = group;
                VolumeIconPath2.Visibility = Visibility.Collapsed;
            }
            else if (volume >= 0.5f)
            {
                // 音量>=50%：扬声器 + 两条声波线
                // 扬声器部分
                var speakerGeometry = Geometry.Parse("M 7,0 C 6.70313,0 6.42188,0.125086 6.23048,0.35165 L 3,3.99228 H 2 C 0.906251,3.99228 0,4.83603 0,5.99228 V 7.99228 C 0,9.08213 0.910157,9.99228 2,9.99228 H 3 L 6.23048,13.6329 C 6.44141,13.8868 6.72266,13.9962 7,13.9923 V 0 Z");
                // 第一条声波线
                var wave1Geometry = Geometry.Parse("M 13.461,0.961025 C 13.2695,0.957119 13.0742,1.01571 12.9024,1.12899 C 12.4453,1.44149 12.3242,2.06259 12.6328,2.51962 C 14.457,5.22666 14.457,8.75791 12.6328,11.4649 C 12.3242,11.922 12.4453,12.5431 12.9024,12.8556 C 13.3594,13.1642 13.9805,13.0431 14.293,12.586 C 15.4297,10.8946 16,8.94541 16,6.99228 C 16,5.03915 15.4297,3.08993 14.293,1.39853 C 14.0977,1.11337 13.7813,0.961025 13.461,0.961025 Z");
                // 第二条声波线
                var wave2Geometry = Geometry.Parse("M 10.0391,2.98056 C 9.81642,2.97275 9.58595,3.03915 9.39454,3.18368 C 9.13282,3.3829 9.00001,3.68368 9.00001,3.98837 V 4.04697 C 9.01173,4.23837 9.07423,4.42197 9.19923,4.58212 C 10.2734,6.01181 10.2734,7.97275 9.19923,9.39853 C 9.07423,9.5626 9.01173,9.74619 9.00001,9.93369 V 9.99619 C 9.00001,10.3009 9.13282,10.6017 9.39454,10.8009 C 9.83595,11.1329 10.4609,11.0431 10.793,10.6017 C 11.5977,9.53525 12,8.26572 12,6.99228 C 12,5.71884 11.5977,4.44931 10.793,3.379 C 10.6094,3.1329 10.3281,2.99618 10.0391,2.98056 Z");

                var group = new GeometryGroup();
                group.Children.Add(speakerGeometry);
                group.Children.Add(wave1Geometry);
                group.Children.Add(wave2Geometry);
                VolumeIconPath.Data = group;
                VolumeIconPath2.Visibility = Visibility.Collapsed;
            }
            else
            {
                // 音量<50%：扬声器 + 一条实线声波线
                // 扬声器部分
                var speakerGeometry = Geometry.Parse("M 7,1.00759 C 6.70313,1.00369 6.42188,1.13259 6.23048,1.35916 L 3,4.99979 H 2 C 0.906251,4.99979 0,5.84354 0,6.99979 V 8.99979 C 0,10.0896 0.910157,10.9998 2,10.9998 H 3 L 6.23048,14.6404 C 6.44141,14.8943 6.72266,15.0037 7,14.9998 V 1.00759 Z");
                // 声波线（实线，不透明度100%）
                var wave1Geometry = Geometry.Parse("M 10.0391,3.98807 C 9.81642,3.98025 9.58595,4.04666 9.39454,4.19119 C 9.13282,4.39041 9.00001,4.69119 9.00001,4.99588 V 5.06229 C 9.01173,5.24979 9.07813,5.43338 9.19923,5.58963 C 10.2734,7.01932 10.2734,8.98026 9.19923,10.406 C 9.07813,10.5662 9.01173,10.7498 9.00001,10.9373 V 11.0037 C 9.00001,11.3084 9.13282,11.6092 9.39454,11.8084 C 9.83595,12.1404 10.4609,12.0506 10.793,11.6092 C 11.5977,10.5428 12,9.27323 12,7.99979 C 12,6.72635 11.5977,5.45682 10.793,4.3865 C 10.6094,4.14041 10.3281,4.00369 10.0391,3.98807 Z");

                // 主Path：扬声器 + 声波线
                var group = new GeometryGroup();
                group.Children.Add(speakerGeometry);
                group.Children.Add(wave1Geometry);
                VolumeIconPath.Data = group;

                // 隐藏第二个Path
                VolumeIconPath2.Visibility = Visibility.Collapsed;
            }
        }

        #endregion

        #region 展开/折叠动画

        private void ExpandPanel()
        {
            if (_isExpanded) return;

            _isExpanded = true;
            UpdateArrowRotation();

            var animation = (Storyboard)Resources["ExpandAnimation"];
            var doubleAnimation = animation.Children[0] as DoubleAnimation;
            doubleAnimation.From = PanelTransform.X;
            doubleAnimation.To = 0;
            animation.Begin();
        }

        private void CollapsePanel()
        {
            if (!_isExpanded) return;

            _isExpanded = false;
            UpdateArrowRotation();

            var animation = (Storyboard)Resources["CollapseAnimation"];
            var doubleAnimation = animation.Children[0] as DoubleAnimation;
            doubleAnimation.From = PanelTransform.X;
            doubleAnimation.To = _collapsedOffset;
            animation.Begin();
        }

        private void UpdateArrowRotation()
        {
            if (_isExpanded)
            {
                // 展开时箭头指向左（折叠）
                ArrowRotateTransform.Angle = 0;
            }
            else
            {
                // 折叠时箭头指向右（展开）
                ArrowRotateTransform.Angle = 180;
            }
        }

        #endregion

        #region 箭头按钮事件

        private void ArrowButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            if (_isExpanded)
            {
                CollapsePanel();
            }
            else
            {
                ExpandPanel();
            }
        }

        private void ArrowButton_MouseEnter(object sender, MouseEventArgs e)
        {
            ArrowButtonBackgroundBrush.Color = Color.FromArgb(220, 55, 55, 55);
        }

        private void ArrowButton_MouseLeave(object sender, MouseEventArgs e)
        {
            ArrowButtonBackgroundBrush.Color = Color.FromArgb(204, 31, 31, 31);
        }

        #endregion

        #region 拖动手势

        private static bool IsWithinSlider(object source)
        {
            var d = source as DependencyObject;
            while (d != null)
            {
                if (d is Slider) return true;
                d = (d is System.Windows.Media.Visual || d is System.Windows.Media.Media3D.Visual3D)
                    ? System.Windows.Media.VisualTreeHelper.GetParent(d)
                    : LogicalTreeHelper.GetParent(d);
            }
            return false;
        }

        private void ContentBorder_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (IsWithinSlider(e.OriginalSource)) return;

            _isDragging = true;
            _dragStartPoint = e.GetPosition(MainCanvas);
            ContentBorder.CaptureMouse();
            e.Handled = true;
        }

        private void ContentBorder_MouseMove(object sender, MouseEventArgs e)
        {
            if (!_isDragging) return;

            Point currentPoint = e.GetPosition(MainCanvas);
            double deltaX = currentPoint.X - _dragStartPoint.X;

            // 计算新位置
            double newX = PanelTransform.X + deltaX;

            // 限制拖动范围
            newX = Math.Max(0, Math.Min(_collapsedOffset, newX));

            PanelTransform.X = newX;
            _dragStartPoint = currentPoint;
        }

        private void ContentBorder_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (!_isDragging) return;

            _isDragging = false;
            ContentBorder.ReleaseMouseCapture();

            // 判断是否超过一半
            if (PanelTransform.X < _collapsedOffset / 2)
            {
                ExpandPanel();
            }
            else
            {
                CollapsePanel();
            }
        }

        private void ContentBorder_TouchDown(object sender, TouchEventArgs e)
        {
            if (IsWithinSlider(e.OriginalSource)) return;

            _isDragging = true;
            _dragStartPoint = e.GetTouchPoint(MainCanvas).Position;
            e.Handled = true;
        }

        private void ContentBorder_TouchMove(object sender, TouchEventArgs e)
        {
            if (!_isDragging) return;

            Point currentPoint = e.GetTouchPoint(MainCanvas).Position;
            double deltaX = currentPoint.X - _dragStartPoint.X;

            double newX = PanelTransform.X + deltaX;
            newX = Math.Max(0, Math.Min(_collapsedOffset, newX));

            PanelTransform.X = newX;
            _dragStartPoint = currentPoint;
        }

        private void ContentBorder_TouchUp(object sender, TouchEventArgs e)
        {
            if (!_isDragging) return;

            _isDragging = false;

            if (PanelTransform.X < _collapsedOffset / 2)
            {
                ExpandPanel();
            }
            else
            {
                CollapsePanel();
            }
        }

        #endregion

        #region 音量控制事件

        private void VolumeMuteButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                bool currentMute = GetMute();
                float volume = GetVolume();
                SetMute(!currentMute);
                UpdateVolumeIcon(!currentMute, volume);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"切换静音失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void VolumeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (!IsLoaded) return;

            try
            {
                float volume = (float)(e.NewValue / 100.0);
                SetVolume(volume);

                // 更新文本显示
                VolumeValueText.Text = $"{(int)e.NewValue}%";

                // 如果音量大于0，取消静音
                if (e.NewValue > 0)
                {
                    bool isMuted = GetMute();
                    if (isMuted)
                    {
                        SetMute(false);
                    }
                }

                // 更新图标（根据当前音量和静音状态）
                bool currentMute = GetMute();
                UpdateVolumeIcon(currentMute, volume);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"音量滑块值改变处理失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void VolumeSlider_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            // 确保精度为1%
            double value = VolumeSlider.Value;
            VolumeSlider.Value = Math.Round(value);
        }

        private void VolumeSlider_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            // 触摸操作完成时，确保精度为1%
            double value = VolumeSlider.Value;
            VolumeSlider.Value = Math.Round(value);
        }

        #endregion

        #region 图片插入

        private async void InsertImageSelectFileButton_Click(object sender, RoutedEventArgs e)
        {
            if (_mainWindow == null) return;

            try
            {
                var dialog = new OpenFileDialog
                {
                    Filter = "图片与 PDF|*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.pdf|图片文件|*.jpg;*.jpeg;*.png;*.bmp;*.gif|PDF|*.pdf"
                };

                if (dialog.ShowDialog() == true)
                {
                    string filePath = dialog.FileName;

                    var createImageMethod = _mainWindow.GetType().GetMethod("CreateAndCompressImageAsync",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

                    if (createImageMethod != null)
                    {
                        var imageTask = createImageMethod.Invoke(_mainWindow, new object[] { filePath }) as System.Threading.Tasks.Task<FrameworkElement>;
                        if (imageTask != null)
                        {
                            var inserted = await imageTask;
                            if (inserted != null)
                            {
                                inserted.Tag = filePath;
                                await InsertImageToMainWindow(inserted, filePath);
                            }
                        }
                    }
                    else
                    {
                        LogHelper.WriteLogToFile("无法找到CreateAndCompressImageAsync方法", LogHelper.LogType.Warning);
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"插入图片失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private async void InsertImageScreenshotButton_Click(object sender, RoutedEventArgs e)
        {
            if (_mainWindow == null) return;

            try
            {
                var captureScreenshotMethod = _mainWindow.GetType().GetMethod("CaptureScreenshotAndInsert",
                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

                if (captureScreenshotMethod != null)
                {
                    var task = captureScreenshotMethod.Invoke(_mainWindow, null) as System.Threading.Tasks.Task;
                    if (task != null)
                    {
                        await task;
                        await SaveScreenshotToPPT();
                    }
                }
                else
                {
                    LogHelper.WriteLogToFile("无法找到CaptureScreenshotAndInsert方法", LogHelper.LogType.Warning);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"截图插入失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private async System.Threading.Tasks.Task SaveScreenshotToPPT()
        {
            try
            {
                if (_mainWindow == null) return;

                System.Windows.Controls.InkCanvas inkCanvas = null;
                var inkCanvasField = _mainWindow.GetType().GetField("inkCanvas",
                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                if (inkCanvasField != null)
                {
                    inkCanvas = inkCanvasField.GetValue(_mainWindow) as System.Windows.Controls.InkCanvas;
                }
                if (inkCanvas == null)
                {
                    var inkCanvasProperty = _mainWindow.GetType().GetProperty("inkCanvas",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                    inkCanvas = inkCanvasProperty?.GetValue(_mainWindow) as System.Windows.Controls.InkCanvas;
                }

                if (inkCanvas == null) return;

                System.Windows.Controls.Image lastScreenshot = null;
                foreach (System.Windows.Controls.Image img in inkCanvas.Children.OfType<System.Windows.Controls.Image>())
                {
                    if (img.Name != null && (img.Name.StartsWith("screenshot_") || img.Name.StartsWith("camera_")) && img.Tag == null)
                    {
                        lastScreenshot = img;
                    }
                }

                if (lastScreenshot == null) return;

                string screenshotFilePath = await SaveScreenshotToFile(lastScreenshot);

                if (string.IsNullOrEmpty(screenshotFilePath))
                {
                    LogHelper.WriteLogToFile("保存截图文件失败", LogHelper.LogType.Warning);
                    return;
                }

                lastScreenshot.Tag = screenshotFilePath;
                await ManageScreenshotInPPT(lastScreenshot, screenshotFilePath);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"保存截图到PPT失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private async System.Threading.Tasks.Task<string> SaveScreenshotToFile(System.Windows.Controls.Image image)
        {
            try
            {
                if (image?.Source == null) return null;

                string savePath = null;
                var settingsProperty = _mainWindow.GetType().GetProperty("Settings");
                if (settingsProperty != null)
                {
                    var settings = settingsProperty.GetValue(_mainWindow);
                    if (settings != null)
                    {
                        var autoSavedStrokesLocationProperty = settings.GetType().GetProperty("Automation");
                        if (autoSavedStrokesLocationProperty != null)
                        {
                            var automation = autoSavedStrokesLocationProperty.GetValue(settings);
                            if (automation != null)
                            {
                                var locationProperty = automation.GetType().GetProperty("AutoSavedStrokesLocation");
                                if (locationProperty != null)
                                {
                                    var location = locationProperty.GetValue(automation) as string;
                                    if (!string.IsNullOrEmpty(location))
                                    {
                                        savePath = Path.Combine(location, "File Dependency");
                                    }
                                }
                            }
                        }
                    }
                }

                if (string.IsNullOrEmpty(savePath))
                {
                    LogHelper.WriteLogToFile("无法获取AutoSavedStrokesLocation", LogHelper.LogType.Warning);
                    return null;
                }

                if (!Directory.Exists(savePath))
                {
                    Directory.CreateDirectory(savePath);
                }

                string timestamp = image.Name;
                string filePath = Path.Combine(savePath, timestamp + ".png");

                await Application.Current.Dispatcher.InvokeAsync(() =>
                {
                    if (image.Source is BitmapSource bitmapSource)
                    {
                        var encoder = new PngBitmapEncoder();
                        encoder.Frames.Add(BitmapFrame.Create(bitmapSource));

                        using (var fileStream = new FileStream(filePath, FileMode.Create))
                        {
                            encoder.Save(fileStream);
                        }
                    }
                });

                return filePath;
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"保存截图到文件失败: {ex.Message}", LogHelper.LogType.Error);
                return null;
            }
        }

        private async System.Threading.Tasks.Task ManageScreenshotInPPT(System.Windows.Controls.Image image, string filePath)
        {
            if (_mainWindow == null || image == null || string.IsNullOrEmpty(filePath)) return;

            await Application.Current.Dispatcher.InvokeAsync(() =>
            {
                try
                {
                    int currentSlideNumber = 0;
                    try
                    {
                        var pptManagerProperty = _mainWindow.GetType().GetProperty("PPTManager",
                            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                        var pptManager = pptManagerProperty?.GetValue(_mainWindow);

                        if (pptManager != null)
                        {
                            var isInSlideShowProperty = pptManager.GetType().GetProperty("IsInSlideShow");
                            bool isInSlideShow = false;
                            if (isInSlideShowProperty != null)
                            {
                                var result = isInSlideShowProperty.GetValue(pptManager);
                                if (result != null)
                                {
                                    isInSlideShow = (bool)result;
                                }
                            }

                            if (isInSlideShow)
                            {
                                var getCurrentSlideNumberMethod = pptManager.GetType().GetMethod("GetCurrentSlideNumber");
                                if (getCurrentSlideNumberMethod != null)
                                {
                                    var result = getCurrentSlideNumberMethod.Invoke(pptManager, null);
                                    if (result != null)
                                    {
                                        currentSlideNumber = (int)result;
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteLogToFile($"获取当前PPT页面编号失败: {ex.Message}", LogHelper.LogType.Warning);
                    }

                    if (currentSlideNumber > 0 && !string.IsNullOrEmpty(filePath))
                    {
                        _pptImages[image] = currentSlideNumber;

                        if (!_pptImagePaths.ContainsKey(currentSlideNumber))
                        {
                            _pptImagePaths[currentSlideNumber] = new List<string>();
                        }
                        _pptImagePaths[currentSlideNumber].Add(filePath);
                        SavePPTImagePaths(currentSlideNumber);

                        LogHelper.WriteLogToFile($"截图已关联到PPT页面{currentSlideNumber}: {filePath}");
                    }
                    else if (currentSlideNumber > 0)
                    {
                        _pptImages[image] = currentSlideNumber;
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLogToFile($"管理截图在PPT中的关联失败: {ex.Message}", LogHelper.LogType.Error);
                }
            }, DispatcherPriority.Normal);
        }

        private async System.Threading.Tasks.Task InsertImageToMainWindow(FrameworkElement element, string originalFilePath = null, bool saveToJson = true)
        {
            if (_mainWindow == null || element == null) return;

            // 确保在UI线程上执行
            await Application.Current.Dispatcher.InvokeAsync(() =>
            {
                try
                {
                    // 生成唯一名称
                    string timestamp = "img_" + DateTime.Now.ToString("yyyyMMdd_HH_mm_ss_fff");
                    element.Name = timestamp;

                    // 设置图片属性
                    element.IsHitTestVisible = true;
                    element.Focusable = false;

                    System.Windows.Controls.InkCanvas inkCanvas = null;
                    var inkCanvasField = _mainWindow.GetType().GetField("inkCanvas",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                    if (inkCanvasField != null)
                    {
                        inkCanvas = inkCanvasField.GetValue(_mainWindow) as System.Windows.Controls.InkCanvas;
                    }

                    if (inkCanvas == null)
                    {
                        var inkCanvasProperty = _mainWindow.GetType().GetProperty("inkCanvas",
                            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                        if (inkCanvasProperty != null)
                        {
                            inkCanvas = inkCanvasProperty.GetValue(_mainWindow) as System.Windows.Controls.InkCanvas;
                        }
                    }

                    if (inkCanvas == null)
                    {
                        LogHelper.WriteLogToFile("无法获取inkCanvas", LogHelper.LogType.Error);
                        return;
                    }

                    // 初始化InkCanvas选择设置
                    var initializeInkCanvasSelectionSettingsMethod = _mainWindow.GetType().GetMethod("InitializeInkCanvasSelectionSettings",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                    initializeInkCanvasSelectionSettingsMethod?.Invoke(_mainWindow, null);

                    // 获取当前PPT页面编号（如果在PPT模式下）
                    int currentSlideNumber = 0;
                    try
                    {
                        var pptManagerProperty = _mainWindow.GetType().GetProperty("PPTManager",
                            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                        var pptManager = pptManagerProperty?.GetValue(_mainWindow);

                        if (pptManager != null)
                        {
                            var isInSlideShowProperty = pptManager.GetType().GetProperty("IsInSlideShow");
                            bool isInSlideShow = false;
                            if (isInSlideShowProperty != null)
                            {
                                var result = isInSlideShowProperty.GetValue(pptManager);
                                if (result != null)
                                {
                                    isInSlideShow = (bool)result;
                                }
                            }

                            if (isInSlideShow)
                            {
                                var getCurrentSlideNumberMethod = pptManager.GetType().GetMethod("GetCurrentSlideNumber");
                                if (getCurrentSlideNumberMethod != null)
                                {
                                    var result = getCurrentSlideNumberMethod.Invoke(pptManager, null);
                                    if (result != null)
                                    {
                                        currentSlideNumber = (int)result;
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteLogToFile($"获取当前PPT页面编号失败: {ex.Message}", LogHelper.LogType.Warning);
                    }

                    // 如果在PPT模式下，记录图片和页面编号的关联，并保存图片路径
                    if (currentSlideNumber > 0 && !string.IsNullOrEmpty(originalFilePath) && saveToJson)
                    {
                        _pptImages[element] = currentSlideNumber;

                        // 添加到页面图片路径列表
                        if (!_pptImagePaths.ContainsKey(currentSlideNumber))
                        {
                            _pptImagePaths[currentSlideNumber] = new List<string>();
                        }
                        _pptImagePaths[currentSlideNumber].Add(originalFilePath);

                        // 保存图片路径到JSON文件
                        SavePPTImagePaths(currentSlideNumber);
                    }
                    else if (currentSlideNumber > 0)
                    {
                        // 即使不保存到JSON，也要记录图片和页面编号的关联（用于翻页显示/隐藏）
                        _pptImages[element] = currentSlideNumber;
                    }

                    // 先添加到画布（与MainWindow的实现保持一致）
                    inkCanvas.Children.Add(element);

                    // 等待图片加载完成后再进行后续处理
                    element.Loaded += (s, args) =>
                    {
                        Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            try
                            {
                                // 初始化TransformGroup
                                var initializeTransformMethod = _mainWindow.GetType().GetMethod("InitializeElementTransform",
                                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                                initializeTransformMethod?.Invoke(_mainWindow, new object[] { element });

                                // 居中缩放
                                var centerMethod = _mainWindow.GetType().GetMethod("CenterAndScaleElement",
                                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                                centerMethod?.Invoke(_mainWindow, new object[] { element });

                                // 绑定事件处理器
                                var bindEventsMethod = _mainWindow.GetType().GetMethod("BindElementEvents",
                                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                                bindEventsMethod?.Invoke(_mainWindow, new object[] { element });

                                LogHelper.WriteLogToFile($"图片插入完成: {element.Name}, PPT页面: {currentSlideNumber}");
                            }
                            catch (Exception ex)
                            {
                                LogHelper.WriteLogToFile($"图片加载后处理失败: {ex.Message}", LogHelper.LogType.Error);
                            }
                        }), DispatcherPriority.Loaded);
                    };

                    // 提交历史记录
                    var timeMachineProperty = _mainWindow.GetType().GetProperty("timeMachine",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                    var timeMachine = timeMachineProperty?.GetValue(_mainWindow);
                    if (timeMachine != null)
                    {
                        var commitMethod = timeMachine.GetType().GetMethod("CommitElementInsertHistory");
                        commitMethod?.Invoke(timeMachine, new object[] { element });
                    }

                    // 切换到选择模式
                    var setModeMethod = _mainWindow.GetType().GetMethod("SetCurrentToolMode",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                    setModeMethod?.Invoke(_mainWindow, new object[] { System.Windows.Controls.InkCanvasEditingMode.Select });

                    var updateModeMethod = _mainWindow.GetType().GetMethod("UpdateCurrentToolMode",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                    updateModeMethod?.Invoke(_mainWindow, new object[] { "select" });

                    var hidePanelsMethod = _mainWindow.GetType().GetMethod("HideSubPanels",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                    hidePanelsMethod?.Invoke(_mainWindow, new object[] { "select" });
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLogToFile($"插入图片到MainWindow失败: {ex.Message}", LogHelper.LogType.Error);
                }
            }, DispatcherPriority.Normal);
        }

        #endregion

        #region PPT图片保存和加载

        /// <summary>
        /// 获取PPT演示文稿的文件夹路径
        /// </summary>
        private string GetPresentationFolderPath()
        {
            try
            {
                if (_mainWindow == null) return null;

                // 获取PPTInkManager
                var singlePPTInkManagerField = _mainWindow.GetType().GetField("_singlePPTInkManager",
                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                var singlePPTInkManager = singlePPTInkManagerField?.GetValue(_mainWindow);

                if (singlePPTInkManager != null)
                {
                    // 使用反射获取AutoSaveLocation
                    var autoSaveLocationProperty = singlePPTInkManager.GetType().GetProperty("AutoSaveLocation");
                    var autoSaveLocation = autoSaveLocationProperty?.GetValue(singlePPTInkManager) as string;

                    if (!string.IsNullOrEmpty(autoSaveLocation))
                    {
                        // 获取PPTManager以获取当前演示文稿信息
                        var pptManagerProperty = _mainWindow.GetType().GetProperty("PPTManager",
                            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                        var pptManager = pptManagerProperty?.GetValue(_mainWindow);

                        if (pptManager != null)
                        {
                            // 尝试获取当前演示文稿，使用重试机制
                            Microsoft.Office.Interop.PowerPoint.Presentation presentation = null;

                            // 首先尝试使用 CurrentPresentation 属性（可能是缓存的）
                            try
                            {
                                var currentPresentationProperty = pptManager.GetType().GetProperty("CurrentPresentation",
                                    System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
                                presentation = currentPresentationProperty?.GetValue(pptManager) as Microsoft.Office.Interop.PowerPoint.Presentation;
                            }
                            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }

                            // 如果 CurrentPresentation 不可用，尝试 GetCurrentActivePresentation
                            if (presentation == null)
                            {
                                try
                                {
                                    var getCurrentActivePresentationMethod = pptManager.GetType().GetMethod("GetCurrentActivePresentation");
                                    presentation = getCurrentActivePresentationMethod?.Invoke(pptManager, null) as Microsoft.Office.Interop.PowerPoint.Presentation;
                                }
                                catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }
                            }

                            if (presentation != null)
                            {
                                try
                                {
                                    // 立即检查COM对象是否仍然有效
                                    if (!System.Runtime.InteropServices.Marshal.IsComObject(presentation))
                                    {
                                        return null;
                                    }

                                    // 尝试访问对象以验证其有效性
                                    try
                                    {
                                        var _ = System.Runtime.InteropServices.Marshal.GetIUnknownForObject(presentation);
                                        System.Runtime.InteropServices.Marshal.Release(_);
                                    }
                                    catch (System.Runtime.InteropServices.InvalidComObjectException)
                                    {
                                        // COM对象已失效，静默返回
                                        return null;
                                    }

                                    // 立即生成演示文稿ID（在对象失效前）
                                    string presentationId = GeneratePresentationId(presentation);
                                    if (string.IsNullOrEmpty(presentationId) || presentationId.StartsWith("unknown_") || presentationId.StartsWith("invalid_") || presentationId.StartsWith("com_error_"))
                                    {
                                        // 生成ID失败，返回null而不是抛出异常
                                        return null;
                                    }

                                    return Path.Combine(autoSaveLocation, "Auto Saved - Presentations", presentationId);
                                }
                                catch (System.Runtime.InteropServices.InvalidComObjectException)
                                {
                                    // COM对象已失效，静默返回（不记录错误日志）
                                    return null;
                                }
                                catch (System.Runtime.InteropServices.COMException)
                                {
                                    // COM异常，对象可能已失效，静默返回（不记录错误日志）
                                    return null;
                                }
                                catch (Exception ex)
                                {
                                    // 其他异常，只记录非COM相关异常
                                    if (!(ex is System.Runtime.InteropServices.InvalidComObjectException) &&
                                        !(ex is System.Runtime.InteropServices.COMException))
                                    {
                                        LogHelper.WriteLogToFile($"获取PPT文件夹路径时发生非COM异常: {ex.Message}", LogHelper.LogType.Warning);
                                    }
                                    return null;
                                }
                            }
                        }
                    }
                }
            }
            catch (System.Runtime.InteropServices.InvalidComObjectException)
            {
                // COM对象已失效，静默返回（不记录错误日志）
                return null;
            }
            catch (System.Runtime.InteropServices.COMException)
            {
                // COM异常，对象可能已失效，静默返回（不记录错误日志）
                return null;
            }
            catch (Exception ex)
            {
                // 只记录非COM相关异常
                if (!(ex is System.Runtime.InteropServices.InvalidComObjectException) &&
                    !(ex is System.Runtime.InteropServices.COMException))
                {
                    LogHelper.WriteLogToFile($"获取PPT文件夹路径失败: {ex.Message}", LogHelper.LogType.Error);
                }
            }

            return null;
        }

        /// <summary>
        /// 生成演示文稿ID（与PPTInkManager一致）
        /// </summary>
        private string GeneratePresentationId(Microsoft.Office.Interop.PowerPoint.Presentation presentation)
        {
            if (presentation == null)
            {
                return $"unknown_{DateTime.Now.Ticks}";
            }

            try
            {
                // 检查COM对象是否仍然有效
                if (!System.Runtime.InteropServices.Marshal.IsComObject(presentation))
                {
                    return $"unknown_{DateTime.Now.Ticks}";
                }

                // 验证COM对象有效性
                try
                {
                    var _ = System.Runtime.InteropServices.Marshal.GetIUnknownForObject(presentation);
                    System.Runtime.InteropServices.Marshal.Release(_);
                }
                catch (System.Runtime.InteropServices.InvalidComObjectException)
                {
                    // COM对象已失效
                    return $"unknown_{DateTime.Now.Ticks}";
                }

                // 逐个访问属性，每个都进行异常处理
                string presentationName = null;
                string presentationPath = null;
                int slidesCount = 0;

                try
                {
                    presentationName = presentation.Name;
                }
                catch (System.Runtime.InteropServices.InvalidComObjectException)
                {
                    return $"unknown_{DateTime.Now.Ticks}";
                }
                catch (System.Runtime.InteropServices.COMException)
                {
                    return $"unknown_{DateTime.Now.Ticks}";
                }

                try
                {
                    presentationPath = presentation.FullName;
                }
                catch (System.Runtime.InteropServices.InvalidComObjectException)
                {
                    return $"unknown_{DateTime.Now.Ticks}";
                }
                catch (System.Runtime.InteropServices.COMException)
                {
                    return $"unknown_{DateTime.Now.Ticks}";
                }

                try
                {
                    slidesCount = presentation.Slides.Count;
                }
                catch (System.Runtime.InteropServices.InvalidComObjectException)
                {
                    return $"unknown_{DateTime.Now.Ticks}";
                }
                catch (System.Runtime.InteropServices.COMException)
                {
                    return $"unknown_{DateTime.Now.Ticks}";
                }

                var fileHash = GetFileHash(presentationPath);
                return $"{presentationName}_{slidesCount}_{fileHash}";
            }
            catch (System.Runtime.InteropServices.InvalidComObjectException)
            {
                // COM对象已失效
                return $"unknown_{DateTime.Now.Ticks}";
            }
            catch (System.Runtime.InteropServices.COMException)
            {
                // COM异常，对象可能已失效
                return $"unknown_{DateTime.Now.Ticks}";
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"生成演示文稿ID失败: {ex}", LogHelper.LogType.Error);
                return $"unknown_{DateTime.Now.Ticks}";
            }
        }

        /// <summary>
        /// 计算文件哈希值
        /// </summary>
        private string GetFileHash(string filePath)
        {
            try
            {
                if (string.IsNullOrEmpty(filePath)) return "unknown";

                using (var md5 = System.Security.Cryptography.MD5.Create())
                {
                    byte[] hashBytes = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(filePath));
                    return BitConverter.ToString(hashBytes).Replace("-", "").Substring(0, 8);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"计算文件哈希值失败: {ex}", LogHelper.LogType.Error);
                return "error";
            }
        }

        /// <summary>
        /// 保存指定页面的图片路径到JSON文件
        /// </summary>
        private void SavePPTImagePaths(int slideIndex)
        {
            try
            {
                if (slideIndex <= 0 || !_pptImagePaths.ContainsKey(slideIndex)) return;

                var folderPath = GetPresentationFolderPath();
                if (string.IsNullOrEmpty(folderPath)) return;

                if (!Directory.Exists(folderPath))
                {
                    Directory.CreateDirectory(folderPath);
                }

                var jsonFilePath = Path.Combine(folderPath, slideIndex.ToString("0000") + ".images.json");
                var imagePaths = _pptImagePaths[slideIndex];

                string json = JsonConvert.SerializeObject(imagePaths, Formatting.Indented);
                File.WriteAllText(jsonFilePath, json);

                LogHelper.WriteLogToFile($"已保存第{slideIndex}页图片路径到JSON: {jsonFilePath}");
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"保存PPT图片路径失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        /// <summary>
        /// 从JSON文件加载指定页面的图片路径
        /// </summary>
        private List<string> LoadPPTImagePaths(int slideIndex)
        {
            try
            {
                if (slideIndex <= 0) return new List<string>();

                var folderPath = GetPresentationFolderPath();
                if (string.IsNullOrEmpty(folderPath) || !Directory.Exists(folderPath))
                    return new List<string>();

                var jsonFilePath = Path.Combine(folderPath, slideIndex.ToString("0000") + ".images.json");
                if (!File.Exists(jsonFilePath))
                    return new List<string>();

                string json = File.ReadAllText(jsonFilePath);
                var imagePaths = JsonConvert.DeserializeObject<List<string>>(json);

                return imagePaths ?? new List<string>();
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"加载PPT图片路径失败: {ex.Message}", LogHelper.LogType.Error);
                return new List<string>();
            }
        }

        /// <summary>
        /// 加载指定页面的图片
        /// </summary>
        private async System.Threading.Tasks.Task LoadPPTImages(int slideIndex)
        {
            try
            {
                if (_mainWindow == null || slideIndex <= 0) return;

                var imagePaths = LoadPPTImagePaths(slideIndex);
                if (imagePaths == null || imagePaths.Count == 0) return;

                // 获取inkCanvas，检查是否已有图片
                System.Windows.Controls.InkCanvas inkCanvas = null;
                var inkCanvasField = _mainWindow.GetType().GetField("inkCanvas",
                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                if (inkCanvasField != null)
                {
                    inkCanvas = inkCanvasField.GetValue(_mainWindow) as System.Windows.Controls.InkCanvas;
                }
                if (inkCanvas == null)
                {
                    var inkCanvasProperty = _mainWindow.GetType().GetProperty("inkCanvas",
                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                    inkCanvas = inkCanvasProperty?.GetValue(_mainWindow) as System.Windows.Controls.InkCanvas;
                }

                if (inkCanvas == null) return;

                // 检查已存在的图片路径（通过Tag）
                var existingImagePaths = new HashSet<string>();
                foreach (var existingImage in inkCanvas.Children.OfType<System.Windows.Controls.Image>())
                {
                    if (existingImage.Tag is string tagPath && !string.IsNullOrEmpty(tagPath))
                        existingImagePaths.Add(tagPath);
                }

                foreach (var existingPdf in inkCanvas.Children.OfType<PdfEmbeddedView>())
                {
                    if (existingPdf.Tag is string tagPath && !string.IsNullOrEmpty(tagPath))
                        existingImagePaths.Add(tagPath);
                }

                // 使用反射调用MainWindow的CreateAndCompressImageAsync方法
                var createImageMethod = _mainWindow.GetType().GetMethod("CreateAndCompressImageAsync",
                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

                if (createImageMethod == null)
                {
                    LogHelper.WriteLogToFile("无法找到CreateAndCompressImageAsync方法", LogHelper.LogType.Warning);
                    return;
                }

                foreach (var imagePath in imagePaths)
                {
                    try
                    {
                        // 如果图片已存在，跳过
                        if (existingImagePaths.Contains(imagePath))
                        {
                            continue;
                        }

                        if (!File.Exists(imagePath))
                        {
                            LogHelper.WriteLogToFile($"图片文件不存在: {imagePath}", LogHelper.LogType.Warning);
                            continue;
                        }

                        var imageTask = createImageMethod.Invoke(_mainWindow, new object[] { imagePath }) as System.Threading.Tasks.Task<FrameworkElement>;
                        if (imageTask != null)
                        {
                            var inserted = await imageTask;
                            if (inserted != null)
                            {
                                // 保存原始文件路径到Tag
                                inserted.Tag = imagePath;

                                // 插入图片（不保存路径，因为已经存在）
                                await InsertImageToMainWindow(inserted, imagePath, false);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteLogToFile($"加载图片失败: {imagePath}, 错误: {ex.Message}", LogHelper.LogType.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"加载PPT图片失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        /// <summary>
        /// 加载所有页面的图片路径（在PPT打开时调用）
        /// </summary>
        public void LoadAllPPTImagePaths()
        {
            try
            {
                if (_mainWindow == null) return;

                var folderPath = GetPresentationFolderPath();
                if (string.IsNullOrEmpty(folderPath) || !Directory.Exists(folderPath))
                    return;

                // 清空现有数据
                _pptImagePaths.Clear();

                // 查找所有图片JSON文件
                var jsonFiles = Directory.GetFiles(folderPath, "*.images.json");
                foreach (var jsonFile in jsonFiles)
                {
                    try
                    {
                        var fileName = Path.GetFileNameWithoutExtension(jsonFile);
                        fileName = fileName.Replace(".images", ""); // 移除.images后缀

                        if (int.TryParse(fileName, out int slideIndex) && slideIndex > 0)
                        {
                            var imagePaths = LoadPPTImagePaths(slideIndex);
                            if (imagePaths != null && imagePaths.Count > 0)
                            {
                                _pptImagePaths[slideIndex] = imagePaths;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteLogToFile($"加载图片路径文件失败: {jsonFile}, 错误: {ex.Message}", LogHelper.LogType.Error);
                    }
                }

                LogHelper.WriteLogToFile($"已加载{_pptImagePaths.Count}个页面的图片路径");
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"加载所有PPT图片路径失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        #endregion

        #region 主题适配

        private void ApplyTheme()
        {
            try
            {
                if (MainWindow.Settings != null)
                {
                    ApplyTheme(MainWindow.Settings);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"应用PPT快捷面板主题失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void ApplyTheme(Settings settings)
        {
            try
            {
                // Game Bar 风格：始终使用深色半透明外壳，不随系统主题翻转
                ArrowButtonBackgroundBrush.Color = Color.FromArgb(204, 31, 31, 31);
                ContentBackgroundBrush.Color = Color.FromArgb(204, 31, 31, 31); // #CC1F1F1F
                ArrowPathFillBrush.Color = Colors.White;
                VolumeIconFillBrush.Color = Colors.White;
                VolumeIconFillBrush2.Color = Colors.White;
                VolumeValueForegroundBrush.Color = Color.FromArgb(230, 255, 255, 255);
                MagnifierTitleForegroundBrush.Color = Colors.White;
                MagnifierDescForegroundBrush.Color = Color.FromArgb(200, 255, 255, 255);
                Separator1BackgroundBrush.Color = Color.FromArgb(60, 255, 255, 255);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"应用PPT快捷面板主题失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        #endregion

        #region 聚焦放大镜

        private void MagnifierToggleButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (MagnifierWindow.HasInstance)
                {
                    MagnifierWindow.HideInstance();
                    MagnifierToggleButton.Content = Properties.PPTStrings.PPTQuickPanel_OpenMagnifier;
                }
                else
                {
                    MagnifierWindow.Show((float)MagnifierZoomSlider.Value);
                    if (MagnifierWindow.HasInstance)
                    {
                        MagnifierToggleButton.Content = Properties.PPTStrings.PPTQuickPanel_CloseMagnifier;
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLogToFile($"切换聚焦放大镜失败: {ex.Message}", LogHelper.LogType.Error);
            }
        }

        private void MagnifierZoomSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (MagnifierZoomValueText != null)
            {
                MagnifierZoomValueText.Text = $"{e.NewValue:0.0}x";
            }
            if (MagnifierWindow.HasInstance)
            {
                MagnifierWindow.SetZoom((float)e.NewValue);
            }
        }

        #endregion

        #region 公开方法

        /// <summary>
        /// 设置面板的可见性（仅在PPT模式下显示）
        /// </summary>
        public void UpdateVisibility(bool isInPPTMode)
        {
            Visibility = isInPPTMode ? Visibility.Visible : Visibility.Collapsed;
            if (!isInPPTMode && MagnifierWindow.HasInstance)
            {
                MagnifierWindow.HideInstance();
                if (MagnifierToggleButton != null)
                    MagnifierToggleButton.Content = Properties.PPTStrings.PPTQuickPanel_OpenMagnifier;
            }
        }

        #endregion
    }
}

