# example_quick_optimization.py - Simplified Demo
"""
Simplified parameter optimization demo for Local Deep Research.

This script demonstrates basic parameter optimization with simulated results.

Usage:
    # Install dependencies with PDM
    cd /path/to/local-deep-research
    pdm install

    # Run the script with PDM
    pdm run python examples/optimization/example_quick_optimization.py
"""

import json
import random
import time
from datetime import datetime, UTC
from pathlib import Path
from typing import Any, Dict, Tuple

from loguru import logger

# Loguru automatically handles logging configuration


def simulate_optimization(
    param_space: Dict[str, Any],
    n_trials: int = 5,
    metric_weights: Dict[str, float] = None,
) -> Tuple[Dict[str, Any], float]:
    """
    Simulate an optimization process without actually running benchmarks.
    This is just for demonstration purposes.

    Args:
        param_space: Dictionary defining parameter search spaces
        n_trials: Number of simulated trials
        metric_weights: Weights for quality vs speed metrics

    Returns:
        Tuple of (best_parameters, best_score)
    """
    if metric_weights is None:
        metric_weights = {"quality": 0.5, "speed": 0.5}

    logger.info(f"Starting simulated optimization with {n_trials} trials")
    logger.info(f"Parameter space: {param_space}")
    logger.info(f"Metric weights: {metric_weights}")

    # Generate random trials
    best_score = 0.0
    best_params = {}

    for i in range(n_trials):
        # Generate random parameters
        params = {}
        for param_name, param_config in param_space.items():
            if param_config.get("type") == "int":
                params[param_name] = random.randint(
                    param_config.get("low", 1), param_config.get("high", 5)
                )
            elif param_config.get("type") == "categorical":
                params[param_name] = random.choice(
                    param_config.get("choices", ["standard"])
                )

        logger.info(f"Trial {i}: Testing parameters: {params}")

        # Simulate execution delay
        time.sleep(1)

        # Simulate metrics calculation
        quality_score = random.uniform(0.5, 0.9)  # Random quality score
        speed_score = 1.0 - (
            params.get("iterations", 1) * 0.1
        )  # More iterations = slower

        # Calculate weighted score
        combined_score = quality_score * metric_weights.get(
            "quality", 0.5
        ) + speed_score * metric_weights.get("speed", 0.5)

        logger.info(
            f"Trial {i}: Quality: {quality_score:.2f}, Speed: {speed_score:.2f}, Score: {combined_score:.2f}"
        )

        # Update best parameters if this trial is better
        if combined_score > best_score:
            best_score = combined_score
            best_params = params.copy()
            logger.info(
                f"New best parameters found: {best_params} with score: {best_score:.2f}"
            )

    return best_params, best_score


def optimize_for_speed(
    param_space: Dict[str, Any] = None, n_trials: int = 3
) -> Tuple[Dict[str, Any], float]:
    """
    Simulate speed-focused optimization.

    Args:
        param_space: Parameter space definition (optional)
        n_trials: Number of trials

    Returns:
        Tuple of (best_parameters, best_score)
    """
    if param_space is None:
        param_space = {
            "iterations": {
                "type": "int",
                "low": 1,
                "high": 3,
            },
            "questions_per_iteration": {
                "type": "int",
                "low": 1,
                "high": 3,
            },
            "search_strategy": {
                "type": "categorical",
                "choices": ["rapid", "parallel"],
            },
        }

    # Speed-focused weights
    metric_weights = {
        "speed": 0.8,
        "quality": 0.2,
    }

    return simulate_optimization(
        param_space=param_space,
        n_trials=n_trials,
        metric_weights=metric_weights,
    )


def optimize_for_quality(
    param_space: Dict[str, Any] = None, n_trials: int = 3
) -> Tuple[Dict[str, Any], float]:
    """
    Simulate quality-focused optimization.

    Args:
        param_space: Parameter space definition (optional)
        n_trials: Number of trials

    Returns:
        Tuple of (best_parameters, best_score)
    """
    if param_space is None:
        param_space = {
            "iterations": {
                "type": "int",
                "low": 1,
                "high": 5,
            },
            "questions_per_iteration": {
                "type": "int",
                "low": 1,
                "high": 5,
            },
            "search_strategy": {
                "type": "categorical",
                "choices": ["standard", "iterdrag", "source_based"],
            },
        }

    # Quality-focused weights
    metric_weights = {
        "quality": 0.9,
        "speed": 0.1,
    }

    return simulate_optimization(
        param_space=param_space,
        n_trials=n_trials,
        metric_weights=metric_weights,
    )


def main():
    # Create timestamp for unique output directory
    timestamp = datetime.now(UTC).strftime("%Y%m%d_%H%M%S")
    output_dir = str(
        Path("examples")
        / "optimization"
        / "results"
        / f"optimization_demo_{timestamp}"
    )
    Path(output_dir).mkdir(parents=True, exist_ok=True)

    print(
        f"Starting quick optimization demo - results will be saved to {output_dir}"
    )

    # Create a simple parameter space for demonstration
    param_space = {
        "iterations": {
            "type": "int",
            "low": 1,
            "high": 3,
        },
        "questions_per_iteration": {
            "type": "int",
            "low": 1,
            "high": 3,
        },
        "search_strategy": {
            "type": "categorical",
            "choices": ["rapid", "standard", "iterdrag"],
        },
    }

    # Run a balanced optimization
    print("\n=== Running balanced optimization simulation ===")
    balanced_params, balanced_score = simulate_optimization(
        param_space=param_space,
        n_trials=4,
        metric_weights={"quality": 0.6, "speed": 0.4},
    )

    print(f"Best balanced parameters: {balanced_params}")
    print(f"Best balanced score: {balanced_score:.4f}")

    # Run a speed optimization
    print("\n=== Running speed-focused optimization simulation ===")
    speed_params, speed_score = optimize_for_speed(n_trials=3)

    print(f"Best speed parameters: {speed_params}")
    print(f"Best speed score: {speed_score:.4f}")

    # Run a quality optimization
    print("\n=== Running quality-focused optimization simulation ===")
    quality_params, quality_score = optimize_for_quality(n_trials=3)

    print(f"Best quality parameters: {quality_params}")
    print(f"Best quality score: {quality_score:.4f}")

    # Save results
    summary = {
        "timestamp": timestamp,
        "balanced": {
            "parameters": balanced_params,
            "score": float(balanced_score),
        },
        "speed": {"parameters": speed_params, "score": float(speed_score)},
        "quality": {
            "parameters": quality_params,
            "score": float(quality_score),
        },
    }

    with open(Path(output_dir) / "optimization_summary.json", "w") as f:
        json.dump(summary, f, indent=2)

    print(
        f"\nDemo complete! Results saved to {output_dir}/optimization_summary.json"
    )
    print("\nRecommended parameters:")
    print(f"- For balanced performance: {balanced_params}")
    print(f"- For speed: {speed_params}")
    print(f"- For quality: {quality_params}")

    print(
        "\nNote: This is a simulation for demonstration purposes only. Real optimization"
    )
    print(
        "would run actual benchmarks with these parameters to evaluate performance."
    )


if __name__ == "__main__":
    main()
