using System.Net.NetworkInformation;
using System.Net.Sockets;
using AxCopilot.SDK;
using AxCopilot.Themes;

namespace AxCopilot.Handlers;

public partial class SystemInfoHandler
{
    // ─── 헬퍼 ────────────────────────────────────────────────────────────────

    private static LauncherItem MakeItem(string title, string subtitle, string? copyValue, string symbol) =>
        new(title, subtitle, null,
            copyValue != null ? new InfoAction("copy", copyValue) : null,
            Symbol: symbol);

    private static string? GetLocalIpAddress()
    {
        try
        {
            foreach (var iface in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (iface.OperationalStatus != OperationalStatus.Up) continue;
                if (iface.NetworkInterfaceType is NetworkInterfaceType.Loopback
                                               or NetworkInterfaceType.Tunnel) continue;

                foreach (var addr in iface.GetIPProperties().UnicastAddresses)
                {
                    if (addr.Address.AddressFamily == AddressFamily.InterNetwork)
                        return addr.Address.ToString();
                }
            }
        }
        catch (Exception) { /* 무시 */ }
        return null;
    }

    private static string? GetDefaultGateway()
    {
        try
        {
            foreach (var iface in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (iface.OperationalStatus != OperationalStatus.Up) continue;
                var gw = iface.GetIPProperties().GatewayAddresses
                    .FirstOrDefault(g => g.Address.AddressFamily == AddressFamily.InterNetwork);
                if (gw != null) return gw.Address.ToString();
            }
        }
        catch (Exception) { /* 무시 */ }
        return null;
    }

    private static LauncherItem? GetBatteryItem()
    {
        try
        {
            var status = System.Windows.Forms.SystemInformation.PowerStatus;
            var chargeLevel = status.BatteryLifePercent;

            if (chargeLevel < 0) // 배터리 없는 데스크톱
                return new LauncherItem("배터리: 해당 없음", "데스크톱 PC 또는 항상 연결됨  ·  Enter로 전원 설정 열기", null,
                    new InfoAction("ms_settings", "ms-settings:powersleep"), Symbol: Symbols.Battery);

            var pct = (int)(chargeLevel * 100);
            var charging = status.PowerLineStatus == System.Windows.Forms.PowerLineStatus.Online;
            var timeLeft = status.BatteryLifeRemaining >= 0
                ? $"  ·  잔여: {FormatUptime(TimeSpan.FromSeconds(status.BatteryLifeRemaining))}"
                : "";

            var symbol = charging ? Symbols.BatteryCharging
                       : pct > 50 ? Symbols.Battery
                       : Symbols.BatteryLow;

            return new LauncherItem(
                $"배터리: {pct}%{(charging ? "  ⚡ 충전 중" : "")}",
                $"전원: {(charging ? "AC 연결됨" : "배터리 사용 중")}{timeLeft}  ·  Enter로 전원 설정 열기",
                null,
                new InfoAction("ms_settings", "ms-settings:powersleep"),
                Symbol: symbol);
        }
        catch (Exception) { return null; }
    }

    private static LauncherItem? GetVolumeItem()
    {
        try
        {
            if (waveOutGetVolume(IntPtr.Zero, out uint vol) == 0)
            {
                // 왼쪽 채널 0~0xFFFF → 0~100 변환
                var left  = (int)((vol & 0xFFFF) / 655.35);
                var right = (int)(((vol >> 16) & 0xFFFF) / 655.35);
                var avg   = (left + right) / 2;

                return new LauncherItem(
                    $"볼륨: {avg}%",
                    $"L: {left}%  ·  R: {right}%  ·  Enter로 사운드 설정 열기",
                    null,
                    new InfoAction("ms_settings", "ms-settings:sound"),
                    Symbol: avg == 0 ? Symbols.VolumeMute : Symbols.VolumeUp);
            }
        }
        catch (Exception) { /* 무시 */ }
        return null;
    }

    private static string GetOsVersion()
    {
        try
        {
            // registry에서 실제 Windows 버전 읽기
            using var key = Microsoft.Win32.Registry.LocalMachine
                .OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
            if (key != null)
            {
                var name    = key.GetValue("ProductName")    as string ?? "Windows";
                var build   = key.GetValue("CurrentBuildNumber") as string ?? "";
                var ubr     = key.GetValue("UBR");
                return ubr != null ? $"{name} (빌드 {build}.{ubr})" : $"{name} (빌드 {build})";
            }
        }
        catch (Exception) { /* 무시 */ }
        return Environment.OSVersion.ToString();
    }

    private static string GetProcessorName()
    {
        try
        {
            using var key = Microsoft.Win32.Registry.LocalMachine
                .OpenSubKey(@"HARDWARE\DESCRIPTION\System\CentralProcessor\0");
            return key?.GetValue("ProcessorNameString") as string ?? "";
        }
        catch (Exception) { return ""; }
    }

    private static string FormatUptime(TimeSpan t)
    {
        if (t.TotalDays >= 1)
            return $"{(int)t.TotalDays}일 {t.Hours}시간 {t.Minutes}분";
        if (t.TotalHours >= 1)
            return $"{t.Hours}시간 {t.Minutes}분";
        return $"{t.Minutes}분 {t.Seconds}초";
    }
}

/// <summary>
/// * 단축키로 시스템 정보를 빠르게 조회합니다. SystemInfoHandler에 완전히 위임합니다.
/// </summary>
public class StarInfoHandler : IActionHandler
{
    private readonly SystemInfoHandler _inner = new();

    public string? Prefix => "*";

    public PluginMetadata Metadata => new(
        "StarInfo",
        "시스템 정보 빠른 조회 — * 단축키 (info와 동일)",
        "1.0",
        "AX");

    public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
        => _inner.GetItemsAsync(query, ct);

    public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
        => _inner.ExecuteAsync(item, ct);
}
