"""Multi-provider AI service router - all requests go through Eden.ai."""

from typing import Optional, Dict
import asyncio
from ..config import load_config, get_eden_api_key, get_provider_settings


def _run_async(coro):
    """Helper to run async code synchronously, handling nested loops."""
    try:
        # Check if there's already a running loop
        loop = asyncio.get_running_loop()
        # If we're in an async context, use nest_asyncio or run in thread
        import concurrent.futures
        with concurrent.futures.ThreadPoolExecutor() as executor:
            future = executor.submit(asyncio.run, coro)
            return future.result(timeout=120)
    except RuntimeError:
        # No running loop, safe to create one
        return asyncio.run(coro)


def get_eden_key_or_error():
    """Get Eden API key or raise descriptive error."""
    api_key = get_eden_api_key()
    if not api_key:
        raise ValueError("Eden.ai API key not configured. Set it in Settings → Eden.ai tab.")
    return api_key


def analyze_with_provider(
    text: str,
    analysis_type: str = "comprehensive",
    provider: str = None
) -> dict:
    """
    Analyze text using Eden.ai with the configured provider.

    Args:
        text: Text to analyze
        analysis_type: Type of analysis
        provider: Override provider (uses settings if None)

    Returns:
        Analysis results including topics
    """
    api_key = get_eden_key_or_error()

    if provider is None:
        settings = get_provider_settings()
        provider = settings.get("analysis_provider", "openai")

    from .eden_ai import chat_with_eden

    # Map provider names to Eden provider strings
    eden_provider = _map_to_eden_provider(provider)

    # First, get the main analysis
    messages = [{
        "role": "user",
        "content": f"""Analyze this transcription comprehensively.

IMPORTANT: Respond in the SAME LANGUAGE as the transcription text.

{text[:8000]}

Provide:
1. A concise summary (2-3 paragraphs)
2. Key points and main topics discussed
3. Notable quotes or statements
4. Overall tone and style
5. Any actionable items or recommendations mentioned"""
    }]

    result = _run_async(chat_with_eden(messages, api_key, providers=[eden_provider]))

    # Extract response from Eden format
    analysis_text = _extract_eden_response(result)

    # Now extract topics separately for better tagging
    topics = _extract_topics(text, api_key, eden_provider)

    return {
        "analysis": analysis_text,
        "topics": topics,
        "provider": provider,
        "via": "eden",
        "cost_info": result.get("cost_info")
    }


def _extract_topics(text: str, api_key: str, provider: str) -> list:
    """
    Extract topics/tags from text.
    Returns a list of 3-7 topic strings.
    """
    from .eden_ai import chat_with_eden

    messages = [{
        "role": "user",
        "content": f"""Extract 5-7 main topics or tags from this text.

IMPORTANT:
- Respond in the SAME LANGUAGE as the text
- Return ONLY the topics, one per line
- Each topic should be 1-4 words
- No numbering, no bullets, no explanations

Text:
{text[:4000]}"""
    }]

    try:
        result = _run_async(chat_with_eden(messages, api_key, providers=[provider], max_tokens=200))
        response_text = _extract_eden_response(result)

        # Parse topics from response
        topics = []
        for line in response_text.strip().split('\n'):
            line = line.strip()
            # Remove any numbering, bullets, or dashes
            line = line.lstrip('0123456789.-•*) ').strip()
            if line and len(line) < 50:  # Reasonable topic length
                topics.append(line)

        return topics[:7]  # Max 7 topics
    except Exception as e:
        print(f"Topics extraction failed: {e}")
        return []


def critique_with_provider(
    text: str,
    original_analysis: str,
    provider: str = None
) -> str:
    """
    Critique an analysis using Eden.ai with the configured provider.

    Args:
        text: Original transcription
        original_analysis: The analysis to critique
        provider: Override provider (uses settings if None)

    Returns:
        Critique text
    """
    api_key = get_eden_key_or_error()

    if provider is None:
        settings = get_provider_settings()
        provider = settings.get("critique_provider", "anthropic")

    from .eden_ai import chat_with_eden

    eden_provider = _map_to_eden_provider(provider)

    messages = [{
        "role": "user",
        "content": f"""Please critique this analysis.

IMPORTANT: Respond in the SAME LANGUAGE as the original text.

Original Text (excerpt):
{text[:3000]}

Analysis:
{original_analysis}

Provide:
1. A critique of the analysis - what's accurate, what's missing, what's potentially incorrect
2. An improved, more comprehensive version of the analysis
3. Key claims that should be fact-checked
4. Additional context or nuance that should be considered"""
    }]

    result = _run_async(chat_with_eden(messages, api_key, providers=[eden_provider]))
    return _extract_eden_response(result)


