"""
Configuration loader – reads .env and builds PipelineConfig.
"""

from __future__ import annotations

import json
import os
from pathlib import Path

from dotenv import load_dotenv

from models import (
    CharacterTemplate,
    ClothingStyle,
    ExportSettings,
    PipelineConfig,
    PipelineMode,
    ProductPlacement,
    ProductionRules,
    TargetPlatform,
    VoiceSettings,
    WorldStyle,
)

load_dotenv()

# ---------------------------------------------------------------------------
# Paths
# ---------------------------------------------------------------------------

PROJECT_ROOT = Path(__file__).resolve().parent
TEMPLATES_DIR = PROJECT_ROOT / "character_templates"
DEFAULT_OUTPUT_DIR = PROJECT_ROOT / "output"


# ---------------------------------------------------------------------------
# Character template helpers
# ---------------------------------------------------------------------------

def load_character_template(name_or_path: str) -> CharacterTemplate:
    """Load a character template by name (from templates dir) or file path."""
    path = Path(name_or_path)
    if not path.exists():
        path = TEMPLATES_DIR / f"{name_or_path}.json"
    if not path.exists():
        raise FileNotFoundError(
            f"Character template not found: {name_or_path}. "
            f"Available templates: {list_available_templates()}"
        )
    with open(path, "r", encoding="utf-8") as f:
        data = json.load(f)
    return CharacterTemplate(**data)


def list_available_templates() -> list[str]:
    """List available character template names."""
    if not TEMPLATES_DIR.exists():
        return []
    return [p.stem for p in TEMPLATES_DIR.glob("*.json")]


# ---------------------------------------------------------------------------
# Platform presets
# ---------------------------------------------------------------------------

PLATFORM_PRESETS: dict[str, ExportSettings] = {
    "tiktok": ExportSettings(
        resolution="1080x1920", fps=30, video_format="mp4", aspect_ratio="9:16"
    ),
    "instagram_reels": ExportSettings(
        resolution="1080x1920", fps=30, video_format="mp4", aspect_ratio="9:16"
    ),
    "youtube_shorts": ExportSettings(
        resolution="1080x1920", fps=30, video_format="mp4", aspect_ratio="9:16"
    ),
    "youtube": ExportSettings(
        resolution="1920x1080", fps=30, video_format="mp4", aspect_ratio="16:9"
    ),
}


# ---------------------------------------------------------------------------
# Build config from environment
# ---------------------------------------------------------------------------

def build_config(
    *,
    mode: str = "plan",
    character: str | None = "skeleton",
    character_template: CharacterTemplate | None = None,
    # Decoupled style presets
    world_style: WorldStyle | None = None,
    clothing_style: ClothingStyle | None = None,
    production_rules: ProductionRules | None = None,
    # Product placement
    product_placement: ProductPlacement | None = None,
    platform: str | None = None,
    output_dir: str | None = None,
    frames_per_minute: int | None = None,
    enable_coverage_shots: bool = False,
    coverage_angles_per_scene: int = 3,
    coverage_mode: str = "all",
    # TTS settings
    tts_provider: str | None = None,
) -> PipelineConfig:
    """Build a PipelineConfig from env vars + overrides."""

    target_platform = TargetPlatform(
        platform or os.getenv("TARGET_PLATFORM", "tiktok")
    )
    export_settings = PLATFORM_PRESETS.get(
        target_platform.value, PLATFORM_PRESETS["tiktok"]
    )

    voice_settings = VoiceSettings(
        # TTS provider: "elevenlabs" (default) or "pollinations"
        tts_provider=tts_provider or os.getenv("TTS_PROVIDER", "elevenlabs"),
        # ElevenLabs settings
        voice_id=os.getenv("ELEVENLABS_VOICE_ID", "JBFqnCBsd6RMkjVDRZzb"),
        model_id=os.getenv("ELEVENLABS_MODEL_ID", "eleven_multilingual_v2"),
    )

    if character_template is None and character:
        character_template = load_character_template(character)

    fpm = frames_per_minute or int(os.getenv("FRAMES_PER_MINUTE", "25"))

    return PipelineConfig(
        mode=PipelineMode(mode),
        llm_model=os.getenv("LLM_MODEL", "openai/gpt-4o"),
        target_platform=target_platform,
        character_template=character_template,
        world_style=world_style,
        clothing_style=clothing_style,
        production_rules=production_rules,
        product_placement=product_placement,
        voice_settings=voice_settings,
        export_settings=export_settings,
        output_dir=output_dir or os.getenv("OUTPUT_DIR", str(DEFAULT_OUTPUT_DIR)),
        frames_per_minute=fpm,
        enable_coverage_shots=enable_coverage_shots,
        coverage_angles_per_scene=coverage_angles_per_scene,
        coverage_mode=coverage_mode,
    )
