"""Writer agent for creating LinkedIn posts."""
import asyncio
import json
import random
import re
from typing import Dict, Any, Optional, List
from loguru import logger

from src.agents.base import BaseAgent
from src.config import settings


class WriterAgent(BaseAgent):
    """Agent for writing LinkedIn posts based on profile analysis."""

    def __init__(self):
        """Initialize writer agent."""
        super().__init__("Writer")

    async def process(
        self,
        topic: Dict[str, Any],
        profile_analysis: Dict[str, Any],
        feedback: Optional[str] = None,
        previous_version: Optional[str] = None,
        example_posts: Optional[List[str]] = None,
        critic_result: Optional[Dict[str, Any]] = None,
        learned_lessons: Optional[Dict[str, Any]] = None,
        post_type: Any = None,
        post_type_analysis: Optional[Dict[str, Any]] = None,
        user_thoughts: str = "",
        selected_hook: str = "",
        company_strategy: Optional[Dict[str, Any]] = None,
        strategy_weight: float = 0.5
    ) -> str:
        """
        Write a LinkedIn post.

        Args:
            topic: Topic dictionary with title, fact, relevance
            profile_analysis: Profile analysis results
            feedback: Optional feedback from critic (text summary)
            previous_version: Optional previous version of the post
            example_posts: Optional list of real posts from the customer to use as style reference
            critic_result: Optional full critic result with specific_changes
            learned_lessons: Optional lessons learned from past critic feedback
            post_type: Optional PostType object for type-specific writing
            post_type_analysis: Optional analysis of the post type
            company_strategy: Optional company strategy to consider during writing
            strategy_weight: Strategy weight (0.0-1.0) controlling how strongly the company strategy influences post generation

        Returns:
            Written LinkedIn post
        """
        if feedback and previous_version:
            logger.info(f"Revising post based on critic feedback")
            # For revisions, always use single draft (feedback is specific)
            return await self._write_single_draft(
                topic=topic,
                profile_analysis=profile_analysis,
                feedback=feedback,
                previous_version=previous_version,
                example_posts=example_posts,
                critic_result=critic_result,
                learned_lessons=learned_lessons,
                post_type=post_type,
                post_type_analysis=post_type_analysis,
                user_thoughts=user_thoughts,
                selected_hook=selected_hook,
                company_strategy=company_strategy,
                strategy_weight=strategy_weight
            )
        else:
            logger.info(f"Writing initial post for topic: {topic.get('title', 'Unknown')}")
            if post_type:
                logger.info(f"Using post type: {post_type.name}")
            if user_thoughts:
                logger.info(f"Including user thoughts ({len(user_thoughts)} chars)")
            if selected_hook:
                logger.info(f"Using selected hook: {selected_hook[:50]}...")

            # Select example posts - use semantic matching if enabled
            selected_examples = self._select_example_posts(topic, example_posts, profile_analysis)

            # Use Multi-Draft if enabled for initial posts
            if settings.writer_multi_draft_enabled:
                return await self._write_multi_draft(
                    topic=topic,
                    profile_analysis=profile_analysis,
                    example_posts=selected_examples,
                    learned_lessons=learned_lessons,
                    post_type=post_type,
                    post_type_analysis=post_type_analysis,
                    user_thoughts=user_thoughts,
                    selected_hook=selected_hook,
                    company_strategy=company_strategy,
                    strategy_weight=strategy_weight
                )
            else:
                return await self._write_single_draft(
                    topic=topic,
                    profile_analysis=profile_analysis,
                    example_posts=selected_examples,
                    learned_lessons=learned_lessons,
                    post_type=post_type,
                    post_type_analysis=post_type_analysis,
                    user_thoughts=user_thoughts,
                    selected_hook=selected_hook,
                    company_strategy=company_strategy,
                    strategy_weight=strategy_weight
                )

    def _select_example_posts(
        self,
        topic: Dict[str, Any],
        example_posts: Optional[List[str]],
        profile_analysis: Dict[str, Any]
    ) -> List[str]:
        """
        Select example posts - either semantically similar or random.

        Args:
            topic: The topic to write about
            example_posts: All available example posts
            profile_analysis: Profile analysis results

        Returns:
            Selected example posts (always max 2)
        """
        if not example_posts or len(example_posts) == 0:
            return []

        if not settings.writer_semantic_matching_enabled:
            # Fallback to random selection
            num_examples = min(2, len(example_posts))
            selected = random.sample(example_posts, num_examples)
            logger.info(f"Using {len(selected)} random example posts")
            return selected

        # Semantic matching based on keywords
        logger.info("Using semantic matching for example post selection")

        # Extract keywords from topic
        topic_text = f"{topic.get('title', '')} {topic.get('fact', '')} {topic.get('category', '')}".lower()
        topic_keywords = self._extract_keywords(topic_text)

        # Score each post by keyword overlap
        scored_posts = []
        for post in example_posts:
            post_lower = post.lower()
            score = 0
            matched_keywords = []

            for keyword in topic_keywords:
                if keyword in post_lower:
                    score += 1
                    matched_keywords.append(keyword)

            # Bonus for longer matches
            score += len(matched_keywords) * 0.5

            scored_posts.append({
                "post": post,
                "score": score,
                "matched": matched_keywords
            })

        # Sort by score (highest first)
        scored_posts.sort(key=lambda x: x["score"], reverse=True)

        # Take top 2 by relevance
        selected = []

        # Top 2 most relevant
        for item in scored_posts[:2]:
            if item["score"] > 0:
                selected.append(item["post"])
                logger.debug(f"Selected post (score {item['score']:.1f}, keywords: {item['matched'][:3]})")

        # If we still don't have enough, fill with top scored
        while len(selected) < 2 and len(selected) < len(example_posts):
            found = False
            for item in scored_posts:
                if item["post"] not in selected:
                    selected.append(item["post"])
                    found = True
                    break
            if not found:
                break  # no more unique posts available

        logger.info(f"Selected {len(selected)} example posts via semantic matching")
        return selected

    def _extract_keywords(self, text: str) -> List[str]:
        """Extract meaningful keywords from text."""
        # Remove common stop words
        stop_words = {
            'der', 'die', 'das', 'und', 'in', 'zu', 'den', 'von', 'für', 'mit',
            'auf', 'ist', 'im', 'sich', 'des', 'ein', 'eine', 'als', 'auch',
            'es', 'an', 'werden', 'aus', 'er', 'hat', 'dass', 'sie', 'nach',
            'wird', 'bei', 'einer', 'um', 'am', 'sind', 'noch', 'wie', 'einem',
            'über', 'so', 'zum', 'kann', 'nur', 'sein', 'ich', 'nicht', 'was',
            'oder', 'aber', 'wenn', 'ihre', 'man', 'the', 'and', 'to', 'of',
            'a', 'is', 'that', 'it', 'for', 'on', 'are', 'with', 'be', 'this',
            'was', 'have', 'from', 'your', 'you', 'we', 'our', 'mehr', 'neue',
            'neuen', 'können', 'durch', 'diese', 'dieser', 'einem', 'einen'
        }

        # Split and clean
        words = re.findall(r'\b[a-zäöüß]{3,}\b', text.lower())
        keywords = [w for w in words if w not in stop_words and len(w) >= 4]

        # Also extract compound words and important terms
        important_terms = re.findall(r'\b[A-Z][a-zäöüß]+(?:[A-Z][a-zäöüß]+)*\b', text)
        keywords.extend([t.lower() for t in important_terms if len(t) >= 4])

        # Deduplicate while preserving order
        seen = set()
        unique_keywords = []
        for kw in keywords:
            if kw not in seen:
                seen.add(kw)
                unique_keywords.append(kw)

        return unique_keywords[:15]  # Limit to top 15 keywords

    def _parse_json_response(self, response: str) -> Dict[str, Any]:
        """Parse JSON robustly from model output, including fenced or prefixed responses."""
        if not response:
            raise json.JSONDecodeError("Empty response", "", 0)

        try:
            return json.loads(response)
        except json.JSONDecodeError:
            pass

        cleaned = response.strip()
        cleaned = re.sub(r"^```(?:json)?\s*", "", cleaned, flags=re.IGNORECASE)
        cleaned = re.sub(r"\s*```$", "", cleaned)

        try:
            return json.loads(cleaned)
        except json.JSONDecodeError:
            pass

        start = cleaned.find("{")
        end = cleaned.rfind("}")
        if start != -1 and end != -1 and end > start:
            candidate = cleaned[start:end + 1]
            return json.loads(candidate)

        raise json.JSONDecodeError("No JSON object found", cleaned, 0)

    async def _write_multi_draft(
        self,
        topic: Dict[str, Any],
        profile_analysis: Dict[str, Any],
        example_posts: List[str],
        learned_lessons: Optional[Dict[str, Any]] = None,
        post_type: Any = None,
        post_type_analysis: Optional[Dict[str, Any]] = None,
        user_thoughts: str = "",
        selected_hook: str = "",
        company_strategy: Optional[Dict[str, Any]] = None,
        strategy_weight: float = 0.5
    ) -> str:
        """
        Generate multiple drafts and select the best one.

        Args:
            topic: Topic to write about
            profile_analysis: Profile analysis results
            example_posts: Example posts for style reference
            learned_lessons: Lessons learned from past feedback
            post_type: Optional PostType object
            post_type_analysis: Optional post type analysis
            company_strategy: Optional company strategy to consider
            strategy_weight: Strategy weight (0.0-1.0) for company strategy influence

        Returns:
            Best selected draft
        """
        num_drafts = min(max(settings.writer_multi_draft_count, 2), 5)  # Clamp between 2-5
        logger.info(f"Generating {num_drafts} drafts for selection")

        system_prompt = self._get_compact_system_prompt(
            profile_analysis=profile_analysis,
            example_posts=example_posts,
            company_strategy=company_strategy,
            strategy_weight=strategy_weight
        )

        # Generate drafts in parallel with different temperatures/approaches
        draft_configs = [
            {"temperature": 0.5, "approach": "fokussiert"},
            {"temperature": 0.7, "approach": "kreativ"},
            {"temperature": 0.6, "approach": "ausgewogen"},
            {"temperature": 0.8, "approach": "experimentell"},
            {"temperature": 0.55, "approach": "präzise"},
        ][:num_drafts]

        # Create draft tasks
        async def generate_draft(config: Dict, draft_num: int) -> Dict[str, Any]:
            user_prompt = self._get_user_prompt_for_draft(topic, draft_num, config["approach"], user_thoughts, selected_hook)
            try:
                draft = await self.call_azure_claude(
                    system_prompt=system_prompt,
                    user_prompt=user_prompt,
                    model=settings.azure_claude_model,
                    temperature=config["temperature"]
                )
                return {
                    "draft_num": draft_num,
                    "content": draft.strip(),
                    "approach": config["approach"],
                    "temperature": config["temperature"]
                }
            except Exception as e:
                logger.error(f"Failed to generate draft {draft_num}: {e}")
                return None

        # Run drafts in parallel
        tasks = [generate_draft(config, i + 1) for i, config in enumerate(draft_configs)]
        results = await asyncio.gather(*tasks)

        # Filter out failed drafts
        drafts = [r for r in results if r is not None]

        if not drafts:
            raise ValueError("All draft generations failed")

        if len(drafts) == 1:
            logger.warning("Only one draft succeeded, using it directly")
            return drafts[0]["content"]

        logger.info(f"Generated {len(drafts)} drafts, now selecting best one")

        # Select the best draft
        best_draft = await self._select_best_draft(drafts, topic, profile_analysis)
        return best_draft

    def _get_user_prompt_for_draft(
        self,
        topic: Dict[str, Any],
        draft_num: int,
        approach: str,
        user_thoughts: str = "",
        selected_hook: str = ""
    ) -> str:
        """Get user prompt with slight variations for different drafts."""
        # Different emphasis for each draft
        emphasis_variations = {
            1: "Fokussiere auf einen STARKEN, überraschenden Hook. Der erste Satz muss fesseln!",
            2: "Fokussiere auf STORYTELLING. Baue eine kleine Geschichte oder Anekdote ein.",
            3: "Fokussiere auf KONKRETEN MEHRWERT. Was lernt der Leser konkret?",
            4: "Fokussiere auf EMOTION. Sprich Gefühle und persönliche Erfahrungen an.",
            5: "Fokussiere auf PROVOKATION. Stelle eine These auf, die zum Nachdenken anregt.",
        }

        emphasis = emphasis_variations.get(draft_num, emphasis_variations[1])

        # Build enhanced topic section with new fields
        angle_section = ""
        if topic.get('angle'):
            angle_section = f"\n**ANGLE/PERSPEKTIVE:**\n{topic.get('angle')}\n"

        # User-selected hook takes priority
        hook_section = ""
        if selected_hook:
            hook_section = f"\n**HOOK (VERWENDE DIESEN ALS EINSTIEG!):**\n\"{selected_hook}\"\n"
        elif topic.get('hook_idea'):
            hook_section = f"\n**HOOK-IDEE (als Inspiration):**\n\"{topic.get('hook_idea')}\"\n"

        facts_section = ""
        key_facts = topic.get('key_facts', [])
        if key_facts and isinstance(key_facts, list) and len(key_facts) > 0:
            facts_section = "\n**KEY FACTS (nutze diese!):**\n" + "\n".join([f"- {f}" for f in key_facts]) + "\n"

        summary_section = ""
        if topic.get('summary'):
            summary_section = f"\n**ZUSAMMENFASSUNG (vom Link):**\n{topic.get('summary')}\n"

        extended_summary_section = ""
        if topic.get('extended_summary'):
            extended_summary_section = f"\n**DETAILLIERTE ZUSAMMENFASSUNG:**\n{topic.get('extended_summary')}\n"

        outline_section = ""
        outline = topic.get('outline', [])
        if outline and isinstance(outline, list) and len(outline) > 0:
            outline_section = "\n**INHALTS-GLIEDERUNG:**\n" + "\n".join([f"- {o}" for o in outline]) + "\n"

        key_points_section = ""
        key_points = topic.get('key_points', [])
        if key_points and isinstance(key_points, list) and len(key_points) > 0:
            key_points_section = "\n**KERNPUNKTE (vom Link):**\n" + "\n".join([f"- {p}" for p in key_points]) + "\n"

        quotes_section = ""
        quotes = topic.get('quotes', [])
        if quotes and isinstance(quotes, list) and len(quotes) > 0:
            quotes_section = "\n**ZITATE (optional verwenden):**\n" + "\n".join([f"- \"{q}\"" for q in quotes]) + "\n"

        source_section = ""
        if topic.get('source_title') or topic.get('source'):
            source_title = topic.get('source_title') or ""
            source_url = topic.get('source') or ""
            source_section = f"\n**QUELLE:** {source_title} {source_url}\n"

        why_section = ""
        if topic.get('why_this_person'):
            why_section = f"\n**WARUM DU DARÜBER SCHREIBEN SOLLTEST:**\n{topic.get('why_this_person')}\n"

        plan_section = ""
        if topic.get("content_plan"):
            plan = topic.get("content_plan") or {}
            alignment = plan.get("company_alignment") or []
            alignment_section = ""
            if isinstance(alignment, list) and alignment:
                alignment_section = "\n**STRATEGIE-ANFORDERUNGEN (VERBINDLICH):**\n" + "\n".join([f"- {a}" for a in alignment]) + "\n"
            plan_section = f"\n**CONTENT-PLAN (VERBINDLICH):**\n{json.dumps(plan, ensure_ascii=False, indent=2)}\n{alignment_section}"

        # User thoughts section
        thoughts_section = ""
        if user_thoughts:
            thoughts_section = f"""
**PERSÖNLICHE GEDANKEN (UNBEDINGT einbauen!):**
{user_thoughts}

Diese Gedanken MÜSSEN im Post verarbeitet werden!
"""

        # Adjust task based on hook
        if selected_hook:
            task_text = """**AUFGABE:**
Schreibe einen authentischen LinkedIn-Post, der:
1. Mit dem VORGEGEBENEN HOOK beginnt (exakt oder leicht angepasst)
2. Den Fakt/das Thema aufgreift und Mehrwert bietet
3. Die persönlichen Gedanken organisch einbaut
4. Die Key Facts verwendet wo es passt
5. Mit einem passenden CTA endet"""
        else:
            task_text = """**AUFGABE:**
Schreibe einen authentischen LinkedIn-Post, der:
1. Mit einem STARKEN, unerwarteten Hook beginnt (nutze die Hook-Idee als Inspiration, NICHT wörtlich!)
2. Den Fakt/das Thema aufgreift und Mehrwert bietet
3. Die persönlichen Gedanken organisch einbaut (falls vorhanden)
4. Die Key Facts einbaut wo es passt
5. Mit einem passenden CTA endet"""

        content_plan_note = ""
        if topic.get("content_plan"):
            plan = topic.get("content_plan") or {}
            tier = plan.get("quality_tier")
            required = plan.get("required_elements") or []
            req_text = ", ".join(required[:6]) if isinstance(required, list) else ""
            tier_text = f" | Qualitätsziel: {tier}" if tier else ""
            req_note = f" | Pflichtelemente: {req_text}" if req_text else ""
            content_plan_note = f"\n- CONTENT-PLAN ist verbindlich: Nutze NUR diese Fakten, keine neuen hinzufügen{tier_text}{req_note}"

        return f"""Schreibe einen LinkedIn-Post zu folgendem Thema:

**THEMA:** {topic.get('title', 'Unbekanntes Thema')}

**KATEGORIE:** {topic.get('category', 'Allgemein')}
{angle_section}{hook_section}
**KERN-FAKT / INHALT:**
{topic.get('fact', topic.get('description', ''))}
{summary_section}{extended_summary_section}{outline_section}{key_points_section}{facts_section}{quotes_section}{source_section}{plan_section}{thoughts_section}
**WARUM RELEVANT:**
{topic.get('relevance', 'Aktuelles Thema für die Zielgruppe')}
{why_section}
**DEIN ANSATZ FÜR DIESEN ENTWURF ({approach}):**
{emphasis}

{task_text}

WICHTIG:
- Vermeide KI-typische Formulierungen ("In der heutigen Zeit", "Tauchen Sie ein", etc.)
- Schreibe natürlich und menschlich
- Der Post soll SOFORT 85+ Punkte im Review erreichen
{content_plan_note}

Gib NUR den fertigen Post zurück."""

    async def _select_best_draft(
        self,
        drafts: List[Dict[str, Any]],
        topic: Dict[str, Any],
        profile_analysis: Dict[str, Any]
    ) -> str:
        """
        Use AI to select the best draft.

        Args:
            drafts: List of draft dictionaries
            topic: The topic being written about
            profile_analysis: Profile analysis for style reference

        Returns:
            Content of the best draft
        """
        # Build comparison prompt
        drafts_text = ""
        for draft in drafts:
            drafts_text += f"\n\n=== ENTWURF {draft['draft_num']} ({draft['approach']}) ===\n"
            drafts_text += draft["content"]
            drafts_text += "\n=== ENDE ENTWURF ==="

        # Extract key style elements for comparison
        writing_style = profile_analysis.get("writing_style", {})
        linguistic = profile_analysis.get("linguistic_fingerprint", {})
        phrase_library = profile_analysis.get("phrase_library", {})

        selector_prompt = f"""Du bist ein erfahrener LinkedIn-Content-Editor. Wähle den BESTEN Entwurf aus.

**THEMA DES POSTS:**
{topic.get('title', 'Unbekannt')}

**STIL-ANFORDERUNGEN:**
- Tonalität: {writing_style.get('tone', 'Professionell')}
- Energie-Level: {linguistic.get('energy_level', 7)}/10
- Ansprache: {writing_style.get('form_of_address', 'Du')}
- Typische Hook-Phrasen: {', '.join(phrase_library.get('hook_phrases', [])[:3])}

**DIE ENTWÜRFE:**
{drafts_text}

**BEWERTUNGSKRITERIEN:**
1. **Hook-Qualität (30%):** Wie aufmerksamkeitsstark ist der erste Satz?
2. **Stil-Match (25%):** Wie gut passt der Entwurf zum beschriebenen Stil?
3. **Mehrwert (25%):** Wie viel konkreten Nutzen bietet der Post?
4. **Natürlichkeit (20%):** Wie authentisch und menschlich klingt er?

**AUFGABE:**
Analysiere jeden Entwurf kurz und wähle den besten. Antworte im JSON-Format:

{{
  "analysis": [
    {{"draft": 1, "hook_score": 8, "style_score": 7, "value_score": 8, "natural_score": 7, "total": 30, "notes": "Kurze Begründung"}},
    ...
  ],
  "winner": 1,
  "reason": "Kurze Begründung für die Wahl"
}}"""

        response = await self.call_azure_claude(
            system_prompt="Du bist ein Content-Editor, der LinkedIn-Posts bewertet und den besten auswählt.",
            user_prompt=selector_prompt,
            model=settings.azure_claude_model,
            temperature=0.2,
            response_format={"type": "json_object"}
        )

        try:
            result = json.loads(response)
            winner_num = result.get("winner", 1)
            reason = result.get("reason", "")

            # Find the winning draft
            winning_draft = next(
                (d for d in drafts if d["draft_num"] == winner_num),
                drafts[0]  # Fallback to first draft
            )

            logger.info(f"Selected draft {winner_num} ({winning_draft['approach']}): {reason}")
            return winning_draft["content"]

        except (json.JSONDecodeError, KeyError) as e:
            logger.warning(f"Failed to parse selector response, using first draft: {e}")
            return drafts[0]["content"]

    async def _write_single_draft(
        self,
        topic: Dict[str, Any],
        profile_analysis: Dict[str, Any],
        feedback: Optional[str] = None,
        previous_version: Optional[str] = None,
        example_posts: Optional[List[str]] = None,
        critic_result: Optional[Dict[str, Any]] = None,
        learned_lessons: Optional[Dict[str, Any]] = None,
        post_type: Any = None,
        post_type_analysis: Optional[Dict[str, Any]] = None,
        user_thoughts: str = "",
        selected_hook: str = "",
        company_strategy: Optional[Dict[str, Any]] = None,
        strategy_weight: float = 0.5
    ) -> str:
        """Write a single draft (original behavior)."""
        # Select examples if not already selected
        if example_posts is None:
            example_posts = []

        selected_examples = example_posts
        if not feedback and not previous_version:
            # Only select for initial posts, not revisions
            if len(selected_examples) == 0:
                pass  # No examples available
            elif len(selected_examples) > 2:
                selected_examples = self._select_example_posts(topic, selected_examples, profile_analysis)
        elif len(selected_examples) > 2:
            selected_examples = self._select_example_posts(topic, selected_examples, profile_analysis)

        system_prompt = self._get_compact_system_prompt(
            profile_analysis=profile_analysis,
            example_posts=selected_examples,
            company_strategy=company_strategy,
            strategy_weight=strategy_weight
        )
        user_prompt = self._get_user_prompt(topic, feedback, previous_version, critic_result, user_thoughts, selected_hook)

        # OPTIMIERT: Niedrigere Temperature (0.5 statt 0.6) für konsistenteren Stil
        post = await self.call_azure_claude(
            system_prompt=system_prompt,
            user_prompt=user_prompt,
            model=settings.azure_claude_model,
            temperature=0.5
        )

        logger.info("Post written successfully")
        return post.strip()

    def _build_style_card(self, profile_analysis: Dict[str, Any]) -> str:
        """Build a compact, deterministic style card."""
        def _ensure_dict(value):
            return value if isinstance(value, dict) else {}

        writing_style = _ensure_dict(profile_analysis.get("writing_style", {}))
        linguistic = _ensure_dict(profile_analysis.get("linguistic_fingerprint", {}))
        tone_analysis = _ensure_dict(profile_analysis.get("tone_analysis", {}))
        phrase_library = _ensure_dict(profile_analysis.get("phrase_library", {}))
        structure_templates = _ensure_dict(profile_analysis.get("structure_templates", {}))
        visual = _ensure_dict(profile_analysis.get("visual_patterns", {}))
        audience = _ensure_dict(profile_analysis.get("audience_insights", {}))
        content_strategy = _ensure_dict(profile_analysis.get("content_strategy", {}))
        ngram_patterns = _ensure_dict(profile_analysis.get("ngram_patterns", {}))

        def _top(items, n):
            if not isinstance(items, list):
                return []
            return [str(i) for i in items[:n]]

        hook_phrases = _top(phrase_library.get("hook_phrases", []), 3)
        cta_phrases = _top(phrase_library.get("cta_phrases", []), 2)
        transition_phrases = _top(phrase_library.get("transition_phrases", []), 3)
        emotional_expressions = _top(phrase_library.get("emotional_expressions", []), 3)
        signature_phrases = _top(linguistic.get("signature_phrases", []), 3)
        narrative_anchors = _top(linguistic.get("narrative_anchors", []), 3)
        typical_bigrams = _top(ngram_patterns.get("typical_bigrams", []), 4)
        typical_trigrams = _top(ngram_patterns.get("typical_trigrams", []), 3)
        sentence_starters = _top(structure_templates.get("typical_sentence_starters", []), 3)
        paragraph_transitions = _top(structure_templates.get("paragraph_transitions", []), 2)
        pain_points = _top(audience.get("pain_points_addressed", []), 3)

        emoji_usage = visual.get("emoji_usage", {})
        emoji_list = emoji_usage.get("emojis", [])
        emoji_str = " ".join(_top(emoji_list, 5)) if isinstance(emoji_list, list) else str(emoji_list)

        return f"""STYLE CARD (kompakt, verbindlich):
- Perspektive: {writing_style.get('perspective', 'Ich')}
- Ansprache: {writing_style.get('form_of_address', 'Du')}
- Ton: {tone_analysis.get('primary_tone', writing_style.get('tone', 'Professionell'))}
- Energie: {linguistic.get('energy_level', 7)}/10
- Satz-Dynamik: {writing_style.get('sentence_dynamics', 'Mix')}
- Interpunktion: {linguistic.get('punctuation_patterns', 'Standard')}
- Durchschnittslänge: ca. {writing_style.get('average_word_count', 300)} Wörter
- Hook-Stil Beispiele: {', '.join(hook_phrases) if hook_phrases else 'keine'}
- CTA-Stil Beispiele: {', '.join(cta_phrases) if cta_phrases else 'keine'}
- Übergangsphrasen: {', '.join(transition_phrases) if transition_phrases else 'keine'}
- Emotionale Ausdrücke: {', '.join(emotional_expressions) if emotional_expressions else 'keine'}
- Signature Phrases: {', '.join(signature_phrases) if signature_phrases else 'keine'}
- Narrative Anker: {', '.join(narrative_anchors) if narrative_anchors else 'keine'}
- Typische Bigramme: {', '.join(typical_bigrams) if typical_bigrams else 'keine'}
- Typische Trigramme: {', '.join(typical_trigrams) if typical_trigrams else 'keine'}
- Typische Satzanfänge: {', '.join(sentence_starters) if sentence_starters else 'keine'}
- Übergänge: {', '.join(paragraph_transitions) if paragraph_transitions else 'keine'}
- Emojis: {emoji_str or 'keine'} | Platzierung: {emoji_usage.get('placement', 'Ende')} | Frequenz: {emoji_usage.get('frequency', 'Mittel')}
- Zielgruppe: {audience.get('target_audience', 'Professionals')} | Branche: {audience.get('industry_context', 'Business')}
- Pain Points: {', '.join(pain_points) if pain_points else 'keine'}
- CTA-Logik: {content_strategy.get('cta_style', 'Frage oder Gesprächseinstieg')}
- Story-Ansatz: {content_strategy.get('storytelling_approach', 'persönlich und konkret')}
"""

    def _build_format_card(self, profile_analysis: Dict[str, Any]) -> str:
        """Build a deterministic format card for rules better enforced by prompting and post-processing."""
        def _ensure_dict(value):
            return value if isinstance(value, dict) else {}

        visual = _ensure_dict(profile_analysis.get("visual_patterns", {}))
        emoji_usage = _ensure_dict(visual.get("emoji_usage", {}))
        unicode_formatting = str(visual.get("unicode_formatting", "") or "")
        structure_preferences = str(visual.get("structure_preferences", "Kurze Absätze, mobil-optimiert") or "Kurze Absätze, mobil-optimiert")

        hook_bold = "auto"
        unicode_lower = unicode_formatting.lower()
        if any(token in unicode_lower for token in ["kein fett", "ohne fett", "nie fett", "keine fettung"]):
            hook_bold = "verboten"
        elif any(token in unicode_lower for token in ["fett", "unicode"]):
            hook_bold = "erforderlich"

        return f"""FORMAT CARD (verbindlich):
- Hook-Fettung: {hook_bold}
- Unicode-Hinweis: {unicode_formatting or 'keine klare Vorgabe'}
- Markdown-Fettung: verboten
- Trennlinien: verboten
- Emoji-Frequenz: {emoji_usage.get('frequency', 'Mittel')}
- Emoji-Platzierung: {emoji_usage.get('placement', 'Ende')}
- Layout: {structure_preferences}
- Absatzstil: mobil-optimiert, klare Zeilenumbrüche
"""

    def _get_compact_system_prompt(
        self,
        profile_analysis: Dict[str, Any],
        example_posts: List[str] = None,
        company_strategy: Optional[Dict[str, Any]] = None,
        strategy_weight: float = 0.5
    ) -> str:
        """Short, high-signal system prompt to enforce style without overload."""
        style_card = self._build_style_card(profile_analysis)
        format_card = self._build_format_card(profile_analysis)

        examples_section = ""
        if example_posts:
            sample = example_posts[:2]
            examples_section = "\nECHTE BEISPIELE DIESER KATEGORIE (nur Stil, nicht kopieren):\n"
            for i, post in enumerate(sample, 1):
                post_text = post[:1400] + "..." if len(post) > 1400 else post
                examples_section += f"\n--- Beispiel {i} ---\n{post_text}\n"

        strategy_section = ""
        if company_strategy and strategy_weight >= 0.2:
            content_pillars = company_strategy.get("content_pillars", [])
            brand_voice = company_strategy.get("brand_voice", "")
            tone_guidelines = company_strategy.get("tone_guidelines", "")
            dos = company_strategy.get("dos", [])
            donts = company_strategy.get("donts", [])

            if strategy_weight >= 0.8:
                weight_note = "KRITISCH: Strategie dominiert Inhalt und Stil"
            elif strategy_weight >= 0.6:
                weight_note = "WICHTIG: Strategie klar erkennbar"
            elif strategy_weight >= 0.4:
                weight_note = "MODERAT: Strategie subtil einweben"
            else:
                weight_note = "LEICHT: Strategie nur als Kontext"

            strategy_section = f"""
UNTERNEHMENSKONTEXT ({weight_note}):
- Brand Voice: {brand_voice}
- Tone Guidelines: {tone_guidelines}
- Content Pillars: {', '.join(content_pillars) if content_pillars else 'keine'}
- Do: {', '.join(dos[:3]) if isinstance(dos, list) and dos else 'keine'}
- Don't: {', '.join(donts[:3]) if isinstance(donts, list) and donts else 'keine'}
"""

        return f"""Du bist Ghostwriter für LinkedIn. Schreibe einen Post, der exakt wie die Person klingt.
{style_card}
{format_card}
{strategy_section}
{examples_section}
ARBEITSWEISE:
- Trenne Stil und Inhalt sauber: Inhalt kommt aus Topic, Content-Plan und user_thoughts. Stil kommt aus Style Card und Beispielen.
- Übernimm NICHT die Fakten, Themen oder Beispiele aus den Referenzposts. Übernimm nur Rhythmus, Satzlängen, sprachliche Temperatur, Übergänge, Hook-Logik und CTA-Muster.
- Schreibe zuerst die Kernaussage sauber und logisch. Ziehe erst danach den Stil darüber.
- Wenn Stil und Klarheit kollidieren, bevorzuge klare Aussage und baue den Stil in Hook, Sprachfluss, Übergängen und CTA ein.

STIL-ZIELE:
- Die Person soll beim Lesen sagen: "So würde ich das schreiben."
- Imitiere bevorzugt diese Ebenen: 1. Perspektive und Ansprache, 2. Hook-Muster, 3. Satzrhythmus, 4. typische Übergänge, 5. emotionale Färbung, 6. CTA-Muster.
- Nutze Signature Phrases, typische Wortkombinationen und emotionale Ausdrücke nur punktuell. Wenige präzise Treffer sind besser als sichtbares Overfitting.
- Falls die Beispiele eher roh, direkt, knapp oder kantig klingen, glätte den Text NICHT künstlich.
- Falls die Beispiele eher reflektiert, ruhig oder analytisch sind, vermeide künstliche Dramatik.

INHALTS-SCHUTZ:
- Kernaussage, Argumentationslogik und Mehrwert dürfen durch die Stil-Imitation NICHT schwächer werden.
- Keine metaphorischen Ausschmückungen, wenn sie den Punkt unklarer machen.
- Keine Hook-Spielereien, wenn dadurch die eigentliche Aussage verwässert.
- Jede Formulierung muss sowohl stilistisch passend als auch inhaltlich sinnvoll sein.

REGELN:
- Inhalt strikt an den Content-Plan halten, keine neuen Fakten erfinden
- Perspektive und Ansprache strikt einhalten
- FORMAT CARD strikt einhalten, auch wenn das Modell stilistisch etwas anderes bevorzugen würde
- Hook, Struktur, Übergänge und CTA am Profil und den zwei Kategorie-Beispielen ausrichten
- Nutze typische Wortkombinationen und narrative Anker organisch, nie mechanisch
- Schmerzpunkte der Zielgruppe konkret adressieren
- Keine KI-Phrasen ("In der heutigen Zeit", "Stellen Sie sich vor", etc.)
- Keine Markdown-Fettung (kein **), keine Trennlinien (---)
- Ausgabe: Nur der fertige Post"""

    def _get_system_prompt(
        self,
        profile_analysis: Dict[str, Any],
        example_posts: List[str] = None,
        learned_lessons: Optional[Dict[str, Any]] = None,
        post_type: Any = None,
        post_type_analysis: Optional[Dict[str, Any]] = None,
        company_strategy: Optional[Dict[str, Any]] = None,
        strategy_weight: float = 0.5
    ) -> str:
        """Get system prompt for writer - orientiert an bewährten n8n-Prompts."""
        # Extract key profile information
        writing_style = profile_analysis.get("writing_style", {})
        linguistic = profile_analysis.get("linguistic_fingerprint", {})
        tone_analysis = profile_analysis.get("tone_analysis", {})
        visual = profile_analysis.get("visual_patterns", {})
        content_strategy = profile_analysis.get("content_strategy", {})
        audience = profile_analysis.get("audience_insights", {})
        phrase_library = profile_analysis.get("phrase_library", {})
        structure_templates = profile_analysis.get("structure_templates", {})

        def _ensure_dict(value):
            return value if isinstance(value, dict) else {}

        def _extract_from_list(items, key):
            if not isinstance(items, list):
                return None
            prefix = f"{key}:"
            for item in items:
                text = str(item)
                if text.lower().startswith(prefix):
                    return text.split(":", 1)[1].strip()
            return None

        def _extract_list_from_list(items, key):
            value = _extract_from_list(items, key)
            if not value:
                return []
            return [part.strip() for part in value.split(",") if part.strip()]

        def _extract_emojis(text: str) -> list:
            if not text:
                return []
            pattern = r"[\U0001F300-\U0001FAFF]"
            matches = re.findall(pattern, text)
            return matches or []

        # Normalize optional sections
        visual_dict = _ensure_dict(visual)
        content_strategy_dict = _ensure_dict(content_strategy)
        structure_templates_dict = _ensure_dict(structure_templates)

        # Build example posts section (OPTIMIERT: mehr Kontext, weniger kürzen)
        examples_section = ""
        if example_posts and len(example_posts) > 0:
            examples_section = "\n\nREFERENZ-POSTS DER PERSON (Orientiere dich am Stil!):\n"
            for i, post in enumerate(example_posts, 1):
                # Erhöht von 1800 auf 3000 für mehr Kontext
                post_text = post[:3000] + "..." if len(post) > 3000 else post
                examples_section += f"\n--- Beispiel {i} ---\n{post_text}\n"
            examples_section += "--- Ende Beispiele ---\n"

        # Safe extraction of nested values
        if isinstance(visual, list):
            emojis = []
            for item in visual:
                emojis.extend(_extract_emojis(str(item)))
            emoji_list = emojis if emojis else ['🚀']
        else:
            emoji_list = visual_dict.get('emoji_usage', {}).get('emojis', ['🚀'])
        emoji_str = ' '.join(emoji_list) if isinstance(emoji_list, list) else str(emoji_list)
        sig_phrases = linguistic.get('signature_phrases', [])
        narrative_anchors = linguistic.get('narrative_anchors', [])
        narrative_str = ', '.join(narrative_anchors) if narrative_anchors else 'Storytelling'
        pain_points = audience.get('pain_points_addressed', [])
        pain_points_str = ', '.join(pain_points) if pain_points else 'Branchenspezifische Herausforderungen'

        # Extract phrase library with variation instruction
        hook_phrases = phrase_library.get('hook_phrases', [])
        transition_phrases = phrase_library.get('transition_phrases', [])
        emotional_expressions = phrase_library.get('emotional_expressions', [])
        cta_phrases = phrase_library.get('cta_phrases', [])
        filler_expressions = phrase_library.get('filler_expressions', [])

        # Randomly select a subset of phrases for this post (variation!)
        # OPTIMIERT: Von 3-4 auf 5-6 erhöht für mehr Kontext
        def select_phrases(phrases: list, max_count: int = 6) -> str:
            if not phrases:
                return "Keine verfügbar"
            selected = random.sample(phrases, min(max_count, len(phrases)))
            return '\n  - '.join(selected)

        # Extract structure templates
        if isinstance(structure_templates, list):
            primary_structure = _extract_from_list(structure_templates, "primary_structure") or "Hook → Body → CTA"
            sentence_starters = _extract_list_from_list(structure_templates, "typical_sentence_starters")
            paragraph_transitions = _extract_list_from_list(structure_templates, "paragraph_transitions")
        else:
            primary_structure = structure_templates_dict.get('primary_structure', 'Hook → Body → CTA')
            sentence_starters = structure_templates_dict.get('typical_sentence_starters', [])
            paragraph_transitions = structure_templates_dict.get('paragraph_transitions', [])

        if isinstance(content_strategy, list):
            content_strategy_dict = {
                "cta_style": _extract_from_list(content_strategy, "cta_style") or "Interaktive Frage an die Community",
                "hook_patterns": _extract_from_list(content_strategy, "hook_patterns"),
                "post_structure": _extract_from_list(content_strategy, "post_structure"),
                "storytelling_approach": _extract_from_list(content_strategy, "storytelling_approach"),
            }

        # Extract N-gram patterns if available (NEU!)
        ngram_patterns = profile_analysis.get("ngram_patterns", {})
        typical_bigrams = ngram_patterns.get("typical_bigrams", [])
        typical_trigrams = ngram_patterns.get("typical_trigrams", [])
        signature_combinations = ngram_patterns.get("signature_combinations", [])

        # Build N-gram section (NEU!)
        ngram_section = ""
        if typical_bigrams or typical_trigrams or signature_combinations:
            ngram_section = f"""

2a. TYPISCHE WORTKOMBINATIONEN (Stilistisches Fingerprinting - WICHTIG!):

Diese Wortkombinationen sind charakteristisch für den Schreibstil der Person.
Baue 3-5 dieser Kombinationen NATÜRLICH in den Post ein!

TYPISCHE 2-WORT-KOMBINATIONEN (Bigrams):
  {', '.join(typical_bigrams[:20])}

TYPISCHE 3-WORT-KOMBINATIONEN (Trigrams):
  {', '.join(typical_trigrams[:15])}

SIGNATURE-KOMBINATIONEN (besonders charakteristisch):
  {', '.join(signature_combinations[:10])}

WICHTIG: Diese Kombinationen machen den Stil authentisch! Nutze sie organisch im Text.
"""

        # Build phrase library section
        phrase_section = ""
        if hook_phrases or emotional_expressions or cta_phrases:
            phrase_section = f"""

2b. PHRASEN-BIBLIOTHEK (Wähle passende aus - NICHT alle verwenden!):

HOOK-VORLAGEN (lass dich inspirieren, kopiere nicht 1:1):
  - {select_phrases(hook_phrases, 5)}

ÜBERGANGS-PHRASEN (nutze 1-2 davon):
  - {select_phrases(transition_phrases, 4)}

EMOTIONALE AUSDRÜCKE (nutze 1-2 passende):
  - {select_phrases(emotional_expressions, 5)}

CTA-FORMULIERUNGEN (wähle eine passende):
  - {select_phrases(cta_phrases, 4)}

FÜLL-AUSDRÜCKE (für natürlichen Flow):
  - {select_phrases(filler_expressions, 4)}

SIGNATURE PHRASES (nutze maximal 1-2 ORGANISCH):
  - {select_phrases(sig_phrases, 5)}

WICHTIG: Variiere! Nutze NICHT immer die gleichen Phrasen. Wähle die, die zum Thema passen.
"""

        # Build structure section
        structure_section = f"""

3. STRUKTUR-TEMPLATE:

Primäre Struktur: {primary_structure}

Typische Satzanfänge (nutze ähnliche):
  - {select_phrases(sentence_starters, 4)}

Absatz-Übergänge:
  - {select_phrases(paragraph_transitions, 3)}
"""

        # Build lessons learned section (from past feedback)
        lessons_section = ""
        if learned_lessons and learned_lessons.get("lessons"):
            lessons_section = "\n\n6. LESSONS LEARNED (aus vergangenen Posts - BEACHTE DIESE!):\n"
            patterns = learned_lessons.get("patterns", {})
            if patterns.get("posts_analyzed", 0) > 0:
                lessons_section += f"\n(Basierend auf {patterns.get('posts_analyzed', 0)} analysierten Posts, Durchschnittsscore: {patterns.get('avg_score', 0):.0f}/100)\n"

            for lesson in learned_lessons["lessons"]:
                if lesson["type"] == "critical":
                    lessons_section += f"\n⚠️ KRITISCH - {lesson['message']}\n"
                    for item in lesson["items"]:
                        lessons_section += f"  ❌ {item}\n"
                elif lesson["type"] == "recurring":
                    lessons_section += f"\n📝 {lesson['message']}\n"
                    for item in lesson["items"]:
                        lessons_section += f"  • {item}\n"

            lessons_section += "\nBerücksichtige diese Punkte PROAKTIV beim Schreiben!"

        # Build post type section
        post_type_section = ""
        if post_type:
            post_type_section = f"""

7. POST-TYP SPEZIFISCH: {post_type.name}
{f"Beschreibung: {post_type.description}" if post_type.description else ""}
"""
            if post_type_analysis and post_type_analysis.get("sufficient_data"):
                # Use the PostTypeAnalyzerAgent's helper method to generate the section
                from src.agents.post_type_analyzer import PostTypeAnalyzerAgent
                analyzer = PostTypeAnalyzerAgent()
                type_guidelines = analyzer.get_writing_prompt_section(post_type_analysis)
                if type_guidelines:
                    post_type_section += f"""
=== POST-TYP ANALYSE & RICHTLINIEN ===
{type_guidelines}
=== ENDE POST-TYP RICHTLINIEN ===

WICHTIG: Dieser Post MUSS den Mustern und Richtlinien dieses Post-Typs folgen!
"""

        return f"""ROLLE: Du bist ein erstklassiger Ghostwriter für LinkedIn. Deine Aufgabe ist es, einen Post zu schreiben, der exakt so klingt wie der digitale Zwilling der beschriebenen Person. Du passt dich zu 100% an das bereitgestellte Profil an.

=== SCHREIB-PROZESS (Chain-of-Thought - Denke Schritt für Schritt!) ===

VOR DEM SCHREIBEN - ANALYSIERE & PLANE:

SCHRITT 1 - STIL-ANALYSE:
Analysiere die Referenz-Posts und Muster:
- Welche Wortkombinationen sind typisch? (siehe N-gram Patterns)
- Welche Satzstrukturen verwendet die Person?
- Wie ist der emotionale Ton und das Energie-Level?
- Welche Signature-Kombinationen fallen auf?

SCHRITT 2 - CONTENT-PLANUNG:
Plane den Post-Inhalt:
- Hook-Strategie: Welcher Hook-Typ passt zum Thema UND zur Person?
- Kernbotschaft: Was ist die ONE key message?
- Struktur: Welches Template aus den Referenz-Posts passt am besten?
- Logischer Fluss: Macht der Argumentationsaufbau Sinn?

SCHRITT 3 - SINNIGKEITS-CHECK (KRITISCH!):
Prüfe BEVOR du schreibst:
- Ist die Kernaussage klar, logisch und nachvollziehbar?
- Passen alle Argumente zusammen? Gibt es Widersprüche?
- Sind die Fakten korrekt verknüpft? (Keine nicht-zusammenhängenden Dinge verbinden!)
- Ist der Mehrwert für den Leser offensichtlich?
- Würde die echte Person SO argumentieren?

SCHRITT 4 - SCHREIBEN:
Jetzt schreibe den Post unter Berücksichtigung von Schritt 1-3.
Baue 3-5 der typischen Wortkombinationen organisch ein!

WICHTIG: Wenn etwas in Schritt 3 nicht "Sinn macht" - STOPP und überdenke den Angle!
{examples_section}

1. STIL & ENERGIE:

Energie-Level (1-10): {linguistic.get('energy_level', 7)}
(WICHTIG: Passe die Intensität und Leidenschaft des Textes EXAKT an diesen Wert an. Bei 9-10 = hochemotional, bei 5-6 = sachlich-professionell)

Rhetorisches Shouting: {linguistic.get('shouting_usage', 'Dezent')}
(Nutze GROSSBUCHSTABEN für einzelne Wörter genau so wie hier beschrieben, um Emphase zu erzeugen - mach das für KEINE anderen Wörter!)

Tonalität: {tone_analysis.get('primary_tone', 'Professionell und authentisch')}

Ansprache (STRENGSTENS EINHALTEN): {writing_style.get('form_of_address', 'Du/Euch')}

Perspektive (STRENGSTENS EINHALTEN): {writing_style.get('perspective', 'Ich-Perspektive')}

Satz-Dynamik: {writing_style.get('sentence_dynamics', 'Mix aus kurzen und längeren Sätzen')}
Interpunktion: {linguistic.get('punctuation_patterns', 'Standard')}

Branche: {audience.get('industry_context', 'Business')}

Zielgruppe: {audience.get('target_audience', 'Professionals')}
{ngram_section}
{phrase_section}
{structure_section}

4. VISUELLE REGELN:

Unicode-Fettung: Nutze für den ersten Satz (Hook) fette Unicode-Zeichen (z.B. 𝗪𝗶𝗰𝗵𝘁𝗶𝗴𝗲𝗿 𝗦𝗮𝘁𝘇), sofern das zur Person passt: {visual_dict.get('unicode_formatting', _extract_from_list(visual, 'unicode_formatting') if isinstance(visual, list) else 'Fett für Hooks')}

Emoji-Logik: Verwende diese Emojis: {emoji_str}
Platzierung: {visual_dict.get('emoji_usage', {}).get('placement', _extract_from_list(visual, 'emoji_usage') if isinstance(visual, list) else 'Ende')}
Häufigkeit: {visual_dict.get('emoji_usage', {}).get('frequency', 'Mittel')}

Erzähl-Anker: Baue Elemente ein wie: {narrative_str}
(Falls 'PS-Zeilen', 'Dialoge' oder 'Flashbacks' genannt sind, integriere diese wenn es passt.)

Layout: {visual_dict.get('structure_preferences', _extract_from_list(visual, 'structure_preferences') if isinstance(visual, list) else 'Kurze Absätze, mobil-optimiert')}

Länge: Ca. {writing_style.get('average_word_count', 300)} Wörter

CTA: Beende den Post mit einer Variante von: {content_strategy_dict.get('cta_style', 'Interaktive Frage an die Community')}


5. GUARDRAILS (VERBOTE!):

Vermeide IMMER diese KI-typischen Muster:
- "In der heutigen Zeit", "Tauchen Sie ein", "Es ist kein Geheimnis"
- "Stellen Sie sich vor", "Lassen Sie uns", "Es ist wichtig zu verstehen"
- Gedankenstriche (–) zur Satzverbindung - nutze stattdessen Kommas oder Punkte
- Belehrende Formulierungen wenn die Person eine Ich-Perspektive nutzt
- Übertriebene Superlative ohne Substanz
- Zu perfekte, glatte Formulierungen - echte Menschen schreiben mit Ecken und Kanten
{lessons_section}
{post_type_section}
{self._get_company_strategy_section(company_strategy, strategy_weight)}
DEIN AUFTRAG: Schreibe den Post so, dass er für die Zielgruppe ({audience.get('target_audience', 'Professionals')}) einen klaren Mehrwert bietet und ihre Pain Points ({pain_points_str}) adressiert. Mach die Persönlichkeit des linguistischen Fingerabdrucks spürbar.

Beginne DIREKT mit dem Hook. Keine einleitenden Sätze, kein "Hier ist der Post"."""

    def _get_company_strategy_section(self, company_strategy: Optional[Dict[str, Any]] = None, strategy_weight: float = 0.5) -> str:
        """Build the company strategy section for the system prompt with weighted influence."""
        if not company_strategy:
            return ""

        # Extract strategy elements
        mission = company_strategy.get("mission", "")
        vision = company_strategy.get("vision", "")
        brand_voice = company_strategy.get("brand_voice", "")
        tone_guidelines = company_strategy.get("tone_guidelines", "")
        content_pillars = company_strategy.get("content_pillars", [])
        target_audience = company_strategy.get("target_audience", "")
        dos = company_strategy.get("dos", [])
        donts = company_strategy.get("donts", [])

        # Build section only if there's meaningful content
        if not any([mission, vision, brand_voice, content_pillars, dos, donts]):
            return ""

        # Determine importance level and instruction based on strategy_weight
        if strategy_weight >= 0.8:
            importance = "KRITISCH WICHTIG - STRIKT BEFOLGEN"
            instruction = "Der Post MUSS sich eng an die Unternehmensstrategie halten! Die Strategy-Guidelines haben höchste Priorität."
        elif strategy_weight >= 0.6:
            importance = "WICHTIG - BEACHTEN"
            instruction = "Integriere die Unternehmenswerte deutlich, aber bewahre Authentizität! Die Strategie soll klar erkennbar sein."
        elif strategy_weight >= 0.4:
            importance = "ALS KONTEXT BERÜCKSICHTIGEN"
            instruction = "Berücksichtige die Strategie wo sinnvoll - Persönlicher Stil hat Priorität! Subtile Integration genügt."
        elif strategy_weight >= 0.2:
            importance = "OPTIONALE ORIENTIERUNG"
            instruction = "Die Strategie dient als Hintergrundinformation - freie Interpretation erlaubt! Fokus auf Authentizität."
        else:
            importance = "NUR ALS REFERENZ"
            instruction = "Ignoriere die Strategie weitgehend - voller Fokus auf persönlichen Stil! Strategy-Guidelines sind optional."

        section = f"""

8. UNTERNEHMENSSTRATEGIE ({importance}):

Strategy Weight: {strategy_weight:.1f} / 1.0
{instruction}
"""
        if mission:
            section += f"\nMISSION: {mission}"
        if vision:
            section += f"\nVISION: {vision}"
        if brand_voice:
            section += f"\nBRAND VOICE: {brand_voice}"
        if tone_guidelines:
            section += f"\nTONE GUIDELINES: {tone_guidelines}"
        if content_pillars:
            section += f"\nCONTENT PILLARS: {', '.join(content_pillars)}"
        if target_audience:
            section += f"\nZIELGRUPPE: {target_audience}"
        if dos:
            section += f"\n\nDO's (empfohlen):\n" + "\n".join([f"  + {d}" for d in dos])
        if donts:
            section += f"\n\nDON'Ts (vermeiden):\n" + "\n".join([f"  - {d}" for d in donts])

        # Weight-specific closing instruction
        if strategy_weight >= 0.8:
            section += "\n\nKRITISCH: Die Unternehmensstrategie ist nicht verhandelbar - jeder Post muss diese widerspiegeln!"
        elif strategy_weight >= 0.6:
            section += "\n\nWICHTIG: Stelle sicher, dass die Unternehmenswerte deutlich erkennbar sind!"
        elif strategy_weight >= 0.4:
            section += "\n\nINTEGRIERE: Berücksichtige die Strategie subtil - authentischer Stil bleibt wichtig!"
        else:
            section += "\n\nREFERENZ: Die Strategie dient nur als Orientierung - persönlicher Stil hat Vorrang!"

        return section

    def _get_user_prompt(
        self,
        topic: Dict[str, Any],
        feedback: Optional[str] = None,
        previous_version: Optional[str] = None,
        critic_result: Optional[Dict[str, Any]] = None,
        user_thoughts: str = "",
        selected_hook: str = ""
    ) -> str:
        """Get user prompt for writer."""
        if feedback and previous_version:
            # Build specific changes section
            specific_changes_text = ""
            if critic_result and critic_result.get("specific_changes"):
                specific_changes_text = "\n**KONKRETE ÄNDERUNGEN (FÜHRE DIESE EXAKT DURCH!):**\n"
                for i, change in enumerate(critic_result["specific_changes"], 1):
                    specific_changes_text += f"\n{i}. ERSETZE:\n"
                    specific_changes_text += f"   \"{change.get('original', '')}\"\n"
                    specific_changes_text += f"   MIT:\n"
                    specific_changes_text += f"   \"{change.get('replacement', '')}\"\n"
                    if change.get('reason'):
                        specific_changes_text += f"   (Grund: {change.get('reason')})\n"

            # Build improvements section
            improvements_text = ""
            if critic_result and critic_result.get("improvements"):
                improvements_text = "\n**WEITERE VERBESSERUNGEN:**\n"
                for imp in critic_result["improvements"]:
                    improvements_text += f"- {imp}\n"

            # Revision mode with structured feedback
            score_text = f"**AKTUELLER SCORE:** {critic_result.get('overall_score', 'N/A')}/100\n\n" if critic_result else ""

            plan_section = ""
            if topic.get("content_plan"):
                plan = topic.get("content_plan") or {}
                alignment = plan.get("company_alignment") or []
                alignment_section = ""
                if isinstance(alignment, list) and alignment:
                    alignment_section = "\n**STRATEGIE-ANFORDERUNGEN (VERBINDLICH):**\n" + "\n".join([f"- {a}" for a in alignment]) + "\n"
                plan_section = f"\n**CONTENT-PLAN (VERBINDLICH):**\n{json.dumps(plan, ensure_ascii=False, indent=2)}\n{alignment_section}"

            return f"""ÜBERARBEITE den Post basierend auf dem Feedback.

**VORHERIGE VERSION:**
{previous_version}

{score_text}**FEEDBACK:**
{feedback}
{specific_changes_text}
{improvements_text}
{plan_section}
**DEINE AUFGABE:**
1. Führe die Änderungen durch wie im Feedback beschrieben
2. Behalte alles bei was gut funktioniert
3. Der überarbeitete Post soll die Anforderungen erfüllen

Gib NUR den überarbeiteten Post zurück - keine Kommentare."""

        else:
            # Initial writing mode - enhanced with new topic fields
            angle_section = ""
            if topic.get('angle'):
                angle_section = f"\n**ANGLE/PERSPEKTIVE:**\n{topic.get('angle')}\n"

            # User-selected hook takes priority over topic hook_idea
            hook_section = ""
            if selected_hook:
                hook_section = f"\n**HOOK (VERWENDE DIESEN ALS EINSTIEG!):**\n\"{selected_hook}\"\n"
            elif topic.get('hook_idea'):
                hook_section = f"\n**HOOK-IDEE (als Inspiration):**\n\"{topic.get('hook_idea')}\"\n"

            facts_section = ""
            key_facts = topic.get('key_facts', [])
            if key_facts and isinstance(key_facts, list) and len(key_facts) > 0:
                facts_section = "\n**KEY FACTS (nutze diese!):**\n" + "\n".join([f"- {f}" for f in key_facts]) + "\n"

            summary_section = ""
            if topic.get('summary'):
                summary_section = f"\n**ZUSAMMENFASSUNG (vom Link):**\n{topic.get('summary')}\n"

            extended_summary_section = ""
            if topic.get('extended_summary'):
                extended_summary_section = f"\n**DETAILLIERTE ZUSAMMENFASSUNG:**\n{topic.get('extended_summary')}\n"

            outline_section = ""
            outline = topic.get('outline', [])
            if outline and isinstance(outline, list) and len(outline) > 0:
                outline_section = "\n**INHALTS-GLIEDERUNG:**\n" + "\n".join([f"- {o}" for o in outline]) + "\n"

            key_points_section = ""
            key_points = topic.get('key_points', [])
            if key_points and isinstance(key_points, list) and len(key_points) > 0:
                key_points_section = "\n**KERNPUNKTE (vom Link):**\n" + "\n".join([f"- {p}" for p in key_points]) + "\n"

            quotes_section = ""
            quotes = topic.get('quotes', [])
            if quotes and isinstance(quotes, list) and len(quotes) > 0:
                quotes_section = "\n**ZITATE (optional verwenden):**\n" + "\n".join([f"- \"{q}\"" for q in quotes]) + "\n"

            source_section = ""
            if topic.get('source_title') or topic.get('source'):
                source_title = topic.get('source_title') or ""
                source_url = topic.get('source') or ""
                source_section = f"\n**QUELLE:** {source_title} {source_url}\n"

            plan_section = ""
            if topic.get("content_plan"):
                plan_section = f"\n**CONTENT-PLAN (VERBINDLICH):**\n{json.dumps(topic.get('content_plan'), ensure_ascii=False, indent=2)}\n"

            # User thoughts section
            thoughts_section = ""
            if user_thoughts:
                thoughts_section = f"""
**PERSÖNLICHE GEDANKEN (UNBEDINGT einbauen!):**
{user_thoughts}

Diese Gedanken MÜSSEN im Post verarbeitet werden - sie spiegeln die echte Meinung der Person wider!
"""

            # Adjust task based on whether hook is provided
            if selected_hook:
                task_section = """**AUFGABE:**
Schreibe einen authentischen LinkedIn-Post, der:
1. Mit dem VORGEGEBENEN HOOK beginnt (exakt oder leicht angepasst)
2. Den Fakt/das Thema aufgreift und Mehrwert bietet
3. Die persönlichen Gedanken organisch einbaut
4. Die Key Facts verwendet wo es passt
5. Mit einem passenden CTA endet"""
            else:
                task_section = """**AUFGABE:**
Schreibe einen authentischen LinkedIn-Post, der:
1. Mit einem STARKEN, unerwarteten Hook beginnt (nutze Hook-Idee als Inspiration!)
2. Den Fakt/das Thema aufgreift und Mehrwert bietet
3. Die persönlichen Gedanken organisch einbaut (falls vorhanden)
4. Die Key Facts verwendet wo es passt
5. Mit einem passenden CTA endet"""

            content_plan_note = ""
            if topic.get("content_plan"):
                plan = topic.get("content_plan") or {}
                tier = plan.get("quality_tier")
                required = plan.get("required_elements") or []
                req_text = ", ".join(required[:6]) if isinstance(required, list) else ""
                tier_text = f" | Qualitätsziel: {tier}" if tier else ""
                req_note = f" | Pflichtelemente: {req_text}" if req_text else ""
                content_plan_note = f"\n- CONTENT-PLAN ist verbindlich: Nutze NUR diese Fakten, keine neuen hinzufügen{tier_text}{req_note}"

            return f"""Schreibe einen LinkedIn-Post zu folgendem Thema:

**THEMA:** {topic.get('title', 'Unbekanntes Thema')}

**KATEGORIE:** {topic.get('category', 'Allgemein')}
{angle_section}{hook_section}
**KERN-FAKT / INHALT:**
{topic.get('fact', topic.get('description', ''))}
{summary_section}{extended_summary_section}{outline_section}{key_points_section}{facts_section}{quotes_section}{source_section}{plan_section}{thoughts_section}
**WARUM RELEVANT:**
{topic.get('relevance', 'Aktuelles Thema für die Zielgruppe')}

{task_section}

WICHTIG:
- Vermeide KI-typische Formulierungen ("In der heutigen Zeit", "Tauchen Sie ein", etc.)
- Schreibe natürlich und menschlich
- Der Post soll SOFORT 85+ Punkte im Review erreichen
{content_plan_note}

Gib NUR den fertigen Post zurück."""

    async def generate_hooks(
        self,
        topic: Dict[str, Any],
        profile_analysis: Dict[str, Any],
        user_thoughts: str = "",
        post_type: Any = None
    ) -> List[Dict[str, str]]:
        """
        Generate 4 high-quality hook options for a topic.

        Args:
            topic: Topic dictionary with title, fact, etc.
            profile_analysis: Profile analysis for style matching
            user_thoughts: User's personal thoughts about the topic
            post_type: Optional PostType object

        Returns:
            List of {"hook": "...", "style": "..."} dictionaries
        """
        logger.info(f"Generating hooks for topic: {topic.get('title', 'Unknown')}")

        # Extract style info from profile
        tone = profile_analysis.get('tone_analysis', {}).get('primary_tone', 'Professionell')
        energy = profile_analysis.get('linguistic_fingerprint', {}).get('energy_level', 7)
        address = profile_analysis.get('writing_style', {}).get('form_of_address', 'Du')
        hook_phrases = profile_analysis.get('phrase_library', {}).get('hook_phrases', [])

        # Build example hooks section
        example_hooks = ""
        if hook_phrases:
            example_hooks = "\n\nBeispiel-Hooks dieser Person (Muster erkennen, NICHT kopieren):\n" + "\n".join([f"- {h}" for h in hook_phrases[:8]])

        anchor_terms = self._extract_hook_anchor_terms(topic, user_thoughts)
        anchor_terms_text = ", ".join(anchor_terms[:10]) if anchor_terms else "keine"
        format_card = self._build_format_card(profile_analysis)
        source_context = ""
        if topic.get("source") or topic.get("source_title") or topic.get("source_quality"):
            source_context = f"""

QUELLENKONTEXT:
- Quelle: {topic.get('source_title') or topic.get('source') or 'unbekannt'}
- Quellenqualität: {topic.get('source_quality') or topic.get('source_tier') or 'nicht klassifiziert'}
- Datum/Zeitraum: {topic.get('published_at') or 'nicht angegeben'}
"""
        person_fit = topic.get("why_this_person") or topic.get("fit_reason") or topic.get("relevance") or ""

        system_prompt = f"""Du bist ein Hook-Spezialist für LinkedIn Posts. Deine Aufgabe ist es, HOCHWERTIGE Hooks zu generieren, die konkret, sinnvoll und stiltreu sind.

STIL DER PERSON:
- Tonalität: {tone}
- Energie-Level: {energy}/10 (höher = emotionaler, niedriger = sachlicher)
- Ansprache: {address}
{example_hooks}
{format_card}
{source_context}

NICHT VERHANDELBAR:
- Jeder Hook muss auf dem tatsächlichen Inhalt basieren, nicht auf leerer Aufmerksamkeit.
- Kein generischer Einstieg. Kein austauschbares "Die meisten unterschätzen...", "Was wäre wenn...", "X verändert alles", wenn das nicht konkret begründet ist.
- Keine leeren LinkedIn-Templates wie "Niemand spricht darüber", "Unpopular opinion", "Ich muss ehrlich sein", "Das verändert alles".
- Kein Cliffhanger ohne klare inhaltliche Verbindung.
- Kein Fakt behaupten, der im Input nicht enthalten ist.
- Wenn ein Hook provokant ist, muss die Provokation logisch aus dem Thema ableitbar sein.
- Wenn ein Hook storytelling ist, muss er wie ein glaubwürdiger Einstieg in die Perspektive der Person wirken.
- Der Hook muss auch OHNE den Rest des Posts Sinn ergeben.
- Hook darf nicht klingen wie eine Überschrift, sondern wie ein echter erster Satz der Person.
- Wenn die Person eher sachlich schreibt, keine künstliche Dramatisierung.

GENERIERE 12 VERSCHIEDENE HOOK-KANDIDATEN:
- 2x Pointierte Beobachtung
- 2x Konkreter Daten-/Quellenanker
- 2x Persönliche Einordnung
- 2x Konträrer Take
- 2x Problem-/Spannungsbogen
- 2x Ruhige Expertenbeobachtung

REGELN:
- Jeder Hook sollte 1-2 Sätze lang sein
- Hooks müssen zum Energie-Level und Ton der Person passen
- Keine KI-typischen Phrasen ("In der heutigen Zeit", "Stellen Sie sich vor")
- Die Hooks sollen Aufmerksamkeit erzeugen, aber nur mit echter Substanz
- Bei Energie 8+ darf es emotional/leidenschaftlich sein
- Bei Energie 5-7 eher sachlich-professionell
- Nutze nach Möglichkeit mindestens einen dieser inhaltlichen Anker: {anchor_terms_text}
- Nutze bevorzugt einen konkreten Fakt, ein klares Spannungsfeld oder die glaubwürdige Perspektive der Person
- Wenn Hook-Fettung laut Format Card erforderlich ist, formatiere nur den Hook selbst passend. Kein Markdown.

Antworte im JSON-Format:
{{"hooks": [
  {{"hook": "Der Hook-Text hier", "style": "Pointiert", "anchor": "konkreter Fakt/Gedanke dahinter", "fit": "warum passt das zur Person"}},
  {{"hook": "Der Hook-Text hier", "style": "Datenanker", "anchor": "konkreter Fakt/Gedanke dahinter", "fit": "warum passt das zur Person"}}
]}}"""

        # Build user prompt
        thoughts_section = ""
        if user_thoughts:
            thoughts_section = f"\n\nPERSÖNLICHE GEDANKEN DER PERSON ZUM THEMA:\n{user_thoughts}\n\nIntegriere diese Perspektive in die Hooks!"

        post_type_section = ""
        if post_type:
            post_type_section = f"\n\nPOST-TYP: {post_type.name}"
            if post_type.description:
                post_type_section += f"\n{post_type.description}"

        content_block = topic.get('fact', topic.get('description', 'Keine Details verfügbar'))
        if topic.get('angle'):
            content_block += f"\n\nANGLE:\n{topic.get('angle')}"
        if person_fit:
            content_block += f"\n\nWARUM DIESE PERSON:\n{person_fit}"
        if topic.get('summary'):
            content_block += f"\n\nZUSAMMENFASSUNG:\n{topic.get('summary')}"
        if topic.get('extended_summary'):
            content_block += f"\n\nDETAILLIERTE ZUSAMMENFASSUNG:\n{topic.get('extended_summary')}"
        if topic.get('outline') and isinstance(topic.get('outline'), list):
            content_block += "\n\nGLIEDERUNG:\n" + "\n".join([f"- {o}" for o in topic.get('outline', [])])
        if topic.get('key_points') and isinstance(topic.get('key_points'), list):
            content_block += "\n\nKERNPUNKTE:\n" + "\n".join([f"- {p}" for p in topic.get('key_points', [])])
        if topic.get('key_facts') and isinstance(topic.get('key_facts'), list):
            content_block += "\n\nKEY FACTS:\n" + "\n".join([f"- {p}" for p in topic.get('key_facts', [])])
        if topic.get('evidence') and isinstance(topic.get('evidence'), list):
            content_block += "\n\nBELEGE:\n" + "\n".join([f"- {p}" for p in topic.get('evidence', [])])

        user_prompt = f"""Generiere 12 Hook-Kandidaten für dieses Thema:

THEMA: {topic.get('title', 'Unbekanntes Thema')}

KATEGORIE: {topic.get('category', 'Allgemein')}

KERN-FAKT/INHALT:
{content_block}
{thoughts_section}{post_type_section}

WICHTIGE ANKERBEGRIFFE:
{anchor_terms_text}

Wähle keine generischen Einstiege. Jeder Kandidat muss an einem konkreten Fakt, Angle oder persönlichen Gedanken hängen.

Generiere jetzt die 12 verschiedenen Hooks im JSON-Format."""

        response = await self.call_azure_claude(
            system_prompt=system_prompt,
            user_prompt=user_prompt,
            model=settings.azure_claude_model,
            temperature=0.6,
            response_format={"type": "json_object"}
        )

        try:
            result = self._parse_json_response(response)
            hooks = result.get("hooks", [])
            hooks = self._select_best_hooks(hooks, topic, user_thoughts)
            if len(hooks) < 4:
                raise ValueError("Too few valid hooks after filtering")
            logger.info(f"Generated {len(hooks)} hooks successfully")
            return hooks
        except (json.JSONDecodeError, KeyError, ValueError) as e:
            logger.error(f"Failed to parse hooks response: {e}")
            title = str(topic.get("title", "dieser Entwicklung") or "dieser Entwicklung")
            fact = str(topic.get("fact", "dieser Punkt") or "dieser Punkt")
            return [
                {"hook": f"An {title} ist für mich nicht die Schlagzeile entscheidend. Sondern die Verschiebung dahinter.", "style": "Pointiert"},
                {"hook": f"Mich interessiert an {title} weniger der Hype als die Frage, was sich dadurch real verändert.", "style": "Reflektiert"},
                {"hook": f"Wenn {fact} stimmt, ist das deutlich mehr als nur eine Randnotiz.", "style": "Fakten-basiert"},
                {"hook": f"Die spannende Frage ist nicht, ob {title} relevant ist. Sondern was daraus jetzt konkret folgt.", "style": "Neugier-weckend"}
            ]

    def _extract_hook_anchor_terms(self, topic: Dict[str, Any], user_thoughts: str = "") -> List[str]:
        """Extract concrete anchor terms so hooks stay tied to the actual topic."""
        candidates: List[str] = []

        def add_text(value: Any):
            if isinstance(value, str) and value.strip():
                candidates.append(value.strip())
            elif isinstance(value, list):
                for item in value[:8]:
                    if isinstance(item, str) and item.strip():
                        candidates.append(item.strip())

        add_text(topic.get("title"))
        add_text(topic.get("fact"))
        add_text(topic.get("summary"))
        add_text(topic.get("extended_summary"))
        add_text(topic.get("key_points"))
        add_text(topic.get("key_facts"))
        add_text(user_thoughts)

        blob = " ".join(candidates).lower()
        words = re.findall(r"\b[a-zA-ZäöüÄÖÜß0-9][a-zA-ZäöüÄÖÜß0-9\-/]{2,}\b", blob)
        stop_words = {
            "der", "die", "das", "und", "oder", "aber", "eine", "einer", "einem", "einen",
            "thema", "heute", "diese", "dieser", "dieses", "wurde", "werden", "kann", "sind",
            "nicht", "mehr", "noch", "auch", "eine", "einen", "über", "unter", "durch", "from",
            "with", "that", "this", "have", "your", "about", "into", "their", "what"
        }
        result: List[str] = []
        seen = set()
        for word in words:
            if len(word) < 4 or word in stop_words:
                continue
            if word not in seen:
                seen.add(word)
                result.append(word)
        return result[:15]

    def _score_hook_candidate(self, hook_item: Dict[str, Any], anchor_terms: List[str]) -> float:
        """Score hooks for specificity and topical grounding."""
        hook = str(hook_item.get("hook", "") or "").strip()
        anchor = str(hook_item.get("anchor", "") or "").strip().lower()
        style = str(hook_item.get("style", "") or "").strip()
        hook_lower = hook.lower()

        if not hook:
            return -100.0

        score = 0.0

        generic_penalties = [
            "die meisten unterschätzen",
            "viele unterschätzen",
            "was wäre wenn",
            "verändert alles",
            "niemand spricht darüber",
            "unpopular opinion",
            "unpopuläre meinung",
            "ich muss ehrlich sein",
            "ehrlich gesagt",
            "lass uns",
            "stellen sie sich vor",
            "stell dir vor",
            "in der heutigen zeit",
            "es ist kein geheimnis",
            "gamechanger",
            "game changer",
            "revolutioniert",
            "die zukunft von",
            "wir müssen reden",
            "hier ist warum",
        ]
        for phrase in generic_penalties:
            if phrase in hook_lower:
                score -= 4.0

        overlap = 0
        for term in anchor_terms:
            if term in hook_lower or term in anchor:
                overlap += 1
        score += min(overlap, 3) * 2.5

        concrete_signals = [
            bool(re.search(r"\d", hook)),
            any(char in hook for char in [":", "–", "-"]),
            len(re.findall(r"\b[A-ZÄÖÜ][a-zäöüß]{3,}\b", hook)) >= 1,
        ]
        score += sum(concrete_signals) * 0.6

        if "?" in hook:
            score += 0.2
        if len(hook) < 18:
            score -= 2.0
        if len(hook) > 180:
            score -= 2.0
        if hook.count(".") > 2:
            score -= 1.5
        if hook_lower.count("ich") > 2:
            score -= 0.8

        if style in {
            "Provokant", "Storytelling", "Fakten-basiert", "Neugier-weckend",
            "Pointiert", "Reflektiert", "Datenanker", "Persönlich",
            "Konträr", "Problem", "Expertenbeobachtung"
        }:
            score += 0.5

        return score

    def _select_best_hooks(self, hooks: List[Dict[str, Any]], topic: Dict[str, Any], user_thoughts: str = "") -> List[Dict[str, str]]:
        """Filter and rank generated hooks so only grounded, non-generic hooks remain."""
        if not isinstance(hooks, list):
            return []

        anchor_terms = self._extract_hook_anchor_terms(topic, user_thoughts)
        scored: List[Dict[str, Any]] = []
        seen_hooks = set()

        for item in hooks:
            if not isinstance(item, dict):
                continue
            hook = str(item.get("hook", "") or "").strip()
            style = str(item.get("style", "") or "").strip() or "Hook"
            if not hook:
                continue

            dedupe_key = re.sub(r"\s+", " ", hook.lower())
            if dedupe_key in seen_hooks:
                continue
            seen_hooks.add(dedupe_key)

            score = self._score_hook_candidate(item, anchor_terms)
            scored.append({"hook": hook, "style": style, "score": score})

        scored.sort(key=lambda x: x["score"], reverse=True)

        selected: List[Dict[str, Any]] = []
        used_styles = set()
        for item in scored:
            if len(selected) >= 4:
                break
            if item["style"] in used_styles and len(scored) >= 6:
                continue
            used_styles.add(item["style"])
            selected.append(item)

        if len(selected) < 4:
            for item in scored:
                if item not in selected:
                    selected.append(item)
                if len(selected) >= 4:
                    break

        return [{"hook": item["hook"], "style": item["style"]} for item in selected[:4]]

    async def generate_improvement_suggestions(
        self,
        post_content: str,
        profile_analysis: Dict[str, Any],
        critic_feedback: Optional[Dict[str, Any]] = None
    ) -> List[Dict[str, str]]:
        """
        Generate improvement suggestions for an existing post based on critic feedback.

        Args:
            post_content: The current post content
            profile_analysis: Profile analysis for style matching
            critic_feedback: Optional feedback from the critic with improvements list

        Returns:
            List of {"label": "...", "action": "..."} dictionaries
        """
        logger.info("Generating improvement suggestions for post")

        # Extract style info from profile
        tone = profile_analysis.get('tone_analysis', {}).get('primary_tone', 'Professionell')
        energy = profile_analysis.get('linguistic_fingerprint', {}).get('energy_level', 7)
        address = profile_analysis.get('writing_style', {}).get('form_of_address', 'Du')

        # Build feedback context
        feedback_context = ""
        if critic_feedback:
            feedback_text = critic_feedback.get('feedback', '')
            improvements = critic_feedback.get('improvements', [])
            strengths = critic_feedback.get('strengths', [])
            score = critic_feedback.get('overall_score', 0)

            feedback_context = f"""
LETZTES KRITIKER-FEEDBACK (Score: {score}/100):
{feedback_text}

IDENTIFIZIERTE VERBESSERUNGSPUNKTE:
{chr(10).join(['- ' + imp for imp in improvements]) if improvements else '- Keine spezifischen Verbesserungen genannt'}

STÄRKEN (diese beibehalten!):
{chr(10).join(['- ' + s for s in strengths]) if strengths else '- Keine spezifischen Stärken genannt'}
"""

        system_prompt = f"""Du generierst kurze, klickbare Verbesserungsvorschläge für LinkedIn-Posts.

PROFIL DER PERSON:
- Tonalität: {tone}
- Energie: {energy}/10
- Ansprache: {address}
{feedback_context}

DEINE AUFGABE:
Generiere 4 KURZE Verbesserungsvorschläge (max 5-6 Worte pro Label).
Jeder Vorschlag muss:
1. Auf dem Kritiker-Feedback basieren (falls vorhanden)
2. Zum Stil der Person passen
3. Eine konkrete, umsetzbare Änderung beschreiben

FORMAT - Kurze Labels wie:
- "Hook emotionaler machen"
- "Persönliche Anekdote einbauen"
- "Absätze kürzen"
- "Call-to-Action verstärken"

Antworte im JSON-Format:
{{"suggestions": [
  {{"label": "Kurzes Label (max 6 Worte)", "action": "Detaillierte Anweisung für die KI, was genau geändert werden soll"}},
  ...
]}}"""

        user_prompt = f"""POST:
{post_content[:1500]}

Generiere 4 kurze, spezifische Verbesserungsvorschläge basierend auf dem Feedback und Profil."""

        response = await self.call_azure_claude(
            system_prompt=system_prompt,
            user_prompt=user_prompt,
            model=settings.azure_claude_model,
            temperature=0.7,
            response_format={"type": "json_object"}
        )

        try:
            result = json.loads(response)
            suggestions = result.get("suggestions", [])
            logger.info(f"Generated {len(suggestions)} improvement suggestions")
            return suggestions
        except (json.JSONDecodeError, KeyError) as e:
            logger.error(f"Failed to parse suggestions response: {e}")
            return [
                {"label": "Hook verstärken", "action": "Mache den ersten Satz emotionaler und aufmerksamkeitsstärker"},
                {"label": "Storytelling einbauen", "action": "Füge eine kurze persönliche Anekdote oder Erfahrung hinzu"},
                {"label": "Call-to-Action ergänzen", "action": "Füge am Ende eine Frage oder Handlungsaufforderung hinzu"},
                {"label": "Struktur verbessern", "action": "Kürze lange Absätze und verbessere die Lesbarkeit"}
            ]

    async def apply_suggestion(
        self,
        post_content: str,
        suggestion: str,
        profile_analysis: Dict[str, Any]
    ) -> str:
        """
        Apply a specific improvement suggestion to a post.

        Args:
            post_content: The current post content
            suggestion: The suggestion to apply
            profile_analysis: Profile analysis for style matching

        Returns:
            The improved post content
        """
        logger.info(f"Applying suggestion to post: {suggestion[:50]}...")

        # Extract style info from profile
        tone = profile_analysis.get('tone_analysis', {}).get('primary_tone', 'Professionell')
        energy = profile_analysis.get('linguistic_fingerprint', {}).get('energy_level', 7)
        address = profile_analysis.get('writing_style', {}).get('form_of_address', 'Du')

        system_prompt = f"""Du bist ein LinkedIn-Experte. Deine Aufgabe ist es, einen Post basierend auf einem konkreten Verbesserungsvorschlag zu überarbeiten.

STIL DER PERSON:
- Tonalität: {tone}
- Energie-Level: {energy}/10
- Ansprache: {address}

WICHTIG:
- Behalte den Kern und die Hauptaussage des Posts bei
- Wende NUR die angegebene Verbesserung an
- Behalte die Länge ungefähr bei
- Antworte NUR mit dem überarbeiteten Post, keine Erklärungen"""

        user_prompt = f"""ORIGINAL-POST:
{post_content}

ANZUWENDENDE VERBESSERUNG:
{suggestion}

Schreibe jetzt den überarbeiteten Post:"""

        response = await self.call_azure_claude(
            system_prompt=system_prompt,
            user_prompt=user_prompt,
            model=settings.azure_claude_model,
            temperature=0.5
        )

        logger.info("Successfully applied suggestion to post")
        return response.strip()
