using System.Collections.ObjectModel;
using System.ComponentModel;

namespace AxCopilot.ViewModels;

/// <summary>Phase 17-G: 단일 파일의 diff 정보를 담는 ViewModel.</summary>
public class FileDiffViewModel : INotifyPropertyChanged
{
    private string _filePath = "";
    private string _originalContent = "";
    private string _newContent = "";
    private bool _isSelected;
    private AxCopilot.Services.Agent.ToolRiskLevel _riskLevel;

    public string FilePath
    {
        get => _filePath;
        set { _filePath = value; OnPropertyChanged(); OnPropertyChanged(nameof(FileName)); }
    }

    public string FileName => System.IO.Path.GetFileName(FilePath);

    public string OriginalContent
    {
        get => _originalContent;
        set { _originalContent = value; OnPropertyChanged(); OnPropertyChanged(nameof(DiffSummary)); }
    }

    public string NewContent
    {
        get => _newContent;
        set { _newContent = value; OnPropertyChanged(); OnPropertyChanged(nameof(DiffSummary)); }
    }

    public bool IsSelected
    {
        get => _isSelected;
        set { _isSelected = value; OnPropertyChanged(); }
    }

    public AxCopilot.Services.Agent.ToolRiskLevel RiskLevel
    {
        get => _riskLevel;
        set { _riskLevel = value; OnPropertyChanged(); OnPropertyChanged(nameof(RiskLabel)); }
    }

    public string RiskLabel => AxCopilot.Services.Agent.ToolRiskMapper.GetRiskLabel(_riskLevel);

    /// <summary>변경 줄 수 요약.</summary>
    public string DiffSummary
    {
        get
        {
            var origLines = OriginalContent.Split('\n');
            var newLines = NewContent.Split('\n');
            var added = newLines.Length - origLines.Length;
            return added >= 0 ? $"+{added}줄" : $"{added}줄";
        }
    }

    public event PropertyChangedEventHandler? PropertyChanged;
    protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string? name = null)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}

/// <summary>Phase 17-G: 여러 파일의 diff를 관리하는 ViewModel (AgentDiffPanel용).</summary>
public class MultiFileDiffViewModel : INotifyPropertyChanged
{
    public ObservableCollection<FileDiffViewModel> Files { get; } = new();

    private FileDiffViewModel? _selectedFile;
    public FileDiffViewModel? SelectedFile
    {
        get => _selectedFile;
        set { _selectedFile = value; OnPropertyChanged(); }
    }

    private bool _isVisible;
    public bool IsVisible
    {
        get => _isVisible;
        set { _isVisible = value; OnPropertyChanged(); }
    }

    /// <summary>에이전트 세션 중 파일 변경을 추적하여 추가합니다.</summary>
    public void TrackFileChange(string filePath, string originalContent, string newContent, string toolName)
    {
        var existing = Files.FirstOrDefault(f =>
            string.Equals(f.FilePath, filePath, StringComparison.OrdinalIgnoreCase));

        if (existing != null)
        {
            existing.NewContent = newContent;
        }
        else
        {
            var vm = new FileDiffViewModel
            {
                FilePath = filePath,
                OriginalContent = originalContent,
                NewContent = newContent,
                RiskLevel = AxCopilot.Services.Agent.ToolRiskMapper.GetRisk(toolName),
                IsSelected = Files.Count == 0 // auto-select first
            };
            Files.Add(vm);
            if (Files.Count == 1) SelectedFile = vm;
        }

        IsVisible = Files.Count > 0;
    }

    /// <summary>세션 종료 시 diff 목록을 초기화합니다.</summary>
    public void Clear()
    {
        Files.Clear();
        SelectedFile = null;
        IsVisible = false;
    }

    /// <summary>선택된 파일 변경을 승인합니다 (파일을 실제로 수정하지는 않음 — 이미 적용됨).</summary>
    public void AcceptSelected()
    {
        if (SelectedFile != null)
            Files.Remove(SelectedFile);
        SelectedFile = Files.FirstOrDefault();
    }

    /// <summary>모든 변경 승인.</summary>
    public void AcceptAll() => Clear();

    public event PropertyChangedEventHandler? PropertyChanged;
    protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string? name = null)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
