using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
using AxCopilot.Services;

namespace AxCopilot.Views;

/// <summary>
/// Phase L3-9: 런처 하단 미니 위젯 바 로직.
/// 타이머로 1초마다 ViewModel 갱신 + 서버 상태 dot 색상 직접 업데이트.
/// </summary>
public partial class LauncherWindow
{
    private DispatcherTimer? _widgetTimer;

    private static readonly SolidColorBrush _dotOnline  = new(Color.FromRgb(0x10, 0xB9, 0x81));
    private static readonly SolidColorBrush _dotOffline = new(Color.FromRgb(0x9E, 0x9E, 0x9E));

    /// <summary>LauncherWindow.xaml.cs의 Show()에서 최초 1회 호출 — IsVisibleChanged로 자동 관리.</summary>
    internal void InitWidgets()
    {
        IsVisibleChanged -= OnLauncherVisibleChanged;
        IsVisibleChanged += OnLauncherVisibleChanged;
    }

    private void OnLauncherVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue) StartWidgetUpdates();
        else                  StopWidgetUpdates();
    }

    /// <summary>런처가 표시될 때 위젯 업데이트 시작.</summary>
    internal void StartWidgetUpdates()
    {
        var settings = CurrentApp?.SettingsService?.Settings;

        // 서비스 시작
        PerformanceMonitorService.Instance.StartPolling();
        ServerStatusService.Instance.Start(settings);
        PomodoroService.Instance.StateChanged -= OnPomoStateChanged;
        PomodoroService.Instance.StateChanged += OnPomoStateChanged;
        ServerStatusService.Instance.StatusChanged -= OnServerStatusChanged;
        ServerStatusService.Instance.StatusChanged += OnServerStatusChanged;

        // 메모 건수 즉시 갱신 (최초 1회)
        _vm.UpdateWidgets();
        UpdateServerDots();
        UpdateBatteryWidget();
        // 날씨: 사외 모드에서만 비동기 갱신
        _ = RefreshWeatherAsync();

        // 1초 타이머
        if (_widgetTimer == null)
        {
            _widgetTimer = new DispatcherTimer(DispatcherPriority.Background)
            {
                Interval = TimeSpan.FromSeconds(1)
            };
            _widgetTimer.Tick += (_, _) =>
            {
                _vm.UpdateWidgets();
                UpdateServerDots();

                // 배터리: 30초마다 갱신
                if (_vm.Widget_PerfText.Length > 0 && _widgetBatteryTick++ % 30 == 0)
                    UpdateBatteryWidget();

                // 날씨: 2분마다 서비스 쪽 캐시를 체크 (실제 API 호출은 30분마다)
                if (_widgetWeatherTick++ % 120 == 0)
                    _ = RefreshWeatherAsync();
            };
        }
        _widgetTimer.Start();

        // 뽀모도로 실행 중이면 위젯 색상 강조
        UpdatePomoWidgetStyle();
    }

    private int _widgetBatteryTick;
    private int _widgetWeatherTick;

    /// <summary>런처가 숨겨질 때 타이머 중지 (뽀모도로는 계속 실행).</summary>
    internal void StopWidgetUpdates()
    {
        _widgetTimer?.Stop();
        PerformanceMonitorService.Instance.StopPolling();
        PomodoroService.Instance.StateChanged -= OnPomoStateChanged;
        ServerStatusService.Instance.StatusChanged -= OnServerStatusChanged;
    }

    // ─── 이벤트 핸들러 ──────────────────────────────────────────────────────

    private void OnPomoStateChanged(object? sender, EventArgs e)
    {
        Dispatcher.InvokeAsync(() =>
        {
            _vm.UpdateWidgets();
            UpdatePomoWidgetStyle();
        });
    }

    private void OnServerStatusChanged(object? sender, EventArgs e)
    {
        Dispatcher.InvokeAsync(UpdateServerDots);
    }

    // ─── UI 업데이트 ────────────────────────────────────────────────────────

    private void UpdateServerDots()
    {
        var srv = ServerStatusService.Instance;
        if (OllamaStatusDot != null)
            OllamaStatusDot.Fill = srv.OllamaOnline ? _dotOnline : _dotOffline;
        if (LlmStatusDot != null)
            LlmStatusDot.Fill = srv.LlmOnline ? _dotOnline : _dotOffline;
        if (McpStatusDot != null)
            McpStatusDot.Fill = srv.McpOnline ? _dotOnline : _dotOffline;
    }

    private void UpdatePomoWidgetStyle()
    {
        if (WgtPomo == null) return;
        var running = PomodoroService.Instance.IsRunning;
        WgtPomo.Background = running
            ? new SolidColorBrush(Color.FromArgb(0x1E, 0xF5, 0x9E, 0x0B))
            : new SolidColorBrush(Color.FromArgb(0x0D, 0xF5, 0x9E, 0x0B));
    }

    // ─── 위젯 클릭 핸들러 ───────────────────────────────────────────────────

    private void WgtPerf_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        _vm.InputText = "info ";
        InputBox?.Focus();
    }

    private void WgtPomo_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        _vm.InputText = "pomo ";
        InputBox?.Focus();
    }

    private void WgtNote_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        _vm.InputText = "note ";
        InputBox?.Focus();
    }

    private void WgtServer_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        // 서버 상태 강제 새로고침
        var settings = CurrentApp?.SettingsService?.Settings;
        ServerStatusService.Instance.Refresh(settings);
        _vm.InputText = "port";
        InputBox?.Focus();
    }

    private void WgtWeather_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        var internalMode = CurrentApp?.SettingsService?.Settings.InternalModeEnabled ?? true;
        if (!internalMode)
        {
            // 사외 모드: 브라우저에서 날씨 페이지 열기
            try
            {
                System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(
                    "https://wttr.in") { UseShellExecute = true });
            }
            catch (Exception ex)
            {
                LogService.Warn($"날씨 링크 열기 실패: {ex.Message}");
            }
        }
        else
        {
            // 사내 모드: 날씨 캐시 무효화 후 재시도 (사외 모드 전환 시 즉시 갱신되도록)
            WeatherWidgetService.Invalidate();
            _ = RefreshWeatherAsync();
        }
    }

    private void WgtCal_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        // Windows 달력 앱 열기
        try
        {
            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(
                "ms-clock:") { UseShellExecute = true });
        }
        catch
        {
            try
            {
                System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(
                    "outlookcal:") { UseShellExecute = true });
            }
            catch (Exception ex)
            {
                LogService.Warn($"달력 앱 열기 실패: {ex.Message}");
            }
        }
    }

    private void WgtBattery_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        // 전원 및 절전 설정 열기
        try
        {
            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(
                "ms-settings:powersleep") { UseShellExecute = true });
        }
        catch (Exception ex)
        {
            LogService.Warn($"전원 설정 열기 실패: {ex.Message}");
        }
    }

    // ─── 배터리 상태 갱신 ──────────────────────────────────────────────────────

    private void UpdateBatteryWidget()
    {
        try
        {
            var ps  = System.Windows.Forms.SystemInformation.PowerStatus;
            var pct = ps.BatteryLifePercent; // 0.0~1.0, unknown = 255f

            if (pct > 1.0f || pct < 0f)
            {
                // 배터리 없는 장치 (데스크톱 등) → 위젯 숨김
                _vm.Widget_BatteryVisible = false;
                return;
            }

            _vm.Widget_BatteryVisible = true;
            var pctInt   = (int)(pct * 100);
            var charging = ps.PowerLineStatus == System.Windows.Forms.PowerLineStatus.Online;

            _vm.Widget_BatteryText = charging ? $"{pctInt}% ⚡" : $"{pctInt}%";
            _vm.Widget_BatteryIcon = charging  ? "\uE83E"   // BatteryCharging
                                   : pctInt >= 85 ? "\uEBA7"  // Battery 8 (Full)
                                   : pctInt >= 70 ? "\uEBA5"  // Battery 6
                                   : pctInt >= 50 ? "\uEBA3"  // Battery 4
                                   : pctInt >= 25 ? "\uEBA1"  // Battery 2
                                   : "\uEBA0";               // Battery 1 (Low)
        }
        catch (Exception ex)
        {
            LogService.Warn($"배터리 위젯 갱신 실패: {ex.Message}");
            _vm.Widget_BatteryVisible = false;
        }
    }

    // ─── 날씨 비동기 갱신 ─────────────────────────────────────────────────────

    private async Task RefreshWeatherAsync()
    {
        var internalMode = CurrentApp?.SettingsService?.Settings.InternalModeEnabled ?? true;
        await WeatherWidgetService.RefreshAsync(internalMode);
        // UI 스레드에서 바인딩 프로퍼티 갱신
        await Dispatcher.InvokeAsync(() =>
        {
            _vm.Widget_WeatherText = WeatherWidgetService.CachedText;
        });
    }
}
