using Newtonsoft.Json;
using System;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Ink_Canvas.Windows
{
    /// <summary>
    /// SplashScreen.xaml 的交互逻辑
    /// </summary>
    public partial class SplashScreen : Window
    {
        private int _actualSplashStyle = 1;

        /// <summary>
        /// 由 App 启动时注入的缓存 JSON，避免 SplashScreen 构造期间重复读取 + 解析 Settings.json。
        /// </summary>
        internal static string CachedSettingsJson { get; set; }

        /// <summary>
        /// 从缓存 JSON 中解析指定路径的值，返回 dynamic 对象；缓存未命中时回退到磁盘读取。
        /// </summary>
        private static dynamic GetParsedSettings()
        {
            if (!string.IsNullOrEmpty(CachedSettingsJson))
                return JsonConvert.DeserializeObject(CachedSettingsJson);

            var settingsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configs", "Settings.json");
            if (File.Exists(settingsPath))
            {
                var json = File.ReadAllText(settingsPath);
                return JsonConvert.DeserializeObject(json);
            }
            return null;
        }

        public SplashScreen()
        {
            InitializeComponent();
            InitializeSplashScreen();
        }

        private void InitializeSplashScreen()
        {
            // 设置窗口居中
            WindowStartupLocation = WindowStartupLocation.CenterScreen;

            // 设置版本号
            SetVersionText();

            // 加载启动图片并获取实际样式
            _actualSplashStyle = LoadSplashImageWithStyle();

            // 加载自定义文字位置
            ApplyCustomTextPosition();
        }

        private void ApplyCustomTextPosition()
        {
            // 只有自定义样式且有自定义图片时才应用文字位置设置
            if (_actualSplashStyle != 7)
            {
                return;
            }

            int textPosition = GetCurrentSplashTextPosition();

            switch (textPosition)
            {
                case 0: // 左下
                    LoadingText.HorizontalAlignment = HorizontalAlignment.Center;
                    LoadingText.Margin = new Thickness(-240, 200, 0, 0);
                    break;
                case 1: // 中下
                    LoadingText.HorizontalAlignment = HorizontalAlignment.Center;
                    LoadingText.Margin = new Thickness(0, 200, 0, 0);
                    break;
                case 2: // 右下
                    LoadingText.HorizontalAlignment = HorizontalAlignment.Center;
                    LoadingText.Margin = new Thickness(0, 200, -240, 0);
                    break;
                default: // 默认中下
                    LoadingText.HorizontalAlignment = HorizontalAlignment.Center;
                    LoadingText.Margin = new Thickness(0, 200, 0, 0);
                    break;
            }
        }

        private int GetCurrentSplashTextPosition()
        {
            try
            {
                dynamic obj = GetParsedSettings();
                if (obj?["appearance"]?["customSplashTextPosition"] != null)
                {
                    return (int)obj["appearance"]["customSplashTextPosition"];
                }
                return 1; // 默认中下
            }
            catch
            {
                return 1; // 默认中下
            }
        }

        public void CloseSplashScreen()
        {
            // 添加淡出动画
            var fadeOutAnimation = new DoubleAnimation
            {
                From = 1,
                To = 0,
                Duration = TimeSpan.FromMilliseconds(300),
                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
            };

            fadeOutAnimation.Completed += (s, e) =>
            {
                this.Close();
            };

            this.BeginAnimation(OpacityProperty, fadeOutAnimation);
        }

        /// <summary>
        /// 设置加载进度（0-100）
        /// </summary>
        /// <param name="progress">进度百分比</param>
        public void SetProgress(int progress)
        {
            // 启动阶段 UI 线程同步调用时，Dispatcher.Invoke 会自锁。
            // 通过 CheckAccess 守卫，UI 线程直接执行，避免等待自身调度。
            if (Dispatcher.CheckAccess())
            {
                ApplyProgress(progress);
            }
            else
            {
                Dispatcher.Invoke(() => ApplyProgress(progress));
            }
        }

        private void ApplyProgress(int progress)
        {
            // 设置进度条颜色
            SetProgressBarColor();

            // 获取进度条容器的实际宽度
            double containerWidth = ProgressBarBackground.ActualWidth;
            if (containerWidth <= 0)
            {
                // 如果ActualWidth为0，使用设计时宽度
                containerWidth = 530;
            }

            // 计算目标宽度
            double targetWidth = containerWidth * (progress / 100.0);

            // 创建Storyboard动画
            var storyboard = new Storyboard();

            // 创建宽度动画
            var widthAnimation = new DoubleAnimation
            {
                From = ProgressBarFill.Width,
                To = targetWidth,
                Duration = TimeSpan.FromMilliseconds(300),
                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
            };

            // 设置动画目标
            Storyboard.SetTarget(widthAnimation, ProgressBarFill);
            Storyboard.SetTargetProperty(widthAnimation, new PropertyPath(Border.WidthProperty));

            // 添加动画到Storyboard
            storyboard.Children.Add(widthAnimation);

            // 添加动画完成事件
            storyboard.Completed += (s, e) =>
            {
                // 确保最终值正确设置
                ProgressBarFill.Width = targetWidth;

                // 根据进度调整圆角
                if (progress >= 100)
                {
                    // 进度100%时，底部角都是圆角
                    ProgressBarFill.CornerRadius = new CornerRadius(0, 0, 7, 7);
                }
                else
                {
                    // 进度未满时，只有左侧是圆角
                    ProgressBarFill.CornerRadius = new CornerRadius(0, 0, 0, 7);
                }
            };

            // 开始动画
            storyboard.Begin();
        }

        /// <summary>
        /// 设置加载消息
        /// </summary>
        /// <param name="message">加载消息</param>
        public void SetLoadingMessage(string message)
        {
            // 使用实际选择的样式
            SetLoadingMessage(message, _actualSplashStyle);
        }

        public void SetLoadingMessage(string message, int actualSplashStyle)
        {
            // 启动阶段 UI 线程同步调用时，Dispatcher.Invoke 会自锁。
            // 通过 CheckAccess 守卫，UI 线程直接执行更新，避免等待自身调度。
            if (Dispatcher.CheckAccess())
            {
                ApplyLoadingMessage(message, actualSplashStyle);
            }
            else
            {
                Dispatcher.Invoke(() => ApplyLoadingMessage(message, actualSplashStyle));
            }
        }

        private void ApplyLoadingMessage(string message, int actualSplashStyle)
        {
            LoadingText.Text = message;

            // 根据实际启动动画样式调整加载文本样式
            if (actualSplashStyle == 6) // 马年限定
            {
                // 马年限定样式
                LoadingText.FontSize = 12;
                LoadingText.FontWeight = FontWeights.SemiBold;
                LoadingText.Foreground = Brushes.White;
                LoadingText.HorizontalAlignment = HorizontalAlignment.Center;
                LoadingText.Margin = new Thickness(0, 200, 140, 4);
            }
            else if (actualSplashStyle == 7) // 自定义图片
            {
                // 自定义图片样式 - 不改变 HorizontalAlignment，由 ApplyCustomTextPosition 决定
                LoadingText.FontSize = 12;
                LoadingText.FontWeight = FontWeights.SemiBold;
                LoadingText.Foreground = Brushes.White;
                // 不覆盖 HorizontalAlignment 和 Margin，保留 ApplyCustomTextPosition 的设置
            }
            else
            {
                // 默认样式
                LoadingText.FontSize = 18;
                LoadingText.FontWeight = FontWeights.SemiBold;
                LoadingText.Foreground = Brushes.White;
                LoadingText.HorizontalAlignment = HorizontalAlignment.Center;
                LoadingText.Margin = new Thickness(0, 200, 0, 0);
            }
        }

        /// <summary>
        /// 获取当前启动动画样式
        /// </summary>
        /// <returns>启动动画样式索引</returns>
        private int GetCurrentSplashStyle()
        {
            try
            {
                dynamic obj = GetParsedSettings();
                if (obj?["appearance"]?["splashScreenStyle"] != null)
                {
                    return (int)obj["appearance"]["splashScreenStyle"];
                }
                return 1; // 默认跟随四季
            }
            catch
            {
                return 1; // 默认跟随四季
            }
        }

        /// <summary>
        /// 设置版本号文本
        /// </summary>
        private void SetVersionText()
        {
            try
            {
                var version = Assembly.GetExecutingAssembly().GetName().Version;
                if (version != null)
                {
                    VersionTextBlock.Text = $"v{version.Major}.{version.Minor}.{version.Build}.{version.Revision}";
                    var informationalVersion = Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>();
                    if (informationalVersion != null)
                    {
                        string infoVersion = informationalVersion.InformationalVersion;
                        int lastDotIndex = infoVersion.LastIndexOf('.');
                        if (lastDotIndex >= 0 && lastDotIndex < infoVersion.Length - 7)
                        {
                            VersionTextBlock.Text += " (" + infoVersion.Substring(lastDotIndex + 1) + ")";
                        }
                    }
                }
                else
                {
                    VersionTextBlock.Text = "v1.7.18.10";
                }
            }
            catch
            {
                VersionTextBlock.Text = "v1.7.18.10";
            }
        }

        /// <summary>
        /// 加载启动图片
        /// </summary>
        private void LoadSplashImage()
        {
            try
            {
                string imagePath = GetSplashImagePath();
                if (!string.IsNullOrEmpty(imagePath))
                {
                    StartupImage.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri(imagePath));
                }
            }
            catch (Exception ex)
            {
                // 如果加载失败，使用默认图片
                System.Diagnostics.Debug.WriteLine($"加载启动图片失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 加载启动图片并返回实际样式
        /// </summary>
        /// <returns>实际选择的样式</returns>
        public int LoadSplashImageWithStyle()
        {
            try
            {
                int actualStyle;
                string imagePath = GetSplashImagePath(out actualStyle);
                if (!string.IsNullOrEmpty(imagePath))
                {
                    if (File.Exists(imagePath) || imagePath.StartsWith("pack://"))
                    {
                        StartupImage.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri(imagePath));
                    }
                }
                return actualStyle;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"加载启动图片失败: {ex.Message}");
                return GetActualStyle(1);
            }
        }

        /// <summary>
        /// 根据设置获取启动图片路径
        /// </summary>
        private string GetSplashImagePath()
        {
            try
            {
                // 从缓存读取设置
                dynamic obj = GetParsedSettings();
                int splashStyle = 1; // 默认跟随四季
                if (obj?["appearance"]?["splashScreenStyle"] != null)
                {
                    splashStyle = (int)obj["appearance"]["splashScreenStyle"];
                }

                // 根据样式选择图片
                string imageName = GetImageNameByStyle(splashStyle);
                return $"pack://application:,,,/Resources/Startup-animation/{imageName}";
            }
            catch
            {
                string imageName = GetImageNameByStyle(1);
                return $"pack://application:,,,/Resources/Startup-animation/{imageName}";
            }
        }

        /// <summary>
        /// 根据设置获取启动图片路径和实际样式
        /// </summary>
        /// <param name="actualStyle">返回实际选择的样式</param>
        /// <returns>图片路径</returns>
        private string GetSplashImagePath(out int actualStyle)
        {
            try
            {
                // 从缓存读取设置
                dynamic obj = GetParsedSettings();
                int splashStyle = 1;
                string customImagePath = string.Empty;

                if (obj?["appearance"]?["splashScreenStyle"] != null)
                {
                    splashStyle = (int)obj["appearance"]["splashScreenStyle"];
                }
                if (obj?["appearance"]?["customSplashImagePath"] != null)
                {
                    customImagePath = (string)obj["appearance"]["customSplashImagePath"];
                }

                if (splashStyle == 7 && !string.IsNullOrEmpty(customImagePath) && File.Exists(customImagePath))
                {
                    actualStyle = 7;
                    return customImagePath;
                }

                // 如果选择自定义样式但没有选择图片，使用随机样式
                if (splashStyle == 7)
                {
                    actualStyle = GetActualStyle(0); // 使用随机，此方法会返回解析后的实际样式(2-6)
                    string randomImageName = GetImageNameByStyle(actualStyle);
                    return $"pack://application:,,,/Resources/Startup-animation/{randomImageName}";
                }

                actualStyle = GetActualStyle(splashStyle);
                string imageName = GetImageNameByStyle(actualStyle);
                return $"pack://application:,,,/Resources/Startup-animation/{imageName}";
            }
            catch
            {
                actualStyle = GetActualStyle(1);
                string imageName = GetImageNameByStyle(1);
                return $"pack://application:,,,/Resources/Startup-animation/{imageName}";
            }
        }

        /// <summary>
        /// 获取实际样式
        /// </summary>
        /// <param name="style">设置中的样式</param>
        /// <returns>实际选择的样式</returns>
        private int GetActualStyle(int style)
        {
            switch (style)
            {
                case 0: // 随机
                    var random = new Random();
                    var randomStyles = new[] { 2, 3, 4, 5, 6 }; // 春季、夏季、秋季、冬季、马年限定
                    return randomStyles[random.Next(randomStyles.Length)];

                case 1: // 跟随四季
                    var month = DateTime.Now.Month;
                    if (month >= 2 && month <= 4) return 2; // 春季
                    if (month >= 5 && month <= 7) return 3; // 夏季
                    if (month >= 8 && month <= 10) return 4; // 秋季
                    return 5; // 冬季

                default:
                    return style;
            }
        }

        /// <summary>
        /// 根据样式获取图片名称
        /// </summary>
        private string GetImageNameByStyle(int style)
        {
            switch (style)
            {
                case 0: // 随机
                    var random = new Random();
                    var randomStyles = new[] { 2, 3, 4, 5, 6 }; // 春季、夏季、秋季、冬季、马年限定
                    return GetImageNameByStyle(randomStyles[random.Next(randomStyles.Length)]);

                case 1: // 跟随四季
                    var month = DateTime.Now.Month;
                    if (month >= 2 && month <= 4) return GetImageNameByStyle(2); // 春季
                    if (month >= 5 && month <= 7) return GetImageNameByStyle(3); // 夏季
                    if (month >= 8 && month <= 10) return GetImageNameByStyle(4); // 秋季
                    return GetImageNameByStyle(5); // 冬季

                case 2: // 春季
                    return "ICC Spring.png";
                case 3: // 夏季
                    return "ICC Summer.png";
                case 4: // 秋季
                    return "ICC Autumn.png";
                case 5: // 冬季
                    return "ICC Winter.png";
                case 6: // 马年限定
                    return "ICC Horse.png";
                default:// 默认返回
                    return "ICC Horse.png";
            }
        }

        /// <summary>
        /// 根据实际样式设置进度条颜色
        /// </summary>
        private void SetProgressBarColor()
        {
            Color progressColor;

            switch (_actualSplashStyle)
            {
                case 2: // 春季 - H=136, S=15, L=22
                    progressColor = HslToRgb(136, 15, 22);
                    break;
                case 3: // 夏季 - H=6, S=15, L=22
                    progressColor = HslToRgb(6, 15, 22);
                    break;
                case 4: // 秋季 - H=39, S=15, L=22
                    progressColor = HslToRgb(39, 15, 22);
                    break;
                case 5: // 冬季 - H=204, S=15, L=22
                    progressColor = HslToRgb(204, 15, 22);
                    break;
                case 6: // 马年限定 - 白色
                    progressColor = Colors.White;
                    break;
                case 7: // 自定义图片 - 白色
                    progressColor = Colors.White;
                    break;
                default: // 默认使用
                    progressColor = Colors.White;
                    break;
            }

            // 创建渐变画刷
            var gradientBrush = new LinearGradientBrush
            {
                StartPoint = new System.Windows.Point(0, 0),
                EndPoint = new System.Windows.Point(1, 0)
            };

            // 根据颜色类型设置渐变
            if (_actualSplashStyle == 6) // 马年限定使用白色渐变
            {
                gradientBrush.GradientStops.Add(new GradientStop(Colors.White, 0));
                gradientBrush.GradientStops.Add(new GradientStop(Color.FromArgb(200, 255, 255, 255), 0.5));
                gradientBrush.GradientStops.Add(new GradientStop(Color.FromArgb(150, 255, 255, 255), 1));
            }
            else // 其他样式使用HSL颜色的渐变
            {
                var lighterColor = Color.FromArgb(255,
                    (byte)Math.Min(255, progressColor.R + 30),
                    (byte)Math.Min(255, progressColor.G + 30),
                    (byte)Math.Min(255, progressColor.B + 30));
                var darkerColor = Color.FromArgb(255,
                    (byte)Math.Max(0, progressColor.R - 30),
                    (byte)Math.Max(0, progressColor.G - 30),
                    (byte)Math.Max(0, progressColor.B - 30));

                gradientBrush.GradientStops.Add(new GradientStop(lighterColor, 0));
                gradientBrush.GradientStops.Add(new GradientStop(progressColor, 0.5));
                gradientBrush.GradientStops.Add(new GradientStop(darkerColor, 1));
            }

            ProgressBarFill.Background = gradientBrush;
        }

        /// <summary>
        /// 将HSL颜色转换为RGB颜色
        /// </summary>
        /// <param name="h">色相 (0-360)</param>
        /// <param name="s">饱和度 (0-100)</param>
        /// <param name="l">亮度 (0-100)</param>
        /// <returns>RGB颜色</returns>
        private Color HslToRgb(double h, double s, double l)
        {
            // 将HSL值转换为0-1范围
            h = h / 360.0;
            s = s / 100.0;
            l = l / 100.0;

            double r, g, b;

            if (s == 0)
            {
                // 无饱和度，为灰度
                r = g = b = l;
            }
            else
            {
                double q = l < 0.5 ? l * (1 + s) : l + s - l * s;
                double p = 2 * l - q;

                r = HueToRgb(p, q, h + 1.0 / 3.0);
                g = HueToRgb(p, q, h);
                b = HueToRgb(p, q, h - 1.0 / 3.0);
            }

            return Color.FromRgb(
                (byte)Math.Round(r * 255),
                (byte)Math.Round(g * 255),
                (byte)Math.Round(b * 255)
            );
        }

        /// <summary>
        /// HSL颜色转换辅助方法
        /// </summary>
        private double HueToRgb(double p, double q, double t)
        {
            if (t < 0) t += 1;
            if (t > 1) t -= 1;
            if (t < 1.0 / 6.0) return p + (q - p) * 6 * t;
            if (t < 1.0 / 2.0) return q;
            if (t < 2.0 / 3.0) return p + (q - p) * (2.0 / 3.0 - t) * 6;
            return p;
        }
    }
}