from __future__ import annotations

from dataclasses import dataclass, field
from pathlib import Path
from typing import Any


@dataclass(slots=True)
class SkillManifest:
    name: str
    description: str
    version: str = "0.1.0"
    enabled: bool = True
    instructions_file: str = "SKILL.md"
    entrypoint: str | None = "main.py"
    register_function: str = "register"
    config: dict[str, Any] = field(default_factory=dict)
    metadata: dict[str, Any] = field(default_factory=dict)

    @classmethod
    def from_dict(cls, payload: dict[str, Any]) -> "SkillManifest":
        data = dict(payload)
        metadata = data.pop("metadata", {}) or {}
        config = data.pop("config", {}) or {}
        return cls(
            name=str(data["name"]),
            description=str(data.get("description", "")),
            version=str(data.get("version", "0.1.0")),
            enabled=bool(data.get("enabled", True)),
            instructions_file=str(data.get("instructions_file", "SKILL.md")),
            entrypoint=str(data["entrypoint"]) if data.get("entrypoint") else None,
            register_function=str(data.get("register_function", "register")),
            config=config,
            metadata=metadata,
        )

    def to_dict(self) -> dict[str, Any]:
        return {
            "name": self.name,
            "description": self.description,
            "version": self.version,
            "enabled": self.enabled,
            "instructions_file": self.instructions_file,
            "entrypoint": self.entrypoint,
            "register_function": self.register_function,
            "config": self.config,
            "metadata": self.metadata,
        }


@dataclass(slots=True)
class SkillExport:
    raw: Any = None
    tools: list[dict[str, Any]] = field(default_factory=list)
    prompts: list[str] = field(default_factory=list)
    metadata: dict[str, Any] = field(default_factory=dict)

    @classmethod
    def normalize(cls, payload: Any) -> "SkillExport":
        if payload is None:
            return cls()
        if isinstance(payload, cls):
            return payload
        if isinstance(payload, dict):
            tools = payload.get("tools", []) or []
            prompts = payload.get("prompts", []) or []
            metadata = payload.get("metadata", {}) or {}
            return cls(raw=payload, tools=list(tools), prompts=list(prompts), metadata=dict(metadata))
        if isinstance(payload, list):
            return cls(raw=payload, tools=list(payload))
        return cls(raw=payload)


@dataclass(slots=True)
class LoadedSkill:
    manifest: SkillManifest
    path: Path
    instructions: str
    export: SkillExport
    fingerprint: str
    files: tuple[Path, ...]
    module_name: str | None = None


@dataclass(slots=True)
class SkillStatus:
    name: str
    enabled: bool
    fingerprint: str | None = None
    error: str | None = None

