"""Comment generator — voice-matched LinkedIn post comments.

Generates engaging comments on prospect's LinkedIn posts that:
1. Sound like the sender wrote them (voice-matched)
2. Reference specific content from the post
3. Build trust without any sales pitch
4. Are concise (under 200 chars by default)

Backend routing: if in backend mode with no local LLM key,
proxies through the backend API (same pattern as followup_generator.py).
"""

from __future__ import annotations

import logging
from typing import Any

from .json_repair import parse_json
from .length_fixer import shorten_to_limit
from .llm import LLMClient
from .prompt_loader import (
    build_context_block,
    get_prompt_temperature,
    has_prompt,
    render_prompt,
)

logger = logging.getLogger(__name__)

COMMENT_MAX_CHARS = 200

COMMENT_SYSTEM = """You are an expert at writing LinkedIn comments. You write genuine, engaging comments that build relationships and trust — never selling, never pitching.

Key principles:
- Sound like a real person, not a bot or salesperson
- Reference a SPECIFIC idea, quote, or moment from the post
- Match the sender's voice and tone exactly
- Keep comments concise (1-3 short sentences, under 200 characters)
- Build trust and familiarity — the goal is to stay on their radar
- Vary comment styles naturally: insights, questions, encouragement, common ground, light humor
- Match the language of the post (if the post is in Spanish, comment in Spanish)
- NEVER mention your product, service, or company
- NEVER use flattery or overreaction

You output a JSON object with three fields: "style", "reasoning", and "comment".
No markdown, no code fences, no explanation outside the JSON."""

COMMENT_PROMPT = """Write a LinkedIn comment on this post.

## SENDER (you are writing AS this person)
Name: {sender_name}
Title: {sender_title}
Company: {sender_company}
Voice: {voice_tone}
Sentence style: {voice_sentence}
Vocabulary preferences: {voice_vocab}
No-go (NEVER use these): {voice_nogo}

## POST AUTHOR (the person whose post you're commenting on)
Name: {prospect_name}
Title: {prospect_title}
Company: {prospect_company}
Headline: {prospect_headline}

## PROSPECT INTELLIGENCE (from analysis)
{prospect_intelligence}

## THE POST
{post_text}

## GOAL PRIORITIZATION (ordered)
1. Build trust & familiarity
2. Stay on the author's radar
3. Encourage author to reply to the comment
4. Subtly reinforce understanding of their challenges

## CONSTRAINTS
- Open with their first name
- 1-3 short sentences, MAXIMUM {max_chars} characters
- Personal and natural — no sales pitch, no buzzwords, no cliches
- Reference a SPECIFIC idea from the post
- Match the sender's voice exactly
- Match the post's language
- NO emojis unless the sender's voice uses them
- NO flattery or overreaction
- NO mention of your product, service, or company

## COMMENT STYLE
Choose the most appropriate style silently (do NOT name it in your comment):
- Insightful Contribution: Add a brief perspective or data point
- Question for Engagement: Ask a thoughtful open-ended question
- Encouragement/Congrats: Genuine support for their achievement or insight
- Resource Sharing: Mention a relevant resource or parallel
- Common-Ground Connection: Connect through shared experience
- Light Humor: Only if the post's tone clearly permits it

## OUTPUT
Return ONLY valid JSON (no markdown):
{{
    "style": "the comment style chosen (e.g., 'Question for Engagement')",
    "reasoning": {{
        "post_hook": "the specific idea/quote from the post you're referencing",
        "angle": "how this builds trust without selling"
    }},
    "comment": "the actual comment text"
}}"""


def _build_intelligence_text(prospect_analysis: dict[str, Any] | None) -> str:
    """Build a prospect intelligence text block for prompt injection."""
    if not prospect_analysis:
        return "No analysis available — use profile data only."
    tone = prospect_analysis.get("tone", {})
    pain_points = prospect_analysis.get("pain_points", [])
    summary = prospect_analysis.get("summary", "")
    parts = []
    if summary:
        parts.append(f"Profile: {summary}")
    if tone.get("recommended_approach"):
        parts.append(f"Approach: {tone['recommended_approach']}")
    if tone.get("formality_level"):
        parts.append(f"Their formality: {tone['formality_level']}/10")
    if tone.get("industry_jargon"):
        jargon = tone["industry_jargon"]
        if isinstance(jargon, list):
            parts.append(f"Their jargon: {', '.join(jargon[:5])}")
    if pain_points and isinstance(pain_points, list):
        parts.append(f"Likely pain points: {'; '.join(str(p) for p in pain_points[:3])}")
    return "\n".join(parts) if parts else "No analysis available — use profile data only."


