from __future__ import annotations

import json

try:
    from .prompt_builder import (
        build_insta_of_options_json,
        build_insta_of_pair,
        camera_detail_choices,
        camera_mode_choices,
        ethnicity_choices,
        hardcore_detail_density_choices,
    )
except ImportError:  # Allows local smoke tests from the repository root.
    from prompt_builder import (
        build_insta_of_options_json,
        build_insta_of_pair,
        camera_detail_choices,
        camera_mode_choices,
        ethnicity_choices,
        hardcore_detail_density_choices,
    )


SXCP_SEED_CONFIG = "SXCP_SEED_CONFIG"
SXCP_CAMERA_CONFIG = "SXCP_CAMERA_CONFIG"
SXCP_LOCATION_CONFIG = "SXCP_LOCATION_CONFIG"
SXCP_COMPOSITION_CONFIG = "SXCP_COMPOSITION_CONFIG"
SXCP_INSTA_OF_OPTIONS = "SXCP_INSTA_OF_OPTIONS"
SXCP_HARDCORE_POSITION_CONFIG = "SXCP_HARDCORE_POSITION_CONFIG"
SXCP_CHARACTER_CAST = "SXCP_CHARACTER_CAST"
SXCP_CHARACTER_PROFILE = "SXCP_CHARACTER_PROFILE"
SXCP_ETHNICITY_LIST = "SXCP_ETHNICITY_LIST"
SXCP_FILTER_CONFIG = "SXCP_FILTER_CONFIG"
SXCP_STYLE_CONFIG = "SXCP_STYLE_CONFIG"


class SxCPInstaOFOptions:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "softcore_cast": (["solo", "same_as_hardcore"], {"default": "solo"}),
                "hardcore_cast": (["use_counts", "couple", "threesome", "group"], {"default": "use_counts"}),
                "hardcore_women_count": ("INT", {"default": 1, "min": 0, "max": 12, "step": 1}),
                "hardcore_men_count": ("INT", {"default": 1, "min": 0, "max": 12, "step": 1}),
                "softcore_level": (["social_tease", "lingerie_tease", "implied_nude", "explicit_tease", "explicit_nude"], {"default": "lingerie_tease"}),
                "hardcore_level": (["explicit", "hardcore"], {"default": "hardcore"}),
                "softcore_expression_enabled": ("BOOLEAN", {"default": True}),
                "hardcore_expression_enabled": ("BOOLEAN", {"default": True}),
                "softcore_expression_intensity": ("FLOAT", {"default": 0.45, "min": 0.0, "max": 1.0, "step": 0.01}),
                "hardcore_expression_intensity": ("FLOAT", {"default": 0.85, "min": 0.0, "max": 1.0, "step": 0.01}),
                "platform_style": (["hybrid", "instagram", "onlyfans"], {"default": "hybrid"}),
                "continuity": (["same_creator_same_room", "same_creator_new_scene"], {"default": "same_creator_same_room"}),
                "hardcore_clothing_continuity": (["none", "same_outfit", "partially_removed", "implied_nude", "explicit_nude"], {"default": "partially_removed"}),
                "softcore_camera_mode": (["from_camera_config"] + camera_mode_choices(), {"default": "handheld_selfie"}),
                "hardcore_camera_mode": (["from_camera_config", "same_as_softcore"] + camera_mode_choices(), {"default": "from_camera_config"}),
                "camera_detail": (["from_camera_config"] + camera_detail_choices(), {"default": "from_camera_config"}),
                "hardcore_detail_density": (hardcore_detail_density_choices(), {"default": "balanced"}),
            }
        }

    RETURN_TYPES = (SXCP_INSTA_OF_OPTIONS,)
    RETURN_NAMES = ("options_json",)
    FUNCTION = "build"
    CATEGORY = "prompt_builder"

    def build(
        self,
        softcore_cast,
        hardcore_cast,
        hardcore_women_count,
        hardcore_men_count,
        softcore_level,
        hardcore_level,
        softcore_expression_enabled,
        hardcore_expression_enabled,
        softcore_expression_intensity,
        hardcore_expression_intensity,
        platform_style,
        continuity,
        hardcore_clothing_continuity,
        softcore_camera_mode,
        hardcore_camera_mode,
        camera_detail,
        hardcore_detail_density,
    ):
        return (
            build_insta_of_options_json(
                softcore_cast=softcore_cast,
                hardcore_cast=hardcore_cast,
                hardcore_women_count=hardcore_women_count,
                hardcore_men_count=hardcore_men_count,
                softcore_level=softcore_level,
                hardcore_level=hardcore_level,
                softcore_expression_enabled=softcore_expression_enabled,
                hardcore_expression_enabled=hardcore_expression_enabled,
                softcore_expression_intensity=softcore_expression_intensity,
                hardcore_expression_intensity=hardcore_expression_intensity,
                platform_style=platform_style,
                continuity=continuity,
                hardcore_clothing_continuity=hardcore_clothing_continuity,
                softcore_camera_mode=softcore_camera_mode,
                hardcore_camera_mode=hardcore_camera_mode,
                camera_detail=camera_detail,
                hardcore_detail_density=hardcore_detail_density,
            ),
        )


