// PRE-GENERATED (design session). AI 관리 창 code-behind (계정 모델 목록 동적 로드 포함).
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using DansoriEQ.App.Ai;
using DansoriEQ.Core.Ai;
using DansoriEQ.Core.Security;

namespace DansoriEQ.App;

public partial class AiManagerWindow : Wpf.Ui.Controls.FluentWindow
{
    private readonly OllamaService _ollama = new();
    private readonly ISecretStore _store;
    private List<string> _installedOllama = new();

    public AiManagerWindow(ISecretStore store)
    {
        InitializeComponent();
        _store = store;
        Loaded += OnLoaded;
    }

    private async void OnLoaded(object sender, RoutedEventArgs e)
    {
        var (free, drive) = DiskInfo.ModelDriveFree();
        DiskText.Text = $"현재 여유 공간: 약 {free:0.0} GB (드라이브 {drive})";

        if (!WingetInstaller.IsAvailable())
            WingetNote.Text = "⚠ winget이 감지되지 않습니다. 자동 설치가 제한될 수 있어요(수동 설치 필요).";

        var s = AppSettings.Load();
        ProviderCombo.SelectedIndex = s.AiProvider switch { "openai" => 1, "gemini" => 2, "ollama" => 3, _ => 0 };

        await RefreshOllamaAsync();
        await RefreshModelsAsync();
    }

    private static string ProviderId(int index) => index switch { 1 => "openai", 2 => "gemini", 3 => "ollama", _ => "claude" };

    private static string ProviderSecretKey(string provider) => provider switch
    {
        "openai" => ProviderKeys.OpenAi,
        "gemini" => ProviderKeys.Gemini,
        _ => ProviderKeys.Claude
    };

    private static string[] StaticModels(string provider) => provider switch
    {
        "openai" => new[] { "gpt-4o", "gpt-4o-mini" },
        "gemini" => new[] { "gemini-2.0-flash", "gemini-2.0-pro" },
        _ => new[] { "claude-sonnet-4-6", "claude-opus-4-8" }
    };

    private async void Provider_Changed(object sender, SelectionChangedEventArgs e) => await RefreshModelsAsync();
    private async void RefreshModels_Click(object sender, RoutedEventArgs e) => await RefreshModelsAsync();

    private async void TestConnection_Click(object sender, RoutedEventArgs e)
    {
        var prov = ProviderId(ProviderCombo.SelectedIndex);
        ModelStatus.Text = "연결 테스트 중…";
        if (prov == "ollama")
        {
            ModelStatus.Text = await _ollama.IsRunningAsync() ? "✓ Ollama 연결됨" : "✗ Ollama 미실행";
            return;
        }
        var key = _store.Load(ProviderSecretKey(prov));
        if (string.IsNullOrEmpty(key)) { ModelStatus.Text = "✗ API 키 없음(설정에서 입력)"; return; }
        var models = await CloudModelLister.ListAsync(prov, key);
        ModelStatus.Text = models.Count > 0 ? $"✓ 연결 성공 (모델 {models.Count}개)" : "✗ 연결 실패 (키/네트워크 확인)";
    }
    private void Model_Changed(object sender, SelectionChangedEventArgs e) => SaveSelection();

    /// <summary>Populate ModelCombo: local = downloaded models; cloud = account models (via key) with static fallback.</summary>
    private async Task RefreshModelsAsync()
    {
        var prov = ProviderId(ProviderCombo.SelectedIndex);

        if (prov == "ollama")
        {
            ModelCombo.ItemsSource = _installedOllama.Count > 0
                ? (IEnumerable<string>)_installedOllama.ToArray()
                : new[] { "(모델 없음 — 아래에서 다운로드)" };
            ModelStatus.Text = _installedOllama.Count > 0 ? $"로컬 모델 {_installedOllama.Count}개" : "다운로드 필요";
            RestoreSelection();
            SaveSelection();
            return;
        }

        var key = _store.Load(ProviderSecretKey(prov));
        if (string.IsNullOrEmpty(key))
        {
            ModelCombo.ItemsSource = StaticModels(prov);
            ModelStatus.Text = "API 키 없음 — 기본 목록(설정에서 키 입력)";
            RestoreSelection();
            SaveSelection();
            return;
        }

        ModelStatus.Text = "계정 모델 불러오는 중…";
        var models = await CloudModelLister.ListAsync(prov, key);
        if (models.Count > 0)
        {
            ModelCombo.ItemsSource = models;
            ModelStatus.Text = $"계정 모델 {models.Count}개";
        }
        else
        {
            ModelCombo.ItemsSource = StaticModels(prov);
            ModelStatus.Text = "불러오기 실패 — 기본 목록(직접 입력도 가능)";
        }
        RestoreSelection();
        SaveSelection();
    }

    private void RestoreSelection()
    {
        var saved = AppSettings.Load().AiModel;
        if (saved != null && ModelCombo.Items.Contains(saved)) ModelCombo.SelectedItem = saved;
        else if (ModelCombo.Items.Count > 0) ModelCombo.SelectedIndex = 0;
    }

    private void SaveSelection()
    {
        var s = AppSettings.Load();
        s.AiProvider = ProviderId(ProviderCombo.SelectedIndex);
        s.AiModel = string.IsNullOrWhiteSpace(ModelCombo.Text) ? ModelCombo.SelectedItem as string : ModelCombo.Text;
        s.Save();
    }

    private async Task RefreshOllamaAsync()
    {
        if (await _ollama.IsRunningAsync())
        {
            OllamaStatus.Text = "감지됨 (실행 중)";
            _installedOllama = await _ollama.ListModelsAsync();
        }
        else
        {
            OllamaStatus.Text = "미설치 / 미실행";
            _installedOllama = new();
        }
        InstalledList.ItemsSource = _installedOllama;
        if (ProviderId(ProviderCombo.SelectedIndex) == "ollama") await RefreshModelsAsync();
    }

    private async void Install_Click(object sender, RoutedEventArgs e)
    {
        if (sender is not FrameworkElement fe || fe.Tag is not string wingetId) return;
        if (!WingetInstaller.IsAvailable())
        {
            MessageBox.Show(this, "winget이 없어 자동 설치할 수 없습니다. 수동 설치가 필요합니다.", "안내");
            return;
        }
        if (sender is Button b) b.IsEnabled = false;
        var ok = await WingetInstaller.InstallAsync(wingetId);
        if (sender is Button b2) b2.IsEnabled = true;
        MessageBox.Show(this, ok ? "설치가 완료되었습니다." : "설치가 취소되었거나 실패했습니다.", "설치");
        await RefreshOllamaAsync();
    }

    private async void Pull_Click(object sender, RoutedEventArgs e)
    {
        var model = OllamaModelCombo.Text?.Trim();
        if (string.IsNullOrEmpty(model)) return;
        if (!await _ollama.IsRunningAsync())
        {
            MessageBox.Show(this, "Ollama가 실행 중이 아닙니다. 먼저 위에서 Ollama를 설치/실행하세요.", "안내");
            return;
        }
        PullBtn.IsEnabled = false;
        var progress = new Progress<double>(p => { PullProgress.Value = p * 100; PullStatus.Text = $"다운로드 {p * 100:0}%"; });
        try { await _ollama.PullModelAsync(model, progress); PullStatus.Text = "완료 ✓"; await RefreshOllamaAsync(); }
        catch (Exception ex) { PullStatus.Text = "실패: " + ex.Message; }
        finally { PullBtn.IsEnabled = true; }
    }

    private void Close_Click(object sender, RoutedEventArgs e) => Close();
}
