"""
Bridge between releaseops and llmhq-promptops.

Single integration point — all promptops access goes through here.
releaseops REFERENCES promptops versions, never re-versions prompts.
"""

from __future__ import annotations

import logging
from pathlib import Path
from typing import Any, Dict, List, Optional

from llmhq_releaseops.core.hasher import hash_content
from llmhq_releaseops.models.artifact import ArtifactRef, ArtifactType

logger = logging.getLogger(__name__)


class PromptBridge:
    """
    Bridge to llmhq-promptops for reading prompt artifacts.

    Wraps PromptManager and GitVersioning to provide:
    - Prompt content resolution at specific versions
    - Prompt listing and version discovery
    - Content hashing for bundle integrity
    """

    def __init__(self, repo_path: str = "."):
        self.repo_path = Path(repo_path).resolve()
        self._manager = None

    @property
    def manager(self):
        """Lazy-load PromptManager to avoid import-time errors."""
        if self._manager is None:
            from llmhq_promptops import PromptManager

            self._manager = PromptManager(str(self.repo_path))
        return self._manager

    def resolve_prompt(self, prompt_id: str, version: Optional[str] = None) -> str:
        """
        Get the raw YAML content of a prompt at a specific version.

        Args:
            prompt_id: Prompt identifier (e.g., "user-onboarding")
            version: Version string (e.g., "v1.0.1", "working", "latest")
                     None defaults to working/latest.

        Returns:
            Raw YAML content string.
        """
        content = self.manager.git_versioning.get_prompt_at_version(
            prompt_id, version
        )
        if content is None:
            raise ValueError(
                f"Prompt '{prompt_id}' at version '{version or 'latest'}' not found"
            )
        return content

    def render_prompt(
        self,
        prompt_id: str,
        variables: Dict[str, Any],
        version: Optional[str] = None,
    ) -> str:
        """
        Render a prompt with variables at a specific version.

        Args:
            prompt_id: Prompt identifier
            variables: Template variables
            version: Version string

        Returns:
            Rendered prompt string.
        """
        ref = f"{prompt_id}:{version}" if version else prompt_id
        return self.manager.get_prompt(ref, variables)

    def get_prompt_hash(self, prompt_id: str, version: Optional[str] = None) -> str:
        """Get the content hash of a prompt at a specific version."""
        content = self.resolve_prompt(prompt_id, version)
        return hash_content(content)

    def list_prompts(self) -> List[str]:
        """List all available prompt IDs."""
        return self.manager.list_prompts()

    def list_versions(self, prompt_id: str) -> List[Dict]:
        """List all versions of a prompt."""
        return self.manager.list_versions(prompt_id)

    def get_latest_version(self, prompt_id: str) -> Optional[str]:
        """Get the latest version string for a prompt."""
        return self.manager.get_latest_version(prompt_id)

    def create_artifact_ref(
        self,
        role: str,
        prompt_id: str,
        version: Optional[str] = None,
    ) -> ArtifactRef:
        """
        Create an ArtifactRef for a prompt, resolving its content hash.

        Args:
            role: Role name in the bundle (e.g., "system", "planner")
            prompt_id: Prompt identifier
            version: Version to pin to (resolves to latest if None)

        Returns:
            ArtifactRef with content hash populated.
        """
        resolved_version = version or self.get_latest_version(prompt_id) or "working"
        content_hash = self.get_prompt_hash(prompt_id, resolved_version)
        ref_string = f"prompts/{prompt_id}@{resolved_version}"

        return ArtifactRef(
            artifact_type=ArtifactType.PROMPT,
            role=role,
            ref=ref_string,
            content_hash=content_hash,
        )

    def has_prompt(self, prompt_id: str) -> bool:
        """Check if a prompt exists."""
        return prompt_id in self.list_prompts()
