using System;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Autodesk.Navisworks.Api;

namespace NavisworksTransport.Utils
{
    /// <summary>
    /// 路径处理工具类 - 提供文件路径相关的通用方法
    /// </summary>
    public static class PathHelper
    {
        /// <summary>
        /// 获取插件目录路径
        /// </summary>
        public static string GetPluginDirectory()
        {
            return Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
                "Autodesk",
                "Navisworks Manage 2026",
                "plugins",
                "TransportPlugin"
            );
        }

        /// <summary>
        /// 获取截图目录路径
        /// </summary>
        public static string GetScreenshotDirectory()
        {
            return Path.Combine(GetPluginDirectory(), "screenshots");
        }

        /// <summary>
        /// 获取报告目录路径
        /// </summary>
        public static string GetReportDirectory()
        {
            return Path.Combine(GetPluginDirectory(), "reports");
        }

        /// <summary>
        /// 确保目录存在，不存在则创建
        /// </summary>
        public static void EnsureDirectoryExists(string directory)
        {
            if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }
        }

        /// <summary>
        /// 清理文件名中的非法字符
        /// </summary>
        /// <param name="fileName">原始文件名</param>
        /// <returns>清理后的文件名</returns>
        public static string SanitizeFileName(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
            {
                return "unnamed";
            }

            var invalidChars = Path.GetInvalidFileNameChars();
            var cleanedFileName = new string(fileName.Where(c => !invalidChars.Contains(c)).ToArray());
            
            // 如果清理后为空，返回默认名称
            return string.IsNullOrWhiteSpace(cleanedFileName) ? "unnamed" : cleanedFileName;
        }

        /// <summary>
        /// 生成带时间戳的文件名
        /// </summary>
        /// <param name="prefix">文件名前缀</param>
        /// <param name="extension">文件扩展名（不含点号）</param>
        /// <returns>带时间戳的文件名</returns>
        public static string GenerateTimestampedFileName(string prefix, string extension)
        {
            string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
            return $"{prefix}_{timestamp}.{extension}";
        }

        /// <summary>
        /// 生成碰撞检测报告文件名。
        /// 格式：碰撞检测报告_{路径名}_{时间戳}.{extension}
        /// </summary>
        public static string GenerateCollisionReportFileName(string pathName, string extension, DateTime? now = null)
        {
            string sanitizedName = SanitizeFileName(pathName ?? "未知路径");
            string normalizedExtension = string.IsNullOrWhiteSpace(extension)
                ? "html"
                : extension.Trim().TrimStart('.');
            string timestamp = (now ?? DateTime.Now).ToString("yyyyMMdd_HHmmss");
            return $"碰撞检测报告_{sanitizedName}_{timestamp}.{normalizedExtension}";
        }

        /// <summary>
        /// 生成复制路径名称。
        /// 如果原名称以 MMdd_HHmmss 结尾，则重建时间戳；否则仅添加“副本_”前缀。
        /// </summary>
        public static string BuildDuplicatedPathName(string originalName, DateTime? now = null)
        {
            var normalizedName = string.IsNullOrWhiteSpace(originalName) ? "路径" : originalName.Trim();
            var timestampPattern = new Regex(@"^(.*)_\d{4}_\d{6}$");
            var match = timestampPattern.Match(normalizedName);

            if (!match.Success)
            {
                return $"副本_{normalizedName}";
            }

            var baseName = match.Groups[1].Value;
            var timestamp = (now ?? DateTime.Now).ToString("MMdd_HHmmss");
            return $"副本_{baseName}_{timestamp}";
        }

        /// <summary>
        /// 计算从HTML文件到目标文件的相对路径
        /// </summary>
        /// <param name="fromPath">HTML文件路径</param>
        /// <param name="toPath">目标文件路径</param>
        /// <returns>相对路径（使用正斜杠）</returns>
        public static string GetRelativePath(string fromPath, string toPath)
        {
            try
            {
                var fromUri = new Uri(fromPath);
                var toUri = new Uri(toPath);
                var relativeUri = fromUri.MakeRelativeUri(toUri);
                return Uri.UnescapeDataString(relativeUri.ToString()).Replace('\\', '/');
            }
            catch (Exception ex)
            {
                LogManager.Error($"计算相对路径失败: {ex.Message}");
                return toPath; // 失败时返回绝对路径
            }
        }

        /// <summary>
        /// 将ImageFormat转换为文件扩展名
        /// </summary>
        public static string ImageFormatToExtension(ImageFormat format)
        {
            if (format.Equals(ImageFormat.Jpeg))
                return "jpg";
            if (format.Equals(ImageFormat.Png))
                return "png";
            if (format.Equals(ImageFormat.Bmp))
                return "bmp";
            return "png"; // 默认
        }

        /// <summary>
        /// 将文件扩展名转换为ImageFormat
        /// </summary>
        public static ImageFormat ExtensionToImageFormat(string extension)
        {
            if (string.IsNullOrEmpty(extension))
                return ImageFormat.Png;

            extension = extension.ToLowerInvariant();
            if (extension == ".jpg" || extension == ".jpeg")
                return ImageFormat.Jpeg;
            if (extension == ".png")
                return ImageFormat.Png;
            if (extension == ".bmp")
                return ImageFormat.Bmp;
            return ImageFormat.Png; // 默认
        }

        /// <summary>
        /// 生成场景截图（通用方法）
        /// </summary>
        /// <param name="sceneName">场景名称</param>
        /// <param name="width">图像宽度</param>
        /// <param name="height">图像高度</param>
        /// <param name="format">图像格式</param>
        /// <param name="prefix">文件名前缀</param>
        /// <returns>截图文件路径，失败返回null</returns>
        public static string GenerateSceneScreenshot(string sceneName, int width, int height, ImageFormat format, string prefix = "scene")
        {
            return GenerateSceneScreenshotInternal(GetScreenshotDirectory(), sceneName, width, height, format, prefix);
        }

        /// <summary>
        /// 生成场景截图到指定目录
        /// </summary>
        /// <param name="outputDirectory">输出目录</param>
        /// <param name="sceneName">场景名称</param>
        /// <param name="width">图像宽度</param>
        /// <param name="height">图像高度</param>
        /// <param name="format">图像格式</param>
        /// <param name="prefix">文件名前缀</param>
        /// <returns>截图文件路径，失败返回null</returns>
        public static string GenerateSceneScreenshotToDirectory(string outputDirectory, string sceneName, int width, int height, ImageFormat format, string prefix = "scene")
        {
            return GenerateSceneScreenshotInternal(outputDirectory, sceneName, width, height, format, prefix);
        }

        /// <summary>
        /// 生成场景截图内部实现
        /// </summary>
        private static string GenerateSceneScreenshotInternal(string outputDirectory, string sceneName, int width, int height, ImageFormat format, string prefix)
        {
            try
            {
                LogManager.Debug(string.Format("开始生成场景截图: {0}_{1}, 尺寸={2}x{3}, 目录={4}", prefix, sceneName, width, height, outputDirectory));

                // 生成文件名（SaveNavigationMapImage会确保目录存在）
                string extension = ImageFormatToExtension(format);
                string sanitizedName = SanitizeFileName(sceneName);
                string filename = GenerateTimestampedFileName(string.Format("{0}_{1}", prefix, sanitizedName), extension);
                string screenshotPath = Path.Combine(outputDirectory, filename);

                // 调用截图生成器（复用 NavigationMapGenerator）
                var generator = new Core.NavigationMapGenerator();
                var bitmap = generator.GenerateNavigationMapImage(
                    ImageGenerationStyle.ScenePlusOverlay,
                    width,
                    height,
                    false
                );

                // 保存截图（SaveNavigationMapImage内部会确保目录存在）
                generator.SaveNavigationMapImage(bitmap, screenshotPath, format);

                LogManager.Debug(string.Format("场景截图已生成: {0}", screenshotPath));
                return screenshotPath;
            }
            catch (Exception ex)
            {
                LogManager.Error(string.Format("生成场景截图失败: {0}", ex.Message), ex);
                return null;
            }
        }
    }
}
