import json
from collections.abc import Collection
from pathlib import Path

from jinja2 import Environment, FileSystemLoader

from .types import SkillScript, SkillScriptArgument

TEMPLATES_DIR = Path(__file__).parent

env = Environment(loader=FileSystemLoader(str(TEMPLATES_DIR)))
env.filters["tojson"] = lambda v: json.dumps(v, ensure_ascii=False)
env.filters["topy"] = repr


def render_skill_markdown(
    name: str,
    description: str,
    instructions: str,
    scripts: list[SkillScript],
) -> str:
    template = env.get_template("skill.md.jinja")
    return template.render(
        name=name,
        description=description,
        instructions=instructions.strip(),
        scripts=scripts,
    )


def render_skill_draft(
    name: str,
    description: str,
    scripts: list[SkillScript],
    instructions_placeholder: str = "[INSTRUCTIONS_PLACEHOLDER]",
) -> str:
    return render_skill_markdown(
        name=name,
        description=description,
        instructions=instructions_placeholder,
        scripts=scripts,
    )


def render_skill_script(script: SkillScript) -> str:
    template = env.get_template("script.py.jinja")
    return template.render(
        requires_python=script.requires_python,
        dependencies=sorted(script.dependencies),
        args=script.args,
        body=script.body,
    )


def render_script_boilerplate(
    file_name: str,
    when_to_use: str,
    dependencies: Collection[str],
    args: list[SkillScriptArgument],
) -> str:
    placeholder_body = "# Aqui entrará o corpo da função `main`."

    script = SkillScript.model_construct(
        file_name=file_name,
        when_to_use=when_to_use,
        body=placeholder_body,
        args=args,
        dependencies=set(dependencies),
        requires_python=">=3.13,<3.14",
    )

    return render_skill_script(script)
