"""
Prompt Service for Translation
Story 3.12: Custom Prompts - Application lors Traduction LLM

Provides functions to retrieve prompt content and validate access.
"""

import uuid
import logging
from typing import Optional, Tuple

from database.connection import get_sync_session
from database.models import CustomPrompt
from utils.exceptions import PromptNotFoundError

logger = logging.getLogger(__name__)


def _validate_uuid(id_str: str, id_name: str = "ID") -> None:
    """
    Validate that a string is a valid UUID.
    
    Args:
        id_str: String to validate
        id_name: Name of the ID for error messages
        
    Raises:
        PromptNotFoundError: If the string is not a valid UUID
    """
    try:
        uuid.UUID(id_str)
    except (ValueError, AttributeError):
        raise PromptNotFoundError(
            message=f"{id_name} invalide.",
            details={id_name.lower(): id_str}
        )


def _get_prompt_record(prompt_id: str, user_id: str) -> Tuple[CustomPrompt, bool]:
    """
    Internal helper to fetch a prompt record from the database.
    
    This is a shared function to avoid code duplication between
    get_prompt_content and validate_prompt_access.
    
    Args:
        prompt_id: UUID of the prompt
        user_id: UUID of the user (must own the prompt)
    
    Returns:
        Tuple of (CustomPrompt, was_logged) - was_logged indicates if access was already logged
        
    Raises:
        PromptNotFoundError: If prompt doesn't exist or doesn't belong to user
    """
    # Validate UUIDs before querying database
    _validate_uuid(prompt_id, "prompt_id")
    _validate_uuid(user_id, "user_id")
    
    try:
        with get_sync_session() as session:
            prompt = (
                session.query(CustomPrompt)
                .filter(CustomPrompt.id == prompt_id, CustomPrompt.user_id == user_id)
                .first()
            )
            
            if not prompt:
                raise PromptNotFoundError(
                    message="Prompt introuvable ou vous n'avez pas accès à cette ressource.",
                    details={"prompt_id": prompt_id}
                )
            
            return prompt, False
            
    except PromptNotFoundError:
        raise
    except Exception as e:
        logger.error(f"Error fetching prompt {prompt_id}: {e}")
        raise PromptNotFoundError(
            message="Erreur lors de la récupération du prompt.",
            details={"prompt_id": prompt_id, "error": str(e)}
        )


def get_prompt_content(prompt_id: str, user_id: str) -> str:
    """
    Retrieve prompt content for a specific prompt owned by a user.
    
    Args:
        prompt_id: UUID of the prompt
        user_id: UUID of the user (must own the prompt)
    
    Returns:
        The prompt content string
        
    Raises:
        PromptNotFoundError: If prompt doesn't exist or doesn't belong to user
    """
    prompt, _ = _get_prompt_record(prompt_id, user_id)
    
    logger.info(
        f"Retrieved prompt '{prompt.name}' ({prompt_id}) for user {user_id}"
    )
    
    return prompt.content


def validate_prompt_access(prompt_id: str, user_id: str) -> bool:
    """
    Validate that a prompt exists and belongs to the user.
    
    Lightweight check before starting a translation job.
    Does NOT log to avoid duplicate log entries when followed by get_prompt_content.
    
    Args:
        prompt_id: UUID of the prompt
        user_id: UUID of the user (must own the prompt)
    
    Returns:
        True if prompt exists and belongs to user
        
    Raises:
        PromptNotFoundError: If prompt doesn't exist or doesn't belong to user
    """
    _get_prompt_record(prompt_id, user_id)
    return True
