from __future__ import annotations
"""Generate a full transcript insight JSON card (single shot) via LLM.

Falls back to heuristic card if LLM disabled or parsing fails.
"""
from typing import Optional, Any, Dict
import json, re
from ..config import settings
from ..models.insight import analyze_transcript

CARD_PROMPT = (
    "You are an expert discourse analyst. Given a transcript, produce ONE JSON object only.\n"
    "Schema: {header:{title,subtitle,badges:[{label,value}]}, sections:[{title, items:[...] }], footer:{persuasion_modes, devices:[{name,time?}], timeline:[{title,start_s,end_s,detail?}]}}.\n"
    "Required section titles (if content exists): 'TL;DR & Key Takeaways', 'Claims & Evidence', 'Glossary', 'Rhetoric & Devices', 'Common Misconceptions', 'Questions to Ponder', 'Next Steps', 'Segments (Timeline)', 'Text Metrics'.\n"
    "Badges MUST include Tone, Complexity, Impact, Claims, Evidence, Refs. Use integers where numeric.\n"
    "Claims items: claim, strength (weak|moderate|strong|unsupported), time (seconds or null), evidence:[{kind,text,time?}], assumptions, counterarguments, fact_check.\n"
    "Keep strings concise; max 5 key takeaways, <=140 chars each. JSON ONLY."
)

_DEF_TITLE = "Transcript Insight"

def _extract_json(text: str) -> Optional[Dict[str, Any]]:
    match = re.search(r"{[\s\S]+}", text)
    raw = match.group(0) if match else text
    try:
        data = json.loads(raw)
        if isinstance(data, dict):
            return data
    except Exception:
        return None
    return None


def llm_card_json_from_transcript(transcript: str, *, title: Optional[str] = None, subtitle: Optional[str] = None) -> Dict[str, Any]:
    if not settings.llm_enabled:
        card = analyze_transcript(transcript, video_title=title, channel_name=subtitle)
        return card.to_card()
    try:  # soft import
        from .base import get_provider, LLMRequest  # type: ignore
    except Exception:
        card = analyze_transcript(transcript, video_title=title, channel_name=subtitle)
        return card.to_card()
    provider = get_provider(settings.llm_provider)
    if not provider:
        card = analyze_transcript(transcript, video_title=title, channel_name=subtitle)
        return card.to_card()
    prompt = f"{CARD_PROMPT}\nTranscript:\n{transcript[:24000]}"
    try:
        resp = provider.complete(LLMRequest(prompt=prompt, temperature=0.15))
        parsed = _extract_json(resp.text.strip()) if resp.text else None
        if parsed:
            return parsed
    except Exception:  # pragma: no cover
        pass
    # Fallback
    card = analyze_transcript(transcript, video_title=title, channel_name=subtitle)
    return card.to_card()
