"""
Claude AI Provider implementation
"""

import logging
import subprocess
import shutil
from typing import Dict, Any, Optional

from config import settings
from core import AIProcessingError
from .base_provider import AIProvider


class ClaudeProvider(AIProvider):
    """Claude AI provider using CLI"""

    def __init__(self):
        self.logger = logging.getLogger(__name__)
        self._cli_path = settings.CLAUDE_CLI_PATH or shutil.which("claude")
        self._token = settings.ZAI_AUTH_TOKEN
        self._base_url = settings.ZAI_BASE_URL

    @property
    def name(self) -> str:
        return "Claude"

    def is_available(self) -> bool:
        """Check if Claude CLI is available"""
        return bool(self._cli_path and self._token)

    def _get_env(self) -> Dict[str, str]:
        """Get environment variables for Claude"""
        # Load all user environment variables first
        import os

        env = os.environ.copy()

        # Override with our specific settings if available
        if self._token:
            env["ANTHROPIC_AUTH_TOKEN"] = self._token
        if self._base_url:
            env["ANTHROPIC_BASE_URL"] = self._base_url

        # Add critical flags
        env["PYTHONUNBUFFERED"] = "1"

        # Ensure model variables are picked up from env (already in os.environ)
        # but if we had explicit settings for them, we'd set them here.
        # Since we put them in .env and loaded via load_dotenv -> os.environ,
        # simply copying os.environ is sufficient.

        return env

    def _run_cli(self, prompt: str, timeout: int = 600) -> str:
        """Run Claude CLI with prompt using -p flag for stdin input"""
        if not self.is_available():
            raise AIProcessingError("Claude CLI not available or not configured")

        try:
            # Use -p flag to read prompt from stdin, --dangerously-skip-permissions for automation
            cmd = [self._cli_path, "--dangerously-skip-permissions", "-p", "-"]
            process = subprocess.run(
                cmd,
                input=prompt,
                env=self._get_env(),
                text=True,
                capture_output=True,
                timeout=timeout,
                shell=False,
            )

            if process.returncode != 0:
                error_msg = process.stderr or "Unknown error"
                raise AIProcessingError(f"Claude CLI failed: {error_msg}")

            return process.stdout.strip()
        except subprocess.TimeoutExpired:
            raise AIProcessingError(f"Claude CLI timed out after {timeout}s")
        except Exception as e:
            raise AIProcessingError(f"Claude CLI error: {e}")

    def summarize(self, text: str, **kwargs) -> str:
        """Generate summary using Claude"""
        prompt = f"""Summarize the following text:

{text}

Provide a clear, concise summary in Spanish."""
        return self._run_cli(prompt)

    def correct_text(self, text: str, **kwargs) -> str:
        """Correct text using Claude"""
        prompt = f"""Correct the following text for grammar, spelling, and clarity:

{text}

Return only the corrected text, nothing else."""
        return self._run_cli(prompt)

    def classify_content(self, text: str, **kwargs) -> Dict[str, Any]:
        """Classify content using Claude"""
        categories = [
            "historia",
            "analisis_contable",
            "instituciones_gobierno",
            "otras_clases",
        ]

        prompt = f"""Classify the following text into one of these categories:
- historia
- analisis_contable
- instituciones_gobierno
- otras_clases

Text: {text}

Return only the category name, nothing else."""
        result = self._run_cli(prompt).lower()

        # Validate result
        if result not in categories:
            result = "otras_clases"

        return {"category": result, "confidence": 0.9, "provider": self.name}

    def generate_text(self, prompt: str, **kwargs) -> str:
        """Generate text using Claude"""
        return self._run_cli(prompt)

    def fix_latex(self, latex_code: str, error_log: str, **kwargs) -> str:
        """Fix broken LaTeX code using Claude"""
        prompt = f"""I have a LaTeX file that failed to compile. Please fix the code.

COMPILER ERROR LOG:
{error_log[-3000:]}

BROKEN LATEX CODE:
{latex_code}

INSTRUCTIONS:
1. Analyze the error log to find the specific syntax error.
2. Fix the LaTeX code.
3. Return ONLY the full corrected LaTeX code.
4. Do not include markdown blocks or explanations.
5. Start immediately with \\documentclass.

COMMON LATEX ERRORS TO CHECK:
- TikZ nodes with line breaks (\\\\) MUST have "align=center" in their style. 
  WRONG: \\node[box] (n) {{Text\\\\More}};
  CORRECT: \\node[box, align=center] (n) {{Text\\\\More}};
- All \\begin{{env}} must have matching \\end{{env}}
- All braces {{ }} must be balanced
- Math mode $ must be paired
- Special characters need escaping: % & # _ 
- tcolorbox environments need proper titles: [Title] not {{Title}}
"""
        return self._run_cli(prompt, timeout=180)
