"""
High-level orchestration functions - the main API.

These are the primary user-facing functions that coordinate
the entire pipeline.
"""

from typing import Any, Mapping
from hired.base import ResumeContent, RenderingConfig, ContentSource, ResumeBasics, ResumeWork, ResumeEducation
from hired.content import FileContentSource, DictContentSource, DefaultAIAgent
from hired.validators import validate_resume_content
from hired.render import _get_renderer_for_format
from hired.config import ConfigStore


def mk_content_for_resume(
    candidate_info_src: ContentSource | str | dict,
    job_info_src: ContentSource | str | dict,
    *,
    agent: Any | None = None,
    validate: bool = True
) -> ResumeContent:
    """
    Generate resume content from candidate and job information.
    """

    def _to_source(src):
        if isinstance(src, dict):
            return DictContentSource(src)
        elif isinstance(src, str):
            return FileContentSource(src)
        return src

    candidate = _to_source(candidate_info_src).read()
    job = _to_source(job_info_src).read()
    agent = agent or DefaultAIAgent()
    content = agent.generate_content(candidate, job)
    if validate:
        assert validate_resume_content(content.model_dump()), "Validation failed"
    return content


def mk_resume(
    content: ResumeContent | dict,
    rendering: RenderingConfig | dict | None = None,
    *,
    output_path: str | None = None
) -> bytes:
    """
    Render resume content to final format.
    """
    if isinstance(content, dict):
        basics = ResumeBasics(**content.get('basics', {}))
        work = [ResumeWork(**w) for w in content.get('work', [])]
        education = [ResumeEducation(**e) for e in content.get('education', [])]
        content = ResumeContent(basics=basics, work=work, education=education)
    if rendering is None:
        rendering = RenderingConfig()
    elif isinstance(rendering, dict):
        rendering = RenderingConfig(**rendering)
    renderer = _get_renderer_for_format(rendering.format)
    result = renderer.render(content, rendering)
    if output_path:
        with open(output_path, 'wb') as f:
            f.write(result)
    return result
