"""
C1 by Thesys — Generative UI service.

Calls the C1 API to generate rich, interactive UI specifications (JSON DSL)
from search results. The DSL is sent to the Android app which renders it
in a WebView using the C1 React SDK.
"""

import html
import os
import re

from loguru import logger
from openai import AsyncOpenAI

C1_MODEL = "c1/google/gemini-3-flash/v-20251230"
C1_BASE_URL = "https://api.thesys.dev/v1/embed"

C1_SYSTEM_PROMPT = (
    "You are a visual data card generator for a mobile voice assistant called Maya. "
    "Generate compact, mobile-friendly visual cards. Rules:\n"
    "- Use MiniCards with Stats for key numbers (prices, temperatures, scores).\n"
    "- Use Tables for structured comparisons.\n"
    "- Use MiniChart for sparkline trends when data supports it.\n"
    "- Use TagBlock with variant success/danger for up/down indicators.\n"
    "- Use CalloutV2 for brief insights or notes.\n"
    "- Keep cards compact — they display inside a chat feed on a phone.\n"
    "- Use real data styling with bold numbers and change indicators.\n"
    "- Do NOT add disclaimers about data accuracy.\n"
    "- Do NOT use form elements (inputs, buttons, sliders).\n"
    "- Do NOT use FollowupBlock or Button components."
)


def _get_c1_client() -> AsyncOpenAI:
    api_key = os.getenv("THESYS_API_KEY", "")
    if not api_key:
        raise ValueError("THESYS_API_KEY env var is not set")
    return AsyncOpenAI(api_key=api_key, base_url=C1_BASE_URL)


def _extract_c1_json(raw: str) -> str:
    """Extract the JSON from C1's <content thesys='true'>...</content> wrapper
    and unescape HTML entities."""
    unescaped = html.unescape(raw)
    match = re.search(r"<content[^>]*>(.*)</content>", unescaped, re.DOTALL)
    if match:
        return match.group(1).strip()
    return unescaped.strip()


async def generate_visual_card(query: str, summary: str, sources: list[dict]) -> dict:
    """Call C1 to generate a visual card for the given search results.

    Args:
        query: The original search query.
        summary: Text summary from Gemini grounded search.
        sources: List of source dicts with title/url/domain.

    Returns:
        dict with keys:
            - success (bool)
            - c1_dsl (str): The C1 JSON DSL string for rendering.
            - error (str, optional)
    """
    try:
        client = _get_c1_client()

        source_text = ""
        if sources:
            source_text = "\nSources:\n" + "\n".join(
                f"- {s.get('title', '')} ({s.get('url', '')})" for s in sources[:4]
            )

        user_prompt = (
            f"Create a visual card for this search result:\n\n"
            f"Query: {query}\n\n"
            f"Data:\n{summary}"
            f"{source_text}"
        )

        logger.info(f"[C1] Generating visual card for: {query!r}")

        response = await client.chat.completions.create(
            model=C1_MODEL,
            messages=[
                {"role": "system", "content": C1_SYSTEM_PROMPT},
                {"role": "user", "content": user_prompt},
            ],
            temperature=0.3,
        )

        raw_content = response.choices[0].message.content
        c1_json = _extract_c1_json(raw_content)

        logger.info(f"[C1] Generated card ({len(c1_json)} chars)")
        return {"success": True, "c1_dsl": c1_json}

    except Exception as e:
        logger.error(f"[C1] Error generating visual card: {e}")
        return {"success": False, "error": str(e)}
