"""
FikoYT MVD — LTX Loader Node.

Bu node gerçek model ağırlıklarını yüklemez; yalnızca LTX Video üretim
node'larının (FikoYT_MVD_LtxVideoGen veya standart ComfyUI-LTXVideo
LTXVCheckpointLoader) tüketebileceği bir bundle hazırlar.
"""

from __future__ import annotations

import hashlib
import os
from typing import Any, Dict, Tuple

try:
    import folder_paths  # ComfyUI
except Exception:  # pragma: no cover
    folder_paths = None  # type: ignore

from .helpers import (
    LTX_FRAME_PRESETS,
    LTX_RES_PRESETS,
)


def _ltx_checkpoint_secenekleri() -> list:
    """folder_paths üzerinden LTX isimli checkpoint'leri filtrele."""
    if folder_paths is None:
        return ["(LTX checkpoint bulunamadı — models/checkpoints/'a koy)"]
    try:
        tumu = folder_paths.get_filename_list("checkpoints") or []
    except Exception:
        tumu = []
    ltx = [ad for ad in tumu if os.path.basename(ad).lower().startswith("ltx") and ad.lower().endswith(".safetensors")]
    if not ltx:
        return ["(LTX checkpoint bulunamadı — models/checkpoints/'a koy)"]
    return ltx


class FikoYT_MVD_LtxLoader:
    """LTX Video parametrelerini hazırlayan ve checkpoint'i doğrulayan loader."""

    CATEGORY = "FikoYT/MVD/Video"
    FUNCTION = "load"
    RETURN_TYPES = ("LTX_MODEL_BUNDLE",)
    RETURN_NAMES = ("ltx_bundle",)

    @classmethod
    def INPUT_TYPES(cls) -> Dict[str, Any]:
        ckpt_secenek = _ltx_checkpoint_secenekleri()
        cozunurlukler = list(LTX_RES_PRESETS.keys())
        frame_secenekleri = [str(f) for f in LTX_FRAME_PRESETS]

        return {
            "required": {
                "checkpoint": (ckpt_secenek,),
                "resolution": (cozunurlukler, {"default": cozunurlukler[1] if len(cozunurlukler) > 1 else cozunurlukler[0]}),
                "frames": (frame_secenekleri, {"default": "121"}),
                "fps": ("INT", {"default": 24, "min": 8, "max": 60, "step": 1}),
                "guidance_scale": ("FLOAT", {"default": 3.0, "min": 1.0, "max": 15.0, "step": 0.1}),
                "steps": ("INT", {"default": 30, "min": 10, "max": 100, "step": 1}),
                "seed": ("INT", {"default": 0, "min": 0, "max": 0xFFFFFFFFFFFFFFFF}),
                "motion_strength": ("FLOAT", {"default": 0.85, "min": 0.0, "max": 2.0, "step": 0.05}),
            },
            "optional": {
                "clip_skip": ("INT", {"default": 0, "min": 0, "max": 12, "step": 1}),
            },
        }

    @classmethod
    def VALIDATE_INPUTS(cls, **kwargs) -> bool:
        return True

    @classmethod
    def IS_CHANGED(cls, **kwargs) -> str:
        h = hashlib.sha256()
        for k in sorted(kwargs.keys()):
            h.update(f"{k}={kwargs[k]}".encode("utf-8", errors="ignore"))
        return h.hexdigest()

    # ------------------------------------------------------------------
    def load(
        self,
        checkpoint: str,
        resolution: str,
        frames: str,
        fps: int,
        guidance_scale: float,
        steps: int,
        seed: int,
        motion_strength: float,
        clip_skip: int = 0,
    ) -> Tuple[Dict[str, Any]]:
        if not checkpoint or checkpoint.startswith("("):
            raise ValueError(
                "LTX checkpoint seçilmedi. models/checkpoints/ klasörüne "
                "ltx-video-*.safetensors koy."
            )

        tam_yol = None
        if folder_paths is not None:
            try:
                tam_yol = folder_paths.get_full_path("checkpoints", checkpoint)
            except Exception:
                tam_yol = None

        if not tam_yol or not os.path.isfile(tam_yol):
            raise ValueError(f"LTX checkpoint bulunamadı: {checkpoint}")

        if resolution not in LTX_RES_PRESETS:
            raise ValueError(f"Geçersiz çözünürlük preset'i: {resolution}")

        w, h, _varsayilan_frame = LTX_RES_PRESETS[resolution]

        try:
            frame_sayisi = int(frames)
        except Exception:
            frame_sayisi = 121
        if frame_sayisi not in LTX_FRAME_PRESETS:
            # En yakına snap
            frame_sayisi = min(LTX_FRAME_PRESETS, key=lambda x: abs(x - frame_sayisi))

        bundle: Dict[str, Any] = {
            "checkpoint": checkpoint,
            "ckpt_path": tam_yol,
            "resolution": resolution,
            "width": int(w),
            "height": int(h),
            "frames": int(frame_sayisi),
            "fps": int(fps),
            "guidance_scale": float(guidance_scale),
            "steps": int(steps),
            "seed": int(seed),
            "motion_strength": float(motion_strength),
            "clip_skip": int(clip_skip),
        }
        return (bundle,)


NODE_CLASS_MAPPINGS = {
    "FikoYT_MVD_LtxLoader": FikoYT_MVD_LtxLoader,
}

NODE_DISPLAY_NAME_MAPPINGS = {
    "FikoYT_MVD_LtxLoader": "🎬 FikoYT | LTX Loader",
}
