"""Project context resolution for CLI commands."""

__author__ = "Lene Preuss <lene.preuss@gmail.com>"

from dataclasses import dataclass
from pathlib import Path

from stable_delusion.exceptions.project_error import ProjectError
from stable_delusion.project.active_project import get_active_project
from stable_delusion.project.models import ProjectMetadata, SceneMetadata
from stable_delusion.project.project_repository import ProjectRepository
from stable_delusion.project.scene_repository import SceneRepository
from stable_delusion.project.xdg_paths import resolve_projects_dir


@dataclass
class ProjectContext:
    """Resolved project and scene for project-mode CLI commands."""

    project_dir: Path
    scene_dir: Path
    project_meta: ProjectMetadata
    scene_meta: SceneMetadata


def _resolve_project(
    project_name: str | None,
    projects_dir: Path,
) -> tuple[Path, ProjectMetadata]:
    """Resolve project directory and metadata by name or active project."""
    project_repo = ProjectRepository()
    if project_name:
        return project_repo.find_by_name(projects_dir, project_name)
    active = get_active_project()
    if active is None:
        raise ProjectError("No active project. Use 'hallucinate project use <name>' to set one.")
    project_dir = active[1]
    return project_dir, project_repo.get(project_dir)


def resolve_context(
    scene_name: str | None,
    project_name: str | None = None,
    projects_dir_override: Path | None = None,
) -> "ProjectContext | None":
    if scene_name is None:
        return None

    projects_dir = resolve_projects_dir(projects_dir_override)
    scene_repo = SceneRepository()
    project_dir, project_meta = _resolve_project(project_name, projects_dir)

    scenes = scene_repo.list_scenes(project_dir)
    matching = [(p, m) for p, m in scenes if m.name == scene_name]
    if not matching:
        raise ProjectError(f"Scene '{scene_name}' not found in project '{project_meta.name}'.")
    scene_dir, scene_meta = matching[0]

    return ProjectContext(
        project_dir=project_dir,
        scene_dir=scene_dir,
        project_meta=project_meta,
        scene_meta=scene_meta,
    )
