using Microsoft.CodeAnalysis;
using RobotNet.Script.Shares;

namespace RobotNet.WebApp.Scripts.Models;

public class ScriptFileModel(DocumentId id, ScriptFile model, int level, ScriptFolderModel? parrent) : IHierachyItemModel
{
    public int Level { get; } = level;
    public ScriptFile Model { get; private set; } = model;
    public ScriptFolderModel? Parrent { get; } = parrent;
    public string Name => Model.Name;
    public string Code => Model.Code;
    public string Path => System.IO.Path.Combine(Parrent?.Path ?? "", Model.Name);

    public DocumentId Id { get; } = id;
    public bool IsModified { get; private set; }
    public int WarningCount { get; private set; }
    public int ErrorCount { get; private set; }
    public string EditCode { get; private set; } = model.Code;

    public IEnumerable<Diagnostic> Diagnostics { get; private set; } = [];

    public event Action? OnModified;
    public event Action? OnNameChanged;
    public event Action<int, int>? OnDiagnosticsChanged;
    public void ChangeCode(string code)
    {
        EditCode = code;
        if (IsModified)
        {
            if (EditCode == Code)
            {
                IsModified = false;
                OnModified?.Invoke();
            }
        }
        else
        {
            if (EditCode != Code)
            {
                IsModified = true;
                OnModified?.Invoke();
            }
        }
    }

    public void Saved()
    {
        if (!IsModified || EditCode == Code) return;

        Model = new ScriptFile(Name, EditCode);
        IsModified = false;
        OnModified?.Invoke();
    }

    public void Rename(string newName)
    {
        if (string.IsNullOrEmpty(newName)) throw new ArgumentNullException("Tên file không được để trống");

        if (Name == newName) return;

        Model = new ScriptFile(newName, Code);
        OnNameChanged?.Invoke();
    }

    public void SetDiagnostics(IEnumerable<Diagnostic> diagnostics)
    {
        Diagnostics = diagnostics;
        var warning = Diagnostics.Count(d => d.Severity == DiagnosticSeverity.Warning);
        var error = Diagnostics.Count(d => d.Severity == DiagnosticSeverity.Error);

        if(WarningCount != warning || ErrorCount != error)
        {
            OnDiagnosticsChanged?.Invoke(warning - WarningCount, error - ErrorCount);
            WarningCount = warning;
            ErrorCount = error;
        }

    }
}
