namespace AxCopilot.Services.Agent;

/// <summary>스킬 정의 (*.skill.md에서 로드).</summary>
public class SkillDefinition
{
    public string Id { get; init; } = "";
    public string Name { get; init; } = "";
    public string Label { get; init; } = "";
    public string Description { get; init; } = "";
    public string Icon { get; init; } = "\uE768";
    public string SystemPrompt { get; init; } = "";
    public string FilePath { get; init; } = "";

    // SKILL.md 표준 확장 필드
    public string License { get; init; } = "";
    public string Compatibility { get; init; } = "";
    public string AllowedTools { get; init; } = "";

    /// <summary>런타임 의존성. "python", "node", "python,node" 등. 빈 문자열이면 의존성 없음.</summary>
    public string Requires { get; init; } = "";

    /// <summary>표시 대상 탭. "all"=전체, "cowork"=코워크만, "code"=코드만. 쉼표 구분 가능.</summary>
    public string Tabs { get; init; } = "all";

    // ── Phase 24: CC 고급 프론트매터 필드 ──

    /// <summary>실행 컨텍스트. "fork"이면 격리된 서브에이전트에서 실행.</summary>
    public string Context { get; init; } = "";

    /// <summary>이 스킬에 사용할 모델 오버라이드. 빈 문자열이면 기본 모델 사용.</summary>
    public string ModelOverride { get; init; } = "";

    /// <summary>사용자가 /로 호출 가능한지 여부. false면 AI만 사용.</summary>
    public bool UserInvocable { get; init; } = true;

    /// <summary>자동 활성화 경로 패턴. "**/*.py" 등 — 매칭 파일 터치 시 스킬 자동 제안.</summary>
    public string Paths { get; init; } = "";

    /// <summary>스킬 실행 중에만 활성화되는 스코프 훅 정의 (JSON).</summary>
    public string ScopedHooks { get; init; } = "";

    /// <summary>프론트매터 arguments 필드. 명명된 인수 목록.</summary>
    public IReadOnlyList<string> Arguments { get; init; } = Array.Empty<string>();

    /// <summary>자동 활성화 안내 (when_to_use). AI가 이 스킬을 선제적으로 사용할 힌트.</summary>
    public string WhenToUse { get; init; } = "";

    /// <summary>스킬 버전.</summary>
    public string Version { get; init; } = "";

    /// <summary>런타임 의존성 충족 여부. Requires가 비어있으면 항상 true.</summary>
    public bool IsAvailable { get; set; } = true;

    /// <summary>context:fork 설정인지 여부.</summary>
    public bool IsForkContext => "fork".Equals(Context, StringComparison.OrdinalIgnoreCase);

    /// <summary>지정 탭에서 이 스킬을 표시할지 판정합니다.</summary>
    public bool IsVisibleInTab(string activeTab)
    {
        if (string.IsNullOrEmpty(Tabs) || Tabs.Equals("all", StringComparison.OrdinalIgnoreCase))
            return true;
        var tabs = Tabs.Split(',').Select(t => t.Trim().ToLowerInvariant());
        var tab = activeTab.ToLowerInvariant();
        return tabs.Any(t => t == "all" || t == tab);
    }

    /// <summary>SKILL.md 표준 폴더 형식인지 여부.</summary>
    public bool IsStandardFormat => FilePath.EndsWith("SKILL.md", StringComparison.OrdinalIgnoreCase);

    /// <summary>비가용 시 사용자에게 표시할 힌트 메시지.</summary>
    public string UnavailableHint
    {
        get
        {
            if (IsAvailable || string.IsNullOrEmpty(Requires)) return "";
            var runtimes = Requires.Split(',').Select(r => r.Trim());
            var missing = runtimes.Where(r => !RuntimeDetector.IsAvailable(r)).ToArray();
            return missing.Length > 0 ? $"({string.Join(", ", missing.Select(r => char.ToUpper(r[0]) + r[1..]))} 필요)" : "";
        }
    }
}
