from __future__ import annotations

import os
from dataclasses import dataclass
from pathlib import Path


@dataclass(frozen=True)
class KlingConfig:
    api_base_url: str = os.getenv('KLING_API_BASE_URL', 'https://api-singapore.klingai.com')
    api_token: str | None = os.getenv('KLING_API_TOKEN')  # optional manual override; preferred auth is AK/SK -> JWT
    callback_base_url: str | None = os.getenv('KLING_CALLBACK_BASE_URL')
    request_timeout_sec: int = int(os.getenv('KLING_REQUEST_TIMEOUT_SEC', '60'))
    concurrency_limit: int = int(os.getenv('KLING_CONCURRENCY_LIMIT', '1'))
    callback_shared_secret: str | None = os.getenv('KLING_CALLBACK_SHARED_SECRET')
    callback_permissive_debug: bool = os.getenv('KLING_CALLBACK_PERMISSIVE_DEBUG', 'false').lower() == 'true'
    assets_root: str = os.getenv('KLING_ASSETS_ROOT', str(Path(__file__).resolve().parents[1] / 'outputs' / 'clips'))


# Production model policy:
# - latest stable production families to support are the 3.0 base model and 3.0 Omni
# - endpoint/model compatibility still varies, so keep the broad allowed set separate from
#   per-endpoint allowlists that represent the current intended production posture
ALLOWED_30_MODELS = {'kling-v3', 'kling-v3-omni'}
OMNI_MODEL_ENDPOINTS = {'omni'}
PRODUCTION_30_ENDPOINTS = {'text2video', 'image2video', 'reference2video'}

# Historical name kept for compatibility with current imports.
# Current production posture after the latest successful non-live verification refresh:
# - omni runtime model: `kling-v3-omni`
# - non-omni video runtime model: `kling-v3`
# - older `kling-video-o1` production-default assumptions are intentionally retired here
V1_MODELS = {
    'omni': ['kling-v3-omni'],
    'text2video': ['kling-v3'],
    'image2video': ['kling-v3'],
    'reference2video': ['kling-v3'],
}

# confirmed vs provisional contract notes are documented in docs/current/*.md
ENDPOINTS = {
    'text2video': '/v1/videos/text2video',  # provisional until live smoke test
    'image2video': '/v1/videos/image2video',  # provisional until live smoke test
    'omni': '/v1/videos/omni-video',
    'reference2video': '/v1/videos/multi-image2video',
    'extend': '/v1/videos/video-extend',
    'motion_control': '/v1/videos/motion-control',
    'multi_elements': '/v1/videos/multi-elements/init-selection',  # provisional / known drift risk
    'video_effects': '/v1/videos/effects',
    'image_omni': '/v1/images/omni-image',
    'image_generation': '/v1/images/generations',
    'reference2image': '/v1/images/multi-image2image',
    'extend_image': '/v1/images/editing/expand',
    'ai_multi_shot': '/v1/general/ai-multi-shot',
    'text_to_audio': '/v1/audio/text-to-audio',
    'video_to_audio': '/v1/audio/video-to-audio',
    'tts': '/v1/audio/tts',
    'voice_clone': '/v1/general/custom-voices',
    'avatar': '/v1/videos/avatar/image2video',
}

# Pipeline policy: treat 15 seconds as the maximum target length for a single scene.
MAX_SINGLE_SCENE_DURATION_SECONDS = 15
