"""
AI-powered analysis generator for SPKMC experiments.

This module provides the AIAnalyzer class that uses OpenAI's API to generate
academic-style analysis of epidemic simulation results. The feature is optional
and only activates if the OPENAI_API_KEY environment variable is set.
"""

import os
from pathlib import Path
from typing import Any, Dict, List, Optional

from spkmc.analysis.metrics import ExperimentMetrics, extract_experiment_metrics
from spkmc.analysis.prompts import SYSTEM_PROMPT, build_collection_prompt, build_experiment_prompt


class AIAnalyzer:
    """
    AI-powered analysis generator for SPKMC experiments.

    Uses OpenAI API to generate academic-style analysis of simulation results.
    Feature is optional and only activates if OPENAI_API_KEY is set.
    """

    DEFAULT_MODEL = "gpt-4o-mini"

    def __init__(self, model: Optional[str] = None):
        """
        Initialize the analyzer.

        Args:
            model: OpenAI model to use (default: gpt-4o-mini)
        """
        self.model = model or self.DEFAULT_MODEL
        self._client: Optional[Any] = None

    @staticmethod
    def is_available() -> bool:
        """
        Check if AI analysis is available (API key is set).

        Returns:
            True if OPENAI_API_KEY environment variable is set and non-empty
        """
        api_key = os.environ.get("OPENAI_API_KEY")
        return api_key is not None and len(api_key.strip()) > 0

    def _get_client(self) -> Any:
        """
        Lazily initialize OpenAI client.

        Returns:
            OpenAI client instance

        Raises:
            ImportError: If openai package not installed
            ValueError: If API key not set
        """
        if self._client is None:
            try:
                from openai import OpenAI
            except ImportError:
                raise ImportError(
                    "OpenAI package not installed. " "Install with: pip install openai"
                )

            api_key = os.environ.get("OPENAI_API_KEY")
            if not api_key:
                raise ValueError("OPENAI_API_KEY environment variable not set")

            self._client = OpenAI(api_key=api_key)

        return self._client

    def analyze_experiment(
        self,
        experiment_name: str,
        experiment_description: str,
        results: List[Dict[str, Any]],
        results_dir: Path,
    ) -> Optional[str]:
        """
        Generate AI analysis for a single experiment.

        Args:
            experiment_name: Name of the experiment
            experiment_description: The hypothesis being tested
            results: List of loaded result dictionaries
            results_dir: Path to experiment results directory

        Returns:
            Path to generated analysis.md file, or None if skipped/failed
        """
        analysis_path = results_dir / "analysis.md"

        # Skip if analysis already exists
        if analysis_path.exists():
            return None

        # Skip if no results
        if not results:
            return None

        # Extract metrics
        metrics = extract_experiment_metrics(experiment_name, experiment_description, results)

        # Skip if no valid scenarios
        if not metrics.scenarios:
            return None

        # Build prompt
        prompt = build_experiment_prompt(metrics)

        # Call OpenAI API
        client = self._get_client()
        response = client.chat.completions.create(
            model=self.model,
            messages=[
                {"role": "system", "content": SYSTEM_PROMPT},
                {"role": "user", "content": prompt},
            ],
            temperature=0.3,  # Lower for more consistent scientific writing
            max_tokens=2000,
        )

        analysis_text = response.choices[0].message.content

        # Write analysis file
        with open(analysis_path, "w", encoding="utf-8") as f:
            f.write(f"# Analysis: {experiment_name}\n\n")
            f.write(f"**Research Question:** {experiment_description}\n\n")
            f.write("---\n\n")
            f.write(analysis_text)
            f.write("\n\n---\n\n")
            f.write(f"*Generated by AI analysis (model: {self.model})*\n")

        return str(analysis_path)

    def generate_collection_summary(
        self, all_experiments_metrics: List[ExperimentMetrics]
    ) -> Optional[str]:
        """
        Generate a collection-level summary for --all mode.

        This summary is displayed to console only, not saved to file.

        Args:
            all_experiments_metrics: Metrics from all completed experiments

        Returns:
            Summary text for display, or None if failed
        """
        if not all_experiments_metrics:
            return None

        prompt = build_collection_prompt(all_experiments_metrics)

        client = self._get_client()
        response = client.chat.completions.create(
            model=self.model,
            messages=[
                {"role": "system", "content": SYSTEM_PROMPT},
                {"role": "user", "content": prompt},
            ],
            temperature=0.3,
            max_tokens=1500,
        )

        content = response.choices[0].message.content
        return str(content) if content is not None else None


def try_generate_analysis(
    experiment_name: str,
    experiment_description: Optional[str],
    results: List[Dict[str, Any]],
    results_dir: Path,
    verbose: bool = False,
) -> Optional[str]:
    """
    Convenience function to attempt AI analysis generation.

    Handles all checks and graceful degradation. This function never raises
    exceptions - it returns None on any failure.

    Args:
        experiment_name: Name of the experiment
        experiment_description: The hypothesis (may be None)
        results: List of result dictionaries
        results_dir: Path to results directory
        verbose: If True, print debug information

    Returns:
        Path to analysis file if generated, None otherwise
    """
    import sys

    def _debug(msg: str) -> None:
        if verbose or os.environ.get("SPKMC_DEBUG", "0") == "1":
            print(f"[AI DEBUG] {msg}", file=sys.stderr)

    # Skip if AI not available
    if not AIAnalyzer.is_available():
        _debug("Skipping: OPENAI_API_KEY not set")
        return None

    # Skip if no description (hypothesis)
    if not experiment_description:
        _debug("Skipping: No experiment description")
        return None

    # Skip if analysis.md already exists
    analysis_path = results_dir / "analysis.md"
    if analysis_path.exists():
        _debug(f"Skipping: analysis.md already exists at {analysis_path}")
        return None

    # Skip if no results
    if not results:
        _debug("Skipping: No results provided")
        return None

    _debug(f"Generating analysis for '{experiment_name}' with {len(results)} results")

    try:
        analyzer = AIAnalyzer()
        result = analyzer.analyze_experiment(
            experiment_name, experiment_description, results, results_dir
        )
        _debug(f"Analysis generated successfully: {result}")
        return result
    except ImportError as e:
        _debug(f"Import error: {e}")
        return None
    except Exception as e:
        _debug(f"Error generating analysis: {type(e).__name__}: {e}")
        return None