class SxCPInstaOFPromptPair:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "row_number": ("INT", {"default": 1, "min": 1, "max": 1000000, "step": 1}),
                "start_index": ("INT", {"default": 41, "min": 1, "max": 1000000, "step": 1}),
                "seed": ("INT", {"default": 20260614, "min": 0, "max": 0xFFFFFFFF, "step": 1}),
                "ethnicity": (ethnicity_choices(), {"default": "any"}),
                "figure": (["random", "curvy", "balanced", "bombshell"], {"default": "random"}),
                "trigger": ("STRING", {"default": "sxcpinup_coloredpencil"}),
                "prepend_trigger_to_prompt": ("BOOLEAN", {"default": True}),
            },
            "optional": {
                "seed_config": (SXCP_SEED_CONFIG,),
                "options_json": (SXCP_INSTA_OF_OPTIONS,),
                "filter_config": (SXCP_FILTER_CONFIG,),
                "ethnicity_list": (SXCP_ETHNICITY_LIST,),
                "camera_config": (SXCP_CAMERA_CONFIG,),
                "softcore_camera_config": (SXCP_CAMERA_CONFIG,),
                "hardcore_camera_config": (SXCP_CAMERA_CONFIG,),
                "location_config": (SXCP_LOCATION_CONFIG,),
                "composition_config": (SXCP_COMPOSITION_CONFIG,),
                "style_config": (SXCP_STYLE_CONFIG,),
                "character_profile": (SXCP_CHARACTER_PROFILE,),
                "character_cast": (SXCP_CHARACTER_CAST,),
                "hardcore_position_config": (SXCP_HARDCORE_POSITION_CONFIG,),
                "extra_positive": ("STRING", {"default": "", "multiline": True}),
                "extra_negative": ("STRING", {"default": "", "multiline": True}),
            },
        }

    RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING", "STRING", "STRING", "STRING")
    RETURN_NAMES = (
        "softcore_prompt",
        "hardcore_prompt",
        "softcore_negative_prompt",
        "hardcore_negative_prompt",
        "softcore_caption",
        "hardcore_caption",
        "shared_descriptor",
        "metadata_json",
    )
    FUNCTION = "build"
    CATEGORY = "prompt_builder"

    def build(
        self,
        row_number,
        start_index,
        seed,
        ethnicity,
        figure,
        trigger,
        prepend_trigger_to_prompt,
        seed_config="",
        options_json="",
        filter_config="",
        ethnicity_list="",
        camera_config="",
        softcore_camera_config="",
        hardcore_camera_config="",
        location_config="",
        composition_config="",
        style_config="",
        character_profile="",
        character_cast="",
        hardcore_position_config="",
        extra_positive="",
        extra_negative="",
        no_plus_women=False,
        no_black=False,
    ):
        row = build_insta_of_pair(
            row_number=row_number,
            start_index=start_index,
            seed=seed,
            ethnicity=ethnicity,
            figure=figure,
            no_plus_women=no_plus_women,
            no_black=no_black,
            trigger=trigger,
            prepend_trigger_to_prompt=prepend_trigger_to_prompt,
            seed_config=seed_config or "",
            options_json=options_json or "",
            filter_config=ethnicity_list or filter_config or "",
            camera_config=camera_config or "",
            softcore_camera_config=softcore_camera_config or "",
            hardcore_camera_config=hardcore_camera_config or "",
            location_config=location_config or "",
            composition_config=composition_config or "",
            style_config=style_config or "",
            character_profile=character_profile or "",
            character_cast=character_cast or "",
            hardcore_position_config=hardcore_position_config or "",
            extra_positive=extra_positive or "",
            extra_negative=extra_negative or "",
        )
        return (
            row["softcore_prompt"],
            row["hardcore_prompt"],
            row["softcore_negative_prompt"],
            row["hardcore_negative_prompt"],
            row["softcore_caption"],
            row["hardcore_caption"],
            row["shared_descriptor"],
            json.dumps(row, ensure_ascii=True, sort_keys=True),
        )


NODE_CLASS_MAPPINGS = {
    "SxCPInstaOFOptions": SxCPInstaOFOptions,
    "SxCPInstaOFPromptPair": SxCPInstaOFPromptPair,
}

NODE_DISPLAY_NAME_MAPPINGS = {
    "SxCPInstaOFOptions": "SxCP Insta/OF Options",
    "SxCPInstaOFPromptPair": "SxCP Insta/OF Prompt Pair",
}
