"""Configuration management for Whisper Scribe."""

import os
import json
from pathlib import Path
from typing import Optional, List, Dict
from pydantic import BaseModel


def get_config_dir() -> Path:
    """Get the configuration directory."""
    config_dir = Path.home() / ".whisper-scribe"
    config_dir.mkdir(parents=True, exist_ok=True)
    return config_dir


def get_config_file() -> Path:
    """Get the configuration file path."""
    return get_config_dir() / "config.json"


def get_default_output_dir() -> Path:
    """Get the default output directory."""
    output_dir = get_config_dir() / "transcriptions"
    output_dir.mkdir(parents=True, exist_ok=True)
    return output_dir


def get_temp_dir() -> Path:
    """Get the temporary directory for downloads."""
    temp_dir = get_config_dir() / "temp"
    temp_dir.mkdir(parents=True, exist_ok=True)
    return temp_dir


class CustomPrompt(BaseModel):
    """A custom analysis prompt."""
    id: str
    name: str
    prompt: str


class AppConfig(BaseModel):
    """Application configuration."""
    # API Keys
    openai_api_key: str = ""
    perplexity_api_key: str = ""
    anthropic_api_key: str = ""
    eden_api_key: str = ""

    # Provider selection
    transcription_provider: str = "openai"  # openai, eden
    analysis_provider: str = "openai"  # openai, anthropic, eden
    critique_provider: str = "anthropic"  # anthropic, openai, eden
    resources_provider: str = "perplexity"  # perplexity, eden

    # Output settings
    output_directory: str = ""
    custom_prompts: List[Dict] = []

    # Webhooks
    webhook_url: str = ""
    webhook_enabled: bool = False

    def __init__(self, **data):
        super().__init__(**data)
        if not self.output_directory:
            self.output_directory = str(get_default_output_dir())


def load_config() -> AppConfig:
    """Load configuration from file or environment."""
    config = AppConfig()
    config_file = get_config_file()

    # Try to load from config file
    if config_file.exists():
        try:
            with open(config_file, 'r') as f:
                data = json.load(f)
                config = AppConfig(**data)
        except (json.JSONDecodeError, Exception):
            pass

    # Environment variables override file config
    if os.environ.get("OPENAI_API_KEY"):
        config.openai_api_key = os.environ["OPENAI_API_KEY"]

    if os.environ.get("PERPLEXITY_API_KEY"):
        config.perplexity_api_key = os.environ["PERPLEXITY_API_KEY"]

    if os.environ.get("ANTHROPIC_API_KEY"):
        config.anthropic_api_key = os.environ["ANTHROPIC_API_KEY"]

    if os.environ.get("EDEN_API_KEY"):
        config.eden_api_key = os.environ["EDEN_API_KEY"]

    if os.environ.get("WHISPER_SCRIBE_OUTPUT_DIR"):
        config.output_directory = os.environ["WHISPER_SCRIBE_OUTPUT_DIR"]

    return config


def save_config(config: AppConfig) -> None:
    """Save configuration to file."""
    config_file = get_config_file()
    with open(config_file, 'w') as f:
        json.dump(config.model_dump(), f, indent=2)


def get_output_directory() -> Path:
    """Get the output directory, creating it if needed."""
    config = load_config()
    output_dir = Path(config.output_directory)
    output_dir.mkdir(parents=True, exist_ok=True)
    return output_dir


def get_api_key() -> str:
    """Get the OpenAI API key."""
    return load_config().openai_api_key


def get_custom_prompts() -> List[Dict]:
    """Get all custom prompts."""
    return load_config().custom_prompts


def add_custom_prompt(prompt_id: str, name: str, prompt: str) -> Dict:
    """Add a new custom prompt."""
    config = load_config()
    new_prompt = {"id": prompt_id, "name": name, "prompt": prompt}
    config.custom_prompts.append(new_prompt)
    save_config(config)
    return new_prompt


def update_custom_prompt(prompt_id: str, name: str = None, prompt: str = None) -> Optional[Dict]:
    """Update an existing custom prompt."""
    config = load_config()
    for p in config.custom_prompts:
        if p["id"] == prompt_id:
            if name is not None:
                p["name"] = name
            if prompt is not None:
                p["prompt"] = prompt
            save_config(config)
            return p
    return None


def delete_custom_prompt(prompt_id: str) -> bool:
    """Delete a custom prompt."""
    config = load_config()
    original_len = len(config.custom_prompts)
    config.custom_prompts = [p for p in config.custom_prompts if p["id"] != prompt_id]
    if len(config.custom_prompts) < original_len:
        save_config(config)
        return True
    return False


def get_webhook_config() -> tuple:
    """Get webhook configuration."""
    config = load_config()
    return config.webhook_url, config.webhook_enabled


def set_webhook_config(url: str = None, enabled: bool = None) -> None:
    """Set webhook configuration."""
    config = load_config()
    if url is not None:
        config.webhook_url = url
    if enabled is not None:
        config.webhook_enabled = enabled
    save_config(config)


def get_anthropic_api_key() -> str:
    """Get the Anthropic API key."""
    return load_config().anthropic_api_key


def get_eden_api_key() -> str:
    """Get the Eden.ai API key."""
    return load_config().eden_api_key


def get_perplexity_api_key() -> str:
    """Get the Perplexity API key."""
    return load_config().perplexity_api_key


def get_provider_settings() -> Dict:
    """Get provider selection settings."""
    config = load_config()
    return {
        "transcription_provider": config.transcription_provider,
        "analysis_provider": config.analysis_provider,
        "critique_provider": config.critique_provider,
        "resources_provider": config.resources_provider
    }


def set_provider_settings(
    transcription_provider: str = None,
    analysis_provider: str = None,
    critique_provider: str = None,
    resources_provider: str = None
) -> None:
    """Set provider selection settings."""
    config = load_config()
    if transcription_provider is not None:
        config.transcription_provider = transcription_provider
    if analysis_provider is not None:
        config.analysis_provider = analysis_provider
    if critique_provider is not None:
        config.critique_provider = critique_provider
    if resources_provider is not None:
        config.resources_provider = resources_provider
    save_config(config)
