"""ComfyUI-Wouldliker — recommend a Wouldliker sound from a graph.

Drop this folder into ComfyUI/custom_nodes/ComfyUI-Wouldliker/ and restart.
The node "Wouldliker Recommend Sound" appears under audio/wouldliker and
outputs:

    SOUND_SLUG         (string)  e.g. "vlog"
    SOUND_NAME         (string)  e.g. "Vlog"
    TIKTOK_SOUND_URL   (string)  paste into your downstream uploader
    BRIEF              (string)  one-paragraph creative brief
    CAPTION_MID        (string)  mid-length caption
    CAPTION_WITH_TAGS  (string)  caption + hashtags
    COPY_BOUNDARY      (string)  surface this in your UI

No heavy deps — stdlib `urllib` only.

Public proof is evidence of fit and momentum, not a guarantee of views.
"""

from __future__ import annotations

import json
import urllib.error
import urllib.request

API = "https://wouldliker.com/api"


def _post(path: str, body: dict) -> dict:
    req = urllib.request.Request(
        f"{API}{path}",
        data=json.dumps(body).encode("utf-8"),
        headers={"content-type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=15) as resp:
            return json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        return {"error": "http_error", "status": e.code, "message": e.read().decode("utf-8", "replace")}
    except Exception as e:
        return {"error": "transport_error", "message": str(e)}


class WouldlikerRecommendSound:
    CATEGORY = "audio/wouldliker"
    FUNCTION = "run"

    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "description":      ("STRING", {"multiline": True, "default": "morning routine vlog"}),
                "platform":         (["tiktok", "reels", "shorts"], {"default": "tiktok"}),
                "duration_seconds": ("INT", {"default": 22, "min": 1, "max": 600}),
                "content_type":     (["", "vlog", "product_reveal", "explainer", "beauty", "football"], {"default": ""}),
                "language":         (["en", "es"], {"default": "en"}),
                "is_aigc":          ("BOOLEAN", {"default": True, "label_on": "AI-generated", "label_off": "Real footage"}),
            }
        }

    RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING", "STRING", "STRING")
    RETURN_NAMES = (
        "SOUND_SLUG",
        "SOUND_NAME",
        "TIKTOK_SOUND_URL",
        "BRIEF",
        "CAPTION_MID",
        "CAPTION_WITH_TAGS",
        "COPY_BOUNDARY",
    )

    def run(self, description, platform, duration_seconds, content_type, language, is_aigc):
        rec_body = {
            "description":      description,
            "platform":         platform,
            "duration_seconds": int(duration_seconds),
            "language":         language,
            "is_aigc":          bool(is_aigc),
        }
        if content_type:
            rec_body["content_type"] = content_type

        rec = _post("/recommend", rec_body)
        if "error" in rec:
            empty = "(Wouldliker error: " + rec.get("message", "unknown") + ")"
            return (empty, empty, "", empty, empty, empty, "")

        sound_slug = rec["primary_sound"]["sound_slug"]
        sound_name = rec["primary_sound"]["name"]
        tiktok_url = rec["primary_sound"]["tiktok_sound_url"]

        brief = _post("/brief", {
            "sound_slug":       sound_slug,
            "description":      description,
            "platform":         platform,
            "duration_seconds": int(duration_seconds),
            "language":         language,
            "is_aigc":          bool(is_aigc),
        })
        if "error" in brief:
            return (sound_slug, sound_name, tiktok_url,
                    "(Wouldliker brief error: " + brief.get("message", "unknown") + ")",
                    "", "", rec.get("copy_boundary", ""))

        return (
            sound_slug,
            sound_name,
            tiktok_url,
            brief.get("clip_brief", ""),
            brief.get("caption_pack", {}).get("mid", ""),
            brief.get("caption_pack", {}).get("with_hashtags", ""),
            rec.get("copy_boundary", ""),
        )


NODE_CLASS_MAPPINGS = {"WouldlikerRecommendSound": WouldlikerRecommendSound}
NODE_DISPLAY_NAME_MAPPINGS = {"WouldlikerRecommendSound": "Wouldliker Recommend Sound"}
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
