from app.core.config import settings
from app.services.infra.database import insert_llm_usage
from app.services.infra.quotas import check_quota, estimate_text_tokens
from app.core.prompts import SUMMARY_SYSTEM_PROMPT, SUMMARY_USER_PROMPT, TITLE_GENERATION_PROMPT
from app.core.llm_client import client
import logging

logger = logging.getLogger(__name__)

def get_embeddings(text: str, tenant_id: str = None, user_id: str = None):
    """
    Generates embeddings for the provided text with error handling.
    """
    if not text.strip():
        logger.warning("Empty text provided for embeddings.")
        return []

    if tenant_id:
        check_quota(tenant_id, "ai_tokens", user_id=user_id, requested_amount=estimate_text_tokens(text))

    try:
        logger.info(f"Generating embeddings using model: {settings.EMBED_MODEL}")
        response = client.embeddings.create(
            input=text,
            model=settings.EMBED_MODEL,
            timeout=30.0
        )
        usage = response.usage
        logger.info(f"LLM Usage (Embedding): Prompt: {usage.prompt_tokens}, Total: {usage.total_tokens}")
        
        # Persist Usage
        if tenant_id:
            insert_llm_usage(
                tenant_id, 
                "Embedding", 
                settings.EMBED_MODEL, 
                usage.prompt_tokens, 
                0, # Embeddings don't have completion tokens
                usage.total_tokens
            )
        
        return response.data[0].embedding
    except Exception as e:
        logger.error(f"Error generating embeddings via Azure OpenAI: {e}", exc_info=True)
        raise RuntimeError(f"Embedding service failure: {e}")

def chunk_text(text: str, chunk_size: int = 6000, overlap: int = 500):
    """
    Simple sliding window chunking with basic validation.
    Optimized for larger embedding models (e.g., text-embedding-3-large).
    """
    if not text:
        return []
        
    chunks = []
    start = 0
    text_len = len(text)
    while start < text_len:
        end = start + chunk_size
        chunks.append(text[start:end])
        if end >= text_len:
            break
        start += chunk_size - overlap
    return chunks

def generate_summary(text: str, tenant_id: str = None, user_id: str = None):
    """
    Generates a concise summary of the provided text using the chat model with error handling.
    """
    if not text.strip():
        logger.warning("Empty text provided for summary.")
        return "No content provided to summarize."

    content_to_summarize = text[:6000] if len(text) > 6000 else text

    if tenant_id:
        projected_tokens = estimate_text_tokens(content_to_summarize) + 500
        check_quota(tenant_id, "ai_tokens", user_id=user_id, requested_amount=projected_tokens)

    try:
        logger.info(f"Generating summary using model: {settings.LLM_MODEL}")
        response = client.chat.completions.create(
            model=settings.LLM_MODEL,
            messages=[
                {"role": "system", "content": SUMMARY_SYSTEM_PROMPT},
                {"role": "user", "content": SUMMARY_USER_PROMPT.format(content_to_summarize=content_to_summarize)}
            ],
            max_completion_tokens=500,
            timeout=60.0 # Add timeout for production
        )
        summary = response.choices[0].message.content
        usage = response.usage
        logger.info(f"LLM Usage (Content Summary): Prompt: {usage.prompt_tokens}, Completion: {usage.completion_tokens}, Total: {usage.total_tokens}")
        
        # Persist Usage
        if tenant_id:
            insert_llm_usage(
                tenant_id, 
                "Content Summary", 
                settings.LLM_MODEL, 
                usage.prompt_tokens, 
                usage.completion_tokens, 
                usage.total_tokens
            )
            
        logger.info("Summary generated successfully.")
        return summary
    except Exception as e:
        logger.error(f"Error generating summary via Azure OpenAI: {e}", exc_info=True)
        return "Summary could not be generated due to a service error."

def generate_title(text: str, tenant_id: str = None, user_id: str = None):
    """
    Generates a concise 3-5 word title for the given text using the LLM.
    """
    if not text.strip():
        return "Untitled_Document"

    user_prompt = TITLE_GENERATION_PROMPT.format(content_to_title=text[:3000]) # Use first 3000 chars

    if tenant_id:
        projected_tokens = estimate_text_tokens(user_prompt) + 100
        check_quota(tenant_id, "ai_tokens", user_id=user_id, requested_amount=projected_tokens)

    try:
        logger.info(f"Generating title using model: {settings.LLM_MODEL}")

        response = client.chat.completions.create(
            model=settings.LLM_MODEL,
            messages=[
                {"role": "user", "content": user_prompt}
            ],
            timeout=30.0
        )
        title_text = response.choices[0].message.content.strip()
        
        # Clean up title for URL/filename safety
        import re
        clean_title = re.sub(r'[^\w\s-]', '', title_text).strip().replace(' ', '_')
        if not clean_title:
            return "Untitled_Document"
            
        usage = response.usage
        
        # Persist Usage
        if tenant_id:
            insert_llm_usage(
                tenant_id, 
                "TitleGeneration", 
                settings.LLM_MODEL, 
                usage.prompt_tokens, 
                usage.completion_tokens, 
                usage.total_tokens
            )
            
        return clean_title
    except Exception as e:
        logger.error(f"Error generating title via Azure OpenAI: {e}", exc_info=True)
        return "Manual_Text_Input"