async def generate_comment(
    prospect: dict[str, Any],
    sender_profile: dict[str, Any],
    voice_signature: dict[str, Any],
    post_data: dict[str, Any],
    max_chars: int = COMMENT_MAX_CHARS,
    prospect_analysis: dict[str, Any] | None = None,
) -> dict[str, Any]:
    """Generate a personalized LinkedIn comment on a prospect's post.

    Args:
        prospect: Prospect profile data (name, title, company, headline)
        sender_profile: User's own profile data
        voice_signature: Voice analysis results (tone, vocabulary, patterns)
        post_data: The post to comment on (text, date, metrics)
        max_chars: Maximum comment length (default 200)

    Returns:
        Dict with "comment" (str), "style" (str), and "reasoning" (dict).
    """
    # Route through backend if in backend mode with no local LLM key
    from ..config import has_local_llm_key, is_backend_mode
    if is_backend_mode() and not has_local_llm_key():
        from ..linkedin import get_linkedin_client
        client = get_linkedin_client()
        try:
            return await client.generate_comment(
                sender=sender_profile,
                prospect=prospect,
                voice=voice_signature,
                post_data=post_data,
            )
        finally:
            await client.close()

    # ── Try v63 comment prompt ──
    use_v63 = has_prompt("comment_main") and has_prompt("outreach_system")

    if use_v63:
        logger.debug("Using v63 comment prompt")
        ctx = build_context_block(
            sender=sender_profile,
            prospect=prospect,
            campaign_config={},
            voice=voice_signature,
            analysis=prospect_analysis,
            max_chars=max_chars,
        )
        # Add post-specific context
        ctx["post_text"] = (post_data.get("text", "") or "")[:1000]
        ctx["post_date"] = post_data.get("date", "")
        ctx["post_metrics"] = post_data.get("metrics", "")

        system = render_prompt("outreach_system", ctx)
        prompt = render_prompt("comment_main", ctx)
        temp = get_prompt_temperature("comment_main")

        llm_client = LLMClient()
        raw = await llm_client.generate(prompt, system=system, temperature=temp)
    else:
        # ── Fallback to legacy prompts ──
        logger.debug("Using legacy comment prompt (v63 not found)")

        # Extract voice details
        voice_vocab = voice_signature.get("vocabulary_preferences", [])
        if isinstance(voice_vocab, list):
            voice_vocab = ", ".join(voice_vocab)

        # Get prospect's first name
        prospect_name = prospect.get("name", "").split()[0] if prospect.get("name") else "there"

        # Build prospect intelligence section
        prospect_intelligence = _build_intelligence_text(prospect_analysis)

        prompt = COMMENT_PROMPT.format(
            sender_name=sender_profile.get("name", ""),
            sender_title=sender_profile.get("title", ""),
            sender_company=sender_profile.get("company", ""),
            voice_tone=voice_signature.get("tone", "Professional, direct"),
            voice_sentence=voice_signature.get("sentence_length", "Medium"),
            voice_vocab=voice_vocab or "None specified",
            voice_nogo=voice_signature.get("no_go", "Generic sales phrases"),
            prospect_name=prospect_name,
            prospect_title=prospect.get("title", ""),
            prospect_company=prospect.get("company", ""),
            prospect_headline=prospect.get("headline", ""),
            prospect_intelligence=prospect_intelligence,
            post_text=(post_data.get("text", "") or "")[:1000],
            max_chars=max_chars,
        )

        llm_client = LLMClient()
        raw = await llm_client.generate(prompt, system=COMMENT_SYSTEM, temperature=0.7)

    # Parse JSON response with 2-tier repair
    fallback_comment = raw.strip().strip('"').strip("'").strip()
    result = parse_json(raw, fallback={"comment": fallback_comment, "style": "", "reasoning": {}})
    comment = result.get("comment", fallback_comment)
    style = result.get("style", "")
    reasoning = result.get("reasoning", {})

    # Clean up
    comment = comment.strip().strip('"').strip("'").strip()

    # Enforce character limit (LLM-based shortening with retry)
    comment = await shorten_to_limit(comment, max_chars)

    return {"comment": comment, "style": style, "reasoning": reasoning}
