"""Quality refiner agent for post-processing improvements."""
import re
from typing import Dict, Any, List, Optional
from loguru import logger

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


class QualityRefinerAgent(BaseAgent):
    """Agent for refining posts based on quality check results."""

    def __init__(self):
        """Initialize quality refiner agent."""
        super().__init__("QualityRefiner")

    async def process(
        self,
        post: str,
        quality_checks: Dict[str, Any],
        example_posts: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        Process method (required by BaseAgent).
        Alias for refine().
        """
        return await self.refine(post, quality_checks, example_posts)

    async def refine(
        self,
        post: str,
        quality_checks: Dict[str, Any],
        example_posts: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        Refine post based on quality check results.

        This is a deterministic, rule-based refiner that makes minimal
        changes to fix detected issues. No LLM calls = 0 API cost.

        Args:
            post: Original post text
            quality_checks: Results from quality checks
            example_posts: Optional reference posts for style

        Returns:
            Dictionary with refined post and improvement stats
        """
        logger.info("Starting quality refinement (deterministic, 0 API calls)")

        refined_post = post
        improvements = []

        # Stage 1: Grammar Auto-Fix (if errors detected)
        grammar_result = quality_checks.get('grammar_check', {})
        if grammar_result.get('has_errors') and grammar_result.get('available'):
            logger.info(f"Auto-fixing {grammar_result['error_count']} grammar errors")
            refined_post = grammar_result.get('corrected_text', refined_post)
            improvements.append(f"Fixed {grammar_result['error_count']} grammar errors")

        # Stage 2: Readability Improvements
        readability_result = quality_checks.get('readability_check', {})
        if not readability_result.get('passed') and readability_result.get('available'):
            logger.info("Improving readability")
            refined_post = self._improve_readability(refined_post, readability_result)
            improvements.append("Improved readability (split long sentences)")

        # Stage 3: Basic Style Adjustments (only if very poor < 60%)
        style_result = quality_checks.get('style_check', {})
        if style_result.get('available') and style_result.get('avg_similarity', 1.0) < 0.60:
            logger.info("Adjusting style (removing KI patterns)")
            refined_post = self._adjust_style(refined_post)
            improvements.append("Removed AI-typical patterns")

        # Calculate improvement
        original_length = len(post)
        refined_length = len(refined_post)
        change_percentage = abs(refined_length - original_length) / original_length * 100

        result = {
            "refined_post": refined_post,
            "original_post": post,
            "improvements": improvements,
            "change_percentage": change_percentage,
            "refined": len(improvements) > 0
        }

        if improvements:
            logger.info(f"Refinement complete: {len(improvements)} improvements made ({change_percentage:.1f}% change)")
        else:
            logger.info("No refinements needed")

        return result

    def _improve_readability(self, text: str, readability_result: Dict[str, Any]) -> str:
        """
        Improve readability by splitting long sentences and simplifying.

        Rule-based, deterministic approach.
        """
        metrics = readability_result.get('metrics', {})
        avg_sentence_length = metrics.get('avg_sentence_length', 0)

        # If sentences are too long (> 25 words), try to split
        if avg_sentence_length > 25:
            text = self._split_long_sentences(text)

        return text

    def _split_long_sentences(self, text: str) -> str:
        """
        Split long sentences at natural breakpoints.

        Looks for:
        - ", und " → ". "
        - ", aber " → ". Aber "
        - ", denn " → ". Denn "
        - " und " (mid-sentence) → ". "
        """
        # Split sentences
        sentences = re.split(r'([.!?]\s+)', text)
        refined_sentences = []

        for i, sentence in enumerate(sentences):
            # Skip punctuation separators
            if re.match(r'[.!?]\s+', sentence):
                refined_sentences.append(sentence)
                continue

            # Count words in sentence
            words = sentence.split()
            if len(words) > 25:
                # Try to split at natural conjunction
                # ", und " → ". "
                sentence = re.sub(r',\s+und\s+', '. ', sentence, count=1)
                # ", aber " → ". Aber "
                sentence = re.sub(r',\s+aber\s+', '. Aber ', sentence, count=1)
                # ", denn " → ". Denn "
                sentence = re.sub(r',\s+denn\s+', '. Denn ', sentence, count=1)

                # Capitalize after new periods
                sentence = re.sub(r'\.\s+([a-z])', lambda m: '. ' + m.group(1).upper(), sentence)

            refined_sentences.append(sentence)

        return ''.join(refined_sentences)

    def _adjust_style(self, text: str) -> str:
        """
        Remove common AI-typical patterns and phrases.

        Rule-based replacements to make text more authentic.
        """
        # Common AI patterns to remove/replace
        replacements = [
            # Remove overly formal phrases
            (r'\bIn der heutigen Zeit\b', 'Heute'),
            (r'\bEs ist kein Geheimnis,? dass\b', ''),
            (r'\bTauchen Sie ein in\b', 'Entdecken Sie'),
            (r'\bStellen Sie sich vor,?\b', ''),
            (r'\bLassen Sie uns\b', 'Lass uns'),

            # Remove redundant phrases
            (r'\bes ist wichtig zu verstehen,? dass\b', ''),
            (r'\bIch möchte betonen,? dass\b', ''),

            # Simplify overly complex phrases
            (r'\bdarüber hinaus\b', 'außerdem'),
            (r'\bdeshalb ist es wichtig\b', 'deshalb'),
            (r'\bin diesem Zusammenhang\b', 'dabei'),

            # Remove double spaces
            (r'\s+', ' '),
        ]

        for pattern, replacement in replacements:
            text = re.sub(pattern, replacement, text, flags=re.IGNORECASE)

        # Clean up spacing
        text = re.sub(r'\s+([.,!?])', r'\1', text)  # Remove space before punctuation
        text = re.sub(r'\s+', ' ', text)  # Normalize spaces
        text = text.strip()

        return text

    async def final_polish(
        self,
        post: str,
        quality_checks: Dict[str, Any],
        profile_analysis: Dict[str, Any],
        example_posts: List[str]
    ) -> str:
        """
        Final polish using ONE LLM call to address quality issues.

        This is the simplified approach per user feedback:
        - Analyze quality issues
        - One LLM call to fix them
        - Preserve ALL formatting (line breaks, spaces, structure)
        - NO score changes

        Args:
            post: Current post text (after Critic approval)
            quality_checks: Quality check results
            profile_analysis: Profile analysis for style
            example_posts: Reference posts

        Returns:
            Polished post
        """
        logger.info("Running final polish (1 API call)")

        # Build specific feedback from quality checks
        feedback_points = []

        grammar_result = quality_checks.get('grammar_check', {})
        if grammar_result.get('has_errors'):
            feedback_points.append(f"⚠️ {grammar_result['error_count']} Grammatikfehler gefunden")

        style_result = quality_checks.get('style_check', {})
        if not style_result.get('passed'):
            similarity = style_result.get('avg_similarity', 0) * 100
            feedback_points.append(f"⚠️ Stil-Ähnlichkeit nur {similarity:.0f}% (Ziel: 75%+)")

        readability_result = quality_checks.get('readability_check', {})
        if not readability_result.get('passed'):
            issues = readability_result.get('issues', [])
            feedback_points.append(f"⚠️ Lesbarkeit: {', '.join(issues)}")

        # If no issues, return unchanged
        if not feedback_points:
            logger.info("No quality issues - returning unchanged post")
            return post

        feedback = "\n".join(feedback_points)

        # Create simple polish prompt
        system_prompt = self._get_final_polish_system_prompt(profile_analysis, example_posts)
        user_prompt = self._get_final_polish_user_prompt(post, feedback)

        polished_post = await self.call_azure_claude(
            system_prompt=system_prompt,
            user_prompt=user_prompt,
            model=settings.azure_claude_model,
            temperature=0.3  # Low temp for precise, minimal changes
        )

        logger.info("Final polish complete")
        return polished_post.strip()

    async def smart_revision(
        self,
        post: str,
        quality_checks: Dict[str, Any],
        profile_analysis: Dict[str, Any],
        example_posts: List[str]
    ) -> str:
        """
        Intelligent revision using LLM to fix remaining quality issues.

        Only called if auto-refiner wasn't enough (score < 85).
        MAX 1 call per post!

        Args:
            post: Current post text
            quality_checks: Quality check results
            profile_analysis: Profile analysis for style
            example_posts: Reference posts

        Returns:
            Revised post
        """
        logger.info("Running smart revision (1 API call)")

        # Build specific feedback from quality checks
        feedback_points = []

        grammar_result = quality_checks.get('grammar_check', {})
        if grammar_result.get('has_errors'):
            feedback_points.append(f"⚠️ Noch {grammar_result['error_count']} Grammatikfehler")

        style_result = quality_checks.get('style_check', {})
        if not style_result.get('passed'):
            similarity = style_result.get('avg_similarity', 0) * 100
            feedback_points.append(f"⚠️ Stil-Ähnlichkeit nur {similarity:.0f}% (Ziel: 75%+)")

        readability_result = quality_checks.get('readability_check', {})
        if not readability_result.get('passed'):
            issues = readability_result.get('issues', [])
            feedback_points.append(f"⚠️ Lesbarkeit: {', '.join(issues)}")

        feedback = "\n".join(feedback_points)

        # Use Writer's revision capability with quality feedback
        system_prompt = self._get_smart_revision_system_prompt(profile_analysis, example_posts)
        user_prompt = self._get_smart_revision_user_prompt(post, feedback, quality_checks)

        revised_post = await self.call_azure_claude(
            system_prompt=system_prompt,
            user_prompt=user_prompt,
            model=settings.azure_claude_model,
            temperature=0.4  # Lower temp for more controlled revision
        )

        logger.info("Smart revision complete")
        return revised_post.strip()

    def _get_smart_revision_system_prompt(
        self,
        profile_analysis: Dict[str, Any],
        example_posts: List[str]
    ) -> str:
        """Get system prompt for smart revision."""
        # Extract key style info
        writing_style = profile_analysis.get("writing_style", {})
        linguistic = profile_analysis.get("linguistic_fingerprint", {})
        phrase_library = profile_analysis.get("phrase_library", {})

        # Build short example section
        examples_text = ""
        if example_posts:
            examples_text = "\n\nSTIL-REFERENZEN (nutze ähnliche Formulierungen):\n"
            for i, post in enumerate(example_posts[:2], 1):  # Only 2 examples
                examples_text += f"\n--- Beispiel {i} ---\n{post[:800]}\n"

        return f"""Du bist ein LinkedIn-Post-Optimierer. Deine Aufgabe ist es, einen Post MINIMAL zu überarbeiten um Quality-Probleme zu beheben.

WICHTIG: Behalte den Kern, die Story und die Hauptaussagen bei! Ändere NUR was nötig ist!

STIL DER PERSON:
- Ansprache: {writing_style.get('form_of_address', 'Du')}
- Perspektive: {writing_style.get('perspective', 'Ich')}
- Energie: {linguistic.get('energy_level', 7)}/10
- Typische Phrasen: {', '.join(phrase_library.get('signature_phrases', [])[:3])}
{examples_text}

AUFGABE:
- Fixe NUR die genannten Quality-Probleme
- Behalte die Story und den Inhalt bei
- Ändere maximal 10-15% des Textes
- Kein komplettes Rewrite!

Antworte NUR mit dem überarbeiteten Post."""

    def _get_smart_revision_user_prompt(
        self,
        post: str,
        feedback: str,
        quality_checks: Dict[str, Any]
    ) -> str:
        """Get user prompt for smart revision."""
        # Get specific improvement suggestions (if available)
        readability_result = quality_checks.get('readability_check', {})
        suggestions = []
        if readability_result and not readability_result.get('passed'):
            # Suggestions are not in the result, we'll generate them from issues
            issues = readability_result.get('issues', [])
            if issues:
                suggestions = [f"Verbesserung nötig: {issue}" for issue in issues]

        suggestions_text = ""
        if suggestions:
            suggestions_text = "\n\nKONKRETE VERBESSERUNGEN:\n" + "\n".join([f"- {s}" for s in suggestions])

        return f"""Überarbeite diesen Post um die Quality-Probleme zu beheben:

**ORIGINAL POST:**
{post}

**QUALITY-PROBLEME:**
{feedback}
{suggestions_text}

**DEINE AUFGABE:**
Fixe die genannten Probleme mit MINIMALEN Änderungen.
Behalte die Story, den Kern und die Hauptaussagen bei!

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

    def _get_final_polish_system_prompt(
        self,
        profile_analysis: Dict[str, Any],
        example_posts: List[str]
    ) -> str:
        """Get system prompt for final polish."""
        # Extract key style info
        writing_style = profile_analysis.get("writing_style", {})
        linguistic = profile_analysis.get("linguistic_fingerprint", {})

        # Build short example section (max 2 examples)
        examples_text = ""
        if example_posts:
            examples_text = "\n\nSTIL-REFERENZEN:\n"
            for i, post in enumerate(example_posts[:2], 1):
                examples_text += f"\n--- Beispiel {i} ---\n{post[:800]}\n"

        return f"""Du bist ein LinkedIn-Post-Polierer. Deine Aufgabe ist es, einen bereits guten Post MINIMAL zu verbessern.

WICHTIG:
- Behalte die EXAKTE Formatierung bei (Zeilenumbrüche, Absätze, Leerzeichen)!
- Behalte die Story, den Inhalt und die Struktur bei!
- Ändere NUR was für Quality-Verbesserungen nötig ist!
- Kein Rewrite - nur Politur!

STIL DER PERSON:
- Ansprache: {writing_style.get('form_of_address', 'Du')}
- Perspektive: {writing_style.get('perspective', 'Ich')}
- Energie: {linguistic.get('energy_level', 7)}/10
{examples_text}

AUFGABE:
Fixe NUR die genannten Quality-Probleme (Grammatik, Stil, Lesbarkeit).
Behalte ALLES andere exakt gleich - vor allem die Formatierung!

Antworte NUR mit dem polierten Post."""

    def _get_final_polish_user_prompt(
        self,
        post: str,
        feedback: str
    ) -> str:
        """Get user prompt for final polish."""
        return f"""Poliere diesen Post um die Quality-Probleme zu beheben:

**POST:**
{post}

**QUALITY-FEEDBACK:**
{feedback}

**WICHTIG:**
- Behalte die EXAKTE Formatierung (Zeilenumbrüche, Absätze, Leerzeichen)!
- Fixe NUR die genannten Quality-Probleme
- Ändere NICHT den Inhalt, die Story oder die Struktur
- Minimale Änderungen!

Gib NUR den polierten Post zurück (ohne Erklärungen)."""

    def get_refinement_summary(self, refinement_result: Dict[str, Any]) -> str:
        """
        Get human-readable summary of refinement.

        Args:
            refinement_result: Result from refine()

        Returns:
            Summary string
        """
        if not refinement_result.get("refined"):
            return "✅ Keine Verbesserungen nötig"

        improvements = refinement_result.get("improvements", [])
        change = refinement_result.get("change_percentage", 0)

        summary = f"🔧 {len(improvements)} Verbesserungen ({change:.1f}% Änderung):\n"
        summary += "\n".join([f"  - {imp}" for imp in improvements])

        return summary
