"""FikoYT IPAdapter v2 Style — IPAdapter Plus node'una sarmalayıcı."""
import os

_IPADAPTER_APPLY = None
try:
    from custom_nodes.ComfyUI_IPAdapter_plus import IPAdapterPlus as _ipa_mod  # type: ignore
    _IPADAPTER_APPLY = getattr(_ipa_mod, "IPAdapterAdvanced", None) or getattr(_ipa_mod, "IPAdapter", None)
except Exception:
    try:
        import ComfyUI_IPAdapter_plus  # type: ignore  # noqa: F401
    except Exception:
        pass

from ..core import ensure_model, get_models_dir


IPADAPTER_MODELS = [
    {"repo": "h94/IP-Adapter", "file": "models/ip-adapter_sd15.safetensors",          "subdir": "ipadapter"},
    {"repo": "h94/IP-Adapter", "file": "models/ip-adapter-plus_sd15.safetensors",     "subdir": "ipadapter"},
    {"repo": "h94/IP-Adapter", "file": "sdxl_models/ip-adapter_sdxl.safetensors",     "subdir": "ipadapter"},
    {"repo": "h94/IP-Adapter", "file": "sdxl_models/ip-adapter-plus_sdxl_vit-h.safetensors", "subdir": "ipadapter"},
]

CLIP_VISION_MODELS = [
    {"repo": "h94/IP-Adapter", "file": "models/image_encoder/model.safetensors",          "subdir": "clip_vision"},
    {"repo": "h94/IP-Adapter", "file": "sdxl_models/image_encoder/model.safetensors",     "subdir": "clip_vision"},
]


def _download_all(auto_download: bool) -> None:
    if not auto_download:
        return
    for m in IPADAPTER_MODELS + CLIP_VISION_MODELS:
        target = os.path.join(get_models_dir(m["subdir"]), os.path.basename(m["file"]))
        if not os.path.isfile(target):
            ensure_model(m["repo"], m["file"], m["subdir"])


class FikoYTIPAdapterV2:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "model": ("MODEL",),
                "style_image": ("IMAGE",),
                "weight":      ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.05}),
                "noise":       ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.01}),
                "weight_type": (["linear", "ease in", "ease out", "ease in-out", "reverse in-out",
                                 "weak input", "weak output", "weak middle", "strong middle"],
                                {"default": "linear"}),
                "start_at": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.01}),
                "end_at":   ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
                "auto_download": ("BOOLEAN", {"default": True}),
            }
        }

    RETURN_TYPES = ("MODEL",)
    RETURN_NAMES = ("MODEL",)
    FUNCTION = "apply"
    CATEGORY = "FikoYT/image"

    def apply(self, model, style_image, weight, noise, weight_type, start_at, end_at, auto_download):
        _download_all(auto_download)

        if _IPADAPTER_APPLY is None:
            raise RuntimeError(
                "ComfyUI_IPAdapter_plus node bulunamadı. "
                "https://github.com/cubiq/ComfyUI_IPAdapter_plus yükleyin."
            )

        try:
            instance = _IPADAPTER_APPLY()
            if hasattr(instance, "apply_ipadapter"):
                out = instance.apply_ipadapter(
                    model=model, ipadapter=None, image=style_image,
                    weight=weight, weight_type=weight_type,
                    start_at=start_at, end_at=end_at, attn_mask=None,
                )
            else:
                raise AttributeError("IPAdapter Advanced API'si tanınmıyor.")
        except Exception as e:
            raise RuntimeError(
                f"IPAdapter v2 uygulanamadı: {e}\n"
                "ComfyUI_IPAdapter_plus node'unu doğrudan kullanmayı deneyin "
                "(IPAdapter Unified Loader + IPAdapter Advanced zinciri)."
            )

        if isinstance(out, tuple):
            return (out[0],)
        return (out,)


NODE_CLASS_MAPPINGS = {"FikoYTIPAdapterV2": FikoYTIPAdapterV2}
NODE_DISPLAY_NAME_MAPPINGS = {"FikoYTIPAdapterV2": "FikoYT • IPAdapter v2 Style"}
