using System.Diagnostics;
using System.Text.Json;

namespace LanMountainDesktop.Launcher.Services;

/// <summary>
    /// 灵活的主程序定位器
    /// </summary>
    internal sealed class FlexibleHostLocator
    {
        private readonly HostDiscoveryOptions _options;
        private readonly string _appRoot;
        private readonly DeploymentLocator _deploymentLocator;

        public FlexibleHostLocator(string appRoot, HostDiscoveryOptions? options = null)
        {
            _appRoot = appRoot;
            _options = options ?? new HostDiscoveryOptions();
            _deploymentLocator = new DeploymentLocator(appRoot);
        }

        /// <summary>
        /// 解析主程序可执行文件路径
        /// </summary>
        public string? ResolveHostExecutablePath()
        {
            var executable = GetExecutableName();
            var searchContext = new SearchContext
            {
                ExecutableName = executable,
                AppRoot = _appRoot,
                Options = _options
            };

            // ========== 第一阶段：标准路径查找（快速路径）==========
            
            // 1. 检查环境变量指定的路径（最高优先级 - 用于调试和特殊场景）
            var envPath = GetPathFromEnvironment();
            if (!string.IsNullOrWhiteSpace(envPath))
            {
                var validated = ValidateAndReturn(envPath, "environment variable");
                if (validated != null) return validated;
            }

            // 2. 使用 DeploymentLocator（ClassIsland 风格的简洁查询 - 优先）
            Console.WriteLine("[FlexibleHostLocator] Trying quick path: DeploymentLocator.FindCurrentDeploymentDirectory()");
            var deploymentDir = _deploymentLocator.FindCurrentDeploymentDirectory();
            if (!string.IsNullOrWhiteSpace(deploymentDir))
            {
                var deploymentExePath = Path.Combine(deploymentDir, executable);
                if (File.Exists(deploymentExePath))
                {
                    Console.WriteLine($"[FlexibleHostLocator] Quick path found: {deploymentExePath}");
                    return deploymentExePath;
                }
                Console.WriteLine($"[FlexibleHostLocator] Quick path found dir but no exe: {deploymentExePath}");
            }

            // 3. 快速路径失败，尝试旧的 SearchDeploymentDirectories 作为 fallback
            Console.WriteLine("[FlexibleHostLocator] Quick path failed, falling back to SearchDeploymentDirectories");
            var deploymentPath = SearchDeploymentDirectories(searchContext);
            if (!string.IsNullOrWhiteSpace(deploymentPath))
            {
                return deploymentPath;
            }

        // 4. 检查 Launcher 同级目录（便携模式）
        var portablePath = SearchPortableLocation(searchContext);
        if (!string.IsNullOrWhiteSpace(portablePath))
        {
            return portablePath;
        }

        // ========== 第二阶段：灵活查找（标准路径找不到时）==========
        
        // 5. 检查配置文件中的路径 - 用户自定义配置
        var configPath = GetPathFromConfigFile();
        if (!string.IsNullOrWhiteSpace(configPath))
        {
            var validated = ValidateAndReturn(configPath, "config file");
            if (validated != null) return validated;
        }

        // 5. 搜索附近目录（向上、向下各一层）
        var nearbyPath = SearchNearbyDirectories(searchContext);
        if (!string.IsNullOrWhiteSpace(nearbyPath))
        {
            return nearbyPath;
        }

        // 7. 开发模式：检查保存的自定义路径
        if (_options.PreferDevModeConfig && Views.ErrorWindow.CheckDevModeEnabled())
        {
            var savedPath = Views.ErrorWindow.GetSavedCustomHostPath();
            if (!string.IsNullOrWhiteSpace(savedPath))
            {
                var validated = ValidateAndReturn(savedPath, "saved dev mode path");
                if (validated != null) return validated;
            }
        }

        // 8. 搜索标准开发路径
        var devPath = SearchDevelopmentPaths(searchContext);
        if (!string.IsNullOrWhiteSpace(devPath))
        {
            return devPath;
        }

        // 9. 搜索额外的配置路径
        var additionalPath = SearchAdditionalPaths(searchContext);
        if (!string.IsNullOrWhiteSpace(additionalPath))
        {
            return additionalPath;
        }

        // 10. 递归搜索（如果启用）
        if (_options.RecursiveSearch)
        {
            var recursivePath = SearchRecursively(searchContext);
            if (!string.IsNullOrWhiteSpace(recursivePath))
            {
                return recursivePath;
            }
        }

        return null;
    }

    /// <summary>
    /// 从环境变量获取路径
    /// </summary>
    private string? GetPathFromEnvironment()
    {
        if (string.IsNullOrWhiteSpace(_options.CustomPathEnvVar))
        {
            return null;
        }

        var path = Environment.GetEnvironmentVariable(_options.CustomPathEnvVar);
        return path;
    }

    /// <summary>
    /// 从配置文件获取路径
    /// </summary>
    private string? GetPathFromConfigFile()
    {
        if (string.IsNullOrWhiteSpace(_options.ConfigFileName))
        {
            return null;
        }

        var configPath = Path.Combine(_appRoot, _options.ConfigFileName);
        if (!File.Exists(configPath))
        {
            return null;
        }

        try
        {
            var json = File.ReadAllText(configPath);
            var config = JsonSerializer.Deserialize(json, AppJsonContext.Default.HostDiscoveryConfig);
            if (config?.HostPath != null && File.Exists(config.HostPath))
            {
                return config.HostPath;
            }
        }
        catch
        {
            // 忽略配置文件读取错误
        }

        return null;
    }

    /// <summary>
    /// 搜索部署目录
    /// </summary>
    private string? SearchDeploymentDirectories(SearchContext context)
    {
        if (!Directory.Exists(_appRoot))
        {
            return null;
        }

        try
        {
            // 查找 app-* 目录
            var appDirs = Directory.GetDirectories(_appRoot, "app-*", SearchOption.TopDirectoryOnly)
                .Where(dir => !File.Exists(Path.Combine(dir, ".destroy")))
                .Where(dir => !File.Exists(Path.Combine(dir, ".partial")))
                .ToList();

            // 优先选择带 .current 标记的
            var currentMarked = appDirs
                .Where(dir => File.Exists(Path.Combine(dir, ".current")))
                .Select(dir => Path.Combine(dir, context.ExecutableName))
                .FirstOrDefault(File.Exists);

            if (currentMarked != null)
            {
                return currentMarked;
            }

            // 选择版本号最高的
            var latest = appDirs
                .Select(dir => new
                {
                    Dir = dir,
                    Version = ParseVersionFromDirectoryName(dir)
                })
                .OrderByDescending(x => x.Version)
                .Select(x => Path.Combine(x.Dir, context.ExecutableName))
                .FirstOrDefault(File.Exists);

            return latest;
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// 搜索便携模式位置（Launcher 同级目录）
    /// </summary>
    private string? SearchPortableLocation(SearchContext context)
    {
        try
        {
            var launcherDir = AppContext.BaseDirectory;
            var portablePath = Path.Combine(launcherDir, context.ExecutableName);
            
            if (File.Exists(portablePath))
            {
                return portablePath;
            }
        }
        catch
        {
            // 忽略错误
        }
        return null;
    }

    /// <summary>
    /// 搜索附近目录（灵活查找，适用于各种部署场景）
    /// </summary>
    private string? SearchNearbyDirectories(SearchContext context)
    {
        try
        {
            var searchDirs = new List<string>();
            
            // Launcher 所在目录
            var launcherDir = AppContext.BaseDirectory;
            searchDirs.Add(launcherDir);
            
            // 上级目录
            var parentDir = Path.GetFullPath(Path.Combine(launcherDir, ".."));
            if (Directory.Exists(parentDir))
            {
                searchDirs.Add(parentDir);
            }
            
            // 上上级目录
            var grandparentDir = Path.GetFullPath(Path.Combine(launcherDir, "..", ".."));
            if (Directory.Exists(grandparentDir))
            {
                searchDirs.Add(grandparentDir);
            }
            
            // AppRoot 及其上级
            if (!string.IsNullOrWhiteSpace(_appRoot) && Directory.Exists(_appRoot))
            {
                searchDirs.Add(_appRoot);
                var appParent = Path.GetFullPath(Path.Combine(_appRoot, ".."));
                if (Directory.Exists(appParent))
                {
                    searchDirs.Add(appParent);
                }
            }
            
            // 去重后搜索
            foreach (var dir in searchDirs.Distinct(StringComparer.OrdinalIgnoreCase))
            {
                // 直接搜索
                var directPath = Path.Combine(dir, context.ExecutableName);
                if (File.Exists(directPath))
                {
                    return directPath;
                }
                
                // 搜索子目录（一层）
                if (Directory.Exists(dir))
                {
                    foreach (var subDir in Directory.GetDirectories(dir))
                    {
                        var subPath = Path.Combine(subDir, context.ExecutableName);
                        if (File.Exists(subPath))
                        {
                            return subPath;
                        }
                    }
                }
            }
        }
        catch
        {
            // 忽略搜索错误
        }
        
        return null;
    }

    /// <summary>
    /// 搜索开发路径
    /// </summary>
    private string? SearchDevelopmentPaths(SearchContext context)
    {
        // 获取 Launcher 所在目录
        var launcherDir = AppContext.BaseDirectory;

        // 动态构建可能的开发路径（支持不同的项目结构）
        var possiblePaths = new List<string>();

        // 从解决方案根目录搜索（支持不同的解决方案结构）
        var solutionRoot = FindSolutionRoot(launcherDir);
        if (!string.IsNullOrWhiteSpace(solutionRoot))
        {
            // 搜索所有可能的 bin 目录
            possiblePaths.AddRange(SearchBinDirectories(solutionRoot, context.ExecutableName));
        }

        // 添加硬编码的备用路径
        possiblePaths.AddRange(new[]
        {
            Path.Combine(launcherDir, "..", "..", "LanMountainDesktop", "bin", "Debug", "net10.0", context.ExecutableName),
            Path.Combine(launcherDir, "..", "..", "LanMountainDesktop", "bin", "Release", "net10.0", context.ExecutableName),
            Path.Combine(launcherDir, "..", "LanMountainDesktop", "bin", "Debug", "net10.0", context.ExecutableName),
            Path.Combine(launcherDir, "..", "LanMountainDesktop", "bin", "Release", "net10.0", context.ExecutableName),
        });

        foreach (var path in possiblePaths.Select(Path.GetFullPath).Distinct())
        {
            if (File.Exists(path))
            {
                return path;
            }
        }

        return null;
    }

    /// <summary>
    /// 搜索额外的配置路径
    /// </summary>
    private string? SearchAdditionalPaths(SearchContext context)
    {
        if (_options.AdditionalSearchPaths == null || !_options.AdditionalSearchPaths.Any())
        {
            return null;
        }

        foreach (var pattern in _options.AdditionalSearchPaths)
        {
            try
            {
                // 替换变量
                var expandedPattern = ExpandVariables(pattern);

                // 支持通配符
                if (expandedPattern.Contains('*') || expandedPattern.Contains('?'))
                {
                    var dir = Path.GetDirectoryName(expandedPattern) ?? _appRoot;
                    var filePattern = Path.GetFileName(expandedPattern);

                    if (Directory.Exists(dir))
                    {
                        var matches = Directory.GetFiles(dir, filePattern, SearchOption.TopDirectoryOnly);
                        var validMatch = matches.FirstOrDefault(File.Exists);
                        if (validMatch != null)
                        {
                            return validMatch;
                        }
                    }
                }
                else if (File.Exists(expandedPattern))
                {
                    return expandedPattern;
                }
            }
            catch
            {
                // 忽略搜索错误
            }
        }

        return null;
    }

    /// <summary>
    /// 递归搜索
    /// </summary>
    private string? SearchRecursively(SearchContext context)
    {
        try
        {
            var searchDirs = new[] { _appRoot, Path.GetFullPath(Path.Combine(_appRoot, "..")) };

            foreach (var searchDir in searchDirs.Where(Directory.Exists))
            {
                var result = SearchDirectoryRecursively(searchDir, context.ExecutableName, 0);
                if (result != null)
                {
                    return result;
                }
            }
        }
        catch
        {
            // 忽略递归搜索错误
        }

        return null;
    }

    /// <summary>
    /// 递归搜索目录
    /// </summary>
    private string? SearchDirectoryRecursively(string dir, string executableName, int depth)
    {
        if (depth > _options.MaxRecursionDepth)
        {
            return null;
        }

        try
        {
            // 检查当前目录
            var directPath = Path.Combine(dir, executableName);
            if (File.Exists(directPath))
            {
                return directPath;
            }

            // 检查子目录
            foreach (var subDir in Directory.GetDirectories(dir))
            {
                // 跳过某些目录
                var dirName = Path.GetFileName(subDir).ToLowerInvariant();
                if (dirName is ".git" or "node_modules" or ".vs" or "obj" or ".launcher")
                {
                    continue;
                }

                var result = SearchDirectoryRecursively(subDir, executableName, depth + 1);
                if (result != null)
                {
                    return result;
                }
            }
        }
        catch
        {
            // 忽略访问错误
        }

        return null;
    }

    /// <summary>
    /// 查找解决方案根目录
    /// </summary>
    private string? FindSolutionRoot(string startDir)
    {
        var current = new DirectoryInfo(startDir);
        while (current != null)
        {
            // 查找 .sln 文件
            if (current.GetFiles("*.sln").Any())
            {
                return current.FullName;
            }

            // 查找 .git 目录作为备选
            if (current.GetDirectories(".git").Any())
            {
                return current.FullName;
            }

            current = current.Parent;
        }

        return null;
    }

    /// <summary>
    /// 搜索 bin 目录
    /// </summary>
    private IEnumerable<string> SearchBinDirectories(string root, string executableName)
    {
        var results = new List<string>();

        try
        {
            // 查找所有 bin 目录
            var binDirs = Directory.GetDirectories(root, "bin", SearchOption.AllDirectories);

            foreach (var binDir in binDirs)
            {
                // 检查 Debug 和 Release 子目录
                var configDirs = new[] { "Debug", "Release" };
                foreach (var config in configDirs)
                {
                    var configPath = Path.Combine(binDir, config);
                    if (Directory.Exists(configPath))
                    {
                        // 检查所有 net* 子目录
                        var frameworkDirs = Directory.GetDirectories(configPath, "net*");
                        foreach (var fwDir in frameworkDirs)
                        {
                            var exePath = Path.Combine(fwDir, executableName);
                            if (File.Exists(exePath))
                            {
                                results.Add(exePath);
                            }
                        }
                    }
                }
            }
        }
        catch
        {
            // 忽略搜索错误
        }

        return results;
    }

    /// <summary>
    /// 验证路径并返回
    /// </summary>
    private string? ValidateAndReturn(string path, string source)
    {
        if (File.Exists(path))
        {
            Debug.WriteLine($"Found host executable from {source}: {path}");
            return path;
        }

        // 尝试添加 .exe（Windows）
        if (OperatingSystem.IsWindows() && !path.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
        {
            var withExe = path + ".exe";
            if (File.Exists(withExe))
            {
                Debug.WriteLine($"Found host executable from {source}: {withExe}");
                return withExe;
            }
        }

        if (string.Equals(source, "saved dev mode path", StringComparison.OrdinalIgnoreCase))
        {
            Logger.Warn($"Saved launcher debug host path is invalid; continuing host discovery. Path='{path}'.");
        }

        return null;
    }

    /// <summary>
    /// 获取可执行文件名
    /// </summary>
    private string GetExecutableName()
    {
        var name = _options.ExecutableName;
        if (OperatingSystem.IsWindows() && !name.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
        {
            name += ".exe";
        }
        return name;
    }

    /// <summary>
    /// 展开路径变量
    /// </summary>
    private string ExpandVariables(string path)
    {
        return path
            .Replace("${AppRoot}", _appRoot)
            .Replace("${BaseDirectory}", AppContext.BaseDirectory)
            .Replace("${UserProfile}", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile))
            .Replace("${LocalAppData}", Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
    }

    /// <summary>
    /// 从目录名解析版本
    /// </summary>
    private static Version ParseVersionFromDirectoryName(string path)
    {
        var fileName = Path.GetFileName(path);
        if (string.IsNullOrWhiteSpace(fileName))
        {
            return new Version(0, 0, 0);
        }

        var segments = fileName.Split('-');
        if (segments.Length < 2)
        {
            return new Version(0, 0, 0);
        }

        return Version.TryParse(segments[1], out var version) ? version : new Version(0, 0, 0);
    }

    /// <summary>
    /// 搜索上下文
    /// </summary>
    private class SearchContext
    {
        public required string ExecutableName { get; set; }
        public required string AppRoot { get; set; }
        public required HostDiscoveryOptions Options { get; set; }
    }
}

/// <summary>
/// 发现配置文件
/// </summary>
internal class HostDiscoveryConfig
{
    public string? HostPath { get; set; }
    public List<string>? AdditionalPaths { get; set; }
}