def find_resources_with_provider(
    topic: str,
    context: str = None,
    provider: str = None
) -> dict:
    """
    Find external resources using Eden.ai with the configured provider.

    Args:
        topic: Topic to search for
        context: Optional context from transcription
        provider: Override provider (uses settings if None)

    Returns:
        Resources and references with citations
    """
    api_key = get_eden_key_or_error()

    if provider is None:
        settings = get_provider_settings()
        provider = settings.get("resources_provider", "perplexityai")

    # Use specialized Perplexity search for citations
    if provider == "perplexity" or provider == "perplexityai":
        from .eden_ai import search_with_perplexity

        query = f"""Find authoritative resources, books, and academic references about: {topic}

Please provide:
1. **Books**: Title, author, publication year with links to purchase/info
2. **Academic Papers**: Title, authors, journal, year with DOI or direct links
3. **Articles**: From reputable sources with URLs
4. **Online Resources**: Courses, documentation, authoritative websites with links"""

        result = _run_async(search_with_perplexity(query, api_key, context))

        return {
            "resources": result.get("answer", ""),
            "citations": result.get("citations", []),
            "provider": "perplexityai",
            "via": "eden",
            "topic": topic
        }

    # For other providers, use chat
    from .eden_ai import chat_with_eden

    eden_provider = _map_to_eden_provider(provider)

    query = f"Search for authoritative resources about: {topic}"
    if context:
        query += f"\n\nContext from the content:\n{context[:1500]}"

    prompt = f"""{query}

Please provide:
1. Relevant books (title, author, year)
2. Academic papers or research articles
3. Online resources, courses, or authoritative websites
4. Why each resource is relevant

Include links/URLs where possible. Format each resource with full citation information."""

    messages = [{"role": "user", "content": prompt}]

    result = _run_async(chat_with_eden(messages, api_key, providers=[eden_provider]))
    response_text = _extract_eden_response(result)

    return {
        "resources": response_text,
        "provider": provider,
        "via": "eden",
        "topic": topic
    }


def answer_question_with_provider(
    text: str,
    question: str,
    provider: str = None
) -> dict:
    """
    Answer a question using Eden.ai with the configured provider.

    Args:
        text: Transcription text
        question: User's question
        provider: Override provider (uses settings if None)

    Returns:
        Answer and metadata
    """
    api_key = get_eden_key_or_error()

    if provider is None:
        settings = get_provider_settings()
        provider = settings.get("analysis_provider", "openai")

    from .eden_ai import chat_with_eden

    eden_provider = _map_to_eden_provider(provider)

    messages = [{
        "role": "user",
        "content": f"""Based on this transcription:

{text[:8000]}

Question: {question}

IMPORTANT: Respond in the SAME LANGUAGE as the transcription text.

Please answer based on the content of the transcription. If the answer isn't found in the transcription, say so clearly. Cite relevant parts of the transcription to support your answer."""
    }]

    result = _run_async(chat_with_eden(messages, api_key, providers=[eden_provider]))
    answer = _extract_eden_response(result)

    return {"answer": answer, "provider": provider, "via": "eden"}


def comprehensive_qa(
    text: str,
    question: str,
    find_references: bool = True
) -> dict:
    """
    Comprehensive Q&A with optional critique and references.
    All requests go through Eden.ai.

    Args:
        text: Transcription text
        question: User's question
        find_references: Whether to find external references

    Returns:
        Complete Q&A response with all provider results
    """
    settings = get_provider_settings()
    result = {}

    # 1. Get initial answer from analysis provider
    try:
        answer_result = answer_question_with_provider(text, question)
        result["initial_answer"] = answer_result
    except Exception as e:
        result["initial_answer_error"] = str(e)

    # 2. Get critique from critique provider (if different from analysis)
    if settings.get("critique_provider") != settings.get("analysis_provider"):
        try:
            initial_answer = result.get("initial_answer", {}).get("answer", "")
            if initial_answer:
                critique = critique_with_provider(text, initial_answer)
                result["critique"] = critique
        except Exception as e:
            result["critique_error"] = str(e)

    # 3. Find external references if requested
    if find_references:
        try:
            resources = find_resources_with_provider(question, text[:2000])
            result["references"] = resources
        except Exception as e:
            result["references_error"] = str(e)

    return result


def _map_to_eden_provider(provider: str) -> str:
    """Map our provider names to Eden.ai provider strings."""
    mapping = {
        # Analysis/Chat providers
        "openai": "openai",
        "anthropic": "anthropic",
        "google": "google",
        "cohere": "cohere",
        "meta": "meta",
        "perplexity": "perplexityai",  # Perplexity for web search & citations
        "perplexityai": "perplexityai",
        # Transcription providers
        "assemblyai": "assemblyai",
        "deepgram": "deepgram",
        "amazon": "amazon",
        "microsoft": "microsoft",
    }
    return mapping.get(provider, "openai")


def _extract_eden_response(result: dict) -> str:
    """Extract the text response from Eden.ai result format."""
    if not result:
        return "No response received"

    # Eden returns results keyed by provider name
    for provider_name, provider_result in result.items():
        if isinstance(provider_result, dict):
            # Try different response formats
            if 'generated_text' in provider_result:
                return provider_result['generated_text']
            if 'message' in provider_result:
                return provider_result['message']
            if 'text' in provider_result:
                return provider_result['text']

    # Fallback: return string representation
    return str(result)
