from __future__ import annotations

import json

try:
    from .filter_config import (
        build_ethnicity_list_json,
        build_filter_config_json,
    )
    from .generation_profile_config import (
        build_generation_profile_json,
        generation_profile_choices,
    )
except ImportError:  # Allows local smoke tests from the repository root.
    from filter_config import (
        build_ethnicity_list_json,
        build_filter_config_json,
    )
    from generation_profile_config import (
        build_generation_profile_json,
        generation_profile_choices,
    )


SXCP_GENERATION_PROFILE = "SXCP_GENERATION_PROFILE"
SXCP_FILTER_CONFIG = "SXCP_FILTER_CONFIG"
SXCP_ETHNICITY_LIST = "SXCP_ETHNICITY_LIST"


class SxCPGenerationProfile:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "profile": (generation_profile_choices(), {"default": "balanced"}),
                "clothing_override": (["profile_default", "random", "full", "minimal"], {"default": "profile_default"}),
                "poses_override": (["profile_default", "random", "standard", "evocative"], {"default": "profile_default"}),
                "expression_enabled": ("BOOLEAN", {"default": True}),
                "expression_intensity_mode": (["profile_default", "random", "fixed"], {"default": "profile_default"}),
                "expression_intensity": ("FLOAT", {"default": -1.0, "min": -1.0, "max": 1.0, "step": 0.01}),
                "backside_bias": ("FLOAT", {"default": -1.0, "min": -1.0, "max": 1.0, "step": 0.01}),
                "minimal_clothing_ratio": ("FLOAT", {"default": -1.0, "min": -1.0, "max": 1.0, "step": 0.01}),
                "standard_pose_ratio": ("FLOAT", {"default": -1.0, "min": -1.0, "max": 1.0, "step": 0.01}),
                "trigger_policy": (["profile_default", "prepend_trigger", "do_not_prepend"], {"default": "profile_default"}),
            }
        }

    RETURN_TYPES = (SXCP_GENERATION_PROFILE, "STRING")
    RETURN_NAMES = ("generation_profile", "summary")
    FUNCTION = "build"
    CATEGORY = "prompt_builder"

    def build(
        self,
        profile,
        clothing_override,
        poses_override,
        expression_enabled,
        expression_intensity_mode,
        expression_intensity,
        backside_bias,
        minimal_clothing_ratio,
        standard_pose_ratio,
        trigger_policy,
    ):
        config = build_generation_profile_json(
            profile=profile,
            clothing_override=clothing_override,
            poses_override=poses_override,
            expression_enabled=expression_enabled,
            expression_intensity_mode=expression_intensity_mode,
            expression_intensity=expression_intensity,
            backside_bias=backside_bias,
            minimal_clothing_ratio=minimal_clothing_ratio,
            standard_pose_ratio=standard_pose_ratio,
            trigger_policy=trigger_policy,
        )
        parsed = json.loads(config)
        if not parsed.get("expression_enabled", True):
            expression_summary = "expression disabled"
        elif float(parsed.get("expression_intensity", 0.5)) < 0:
            expression_summary = "expression random"
        else:
            expression_summary = f"expression {parsed['expression_intensity']}"
        summary = f"{parsed['profile']}: {parsed['clothing']}, {parsed['poses']}, {expression_summary}"
        return config, summary


class SxCPAdvancedFilters:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "include_european": ("BOOLEAN", {"default": True}),
                "include_mediterranean_mena": ("BOOLEAN", {"default": True}),
                "include_latina": ("BOOLEAN", {"default": True}),
                "include_east_asian": ("BOOLEAN", {"default": True}),
                "include_southeast_asian": ("BOOLEAN", {"default": True}),
                "include_south_asian": ("BOOLEAN", {"default": True}),
                "include_black_african": ("BOOLEAN", {"default": True}),
                "include_indigenous": ("BOOLEAN", {"default": True}),
                "include_mixed": ("BOOLEAN", {"default": True}),
                "include_plus_size": ("BOOLEAN", {"default": True}),
                "figure": (["random", "curvy", "balanced", "bombshell"], {"default": "random"}),
            }
        }

    RETURN_TYPES = (SXCP_FILTER_CONFIG,)
    RETURN_NAMES = ("filter_config",)
    FUNCTION = "build"
    CATEGORY = "prompt_builder"

    def build(
        self,
        include_european,
        include_mediterranean_mena,
        include_latina,
        include_east_asian,
        include_southeast_asian,
        include_south_asian,
        include_black_african,
        include_indigenous,
        include_mixed,
        include_plus_size,
        figure,
    ):
        return (
            build_filter_config_json(
                figure=figure,
                include_european=include_european,
                include_mediterranean_mena=include_mediterranean_mena,
                include_latina=include_latina,
                include_east_asian=include_east_asian,
                include_southeast_asian=include_southeast_asian,
                include_south_asian=include_south_asian,
                include_black_african=include_black_african,
                include_indigenous=include_indigenous,
                include_mixed=include_mixed,
                include_plus_size=include_plus_size,
            ),
        )


class SxCPEthnicityList:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "include_european": ("BOOLEAN", {"default": False}),
                "include_mediterranean_mena": ("BOOLEAN", {"default": False}),
                "include_latina": ("BOOLEAN", {"default": False}),
                "include_east_asian": ("BOOLEAN", {"default": False}),
                "include_southeast_asian": ("BOOLEAN", {"default": False}),
                "include_south_asian": ("BOOLEAN", {"default": False}),
                "include_black_african": ("BOOLEAN", {"default": False}),
                "include_indigenous": ("BOOLEAN", {"default": False}),
                "include_mixed": ("BOOLEAN", {"default": False}),
                "include_asian": ("BOOLEAN", {"default": False}),
                "include_white_asian": ("BOOLEAN", {"default": False}),
                "include_western_european": ("BOOLEAN", {"default": False}),
                "include_french_european": ("BOOLEAN", {"default": False}),
                "include_germanic_european": ("BOOLEAN", {"default": False}),
                "include_nordic_european": ("BOOLEAN", {"default": False}),
                "include_celtic_european": ("BOOLEAN", {"default": False}),
                "include_slavic_european": ("BOOLEAN", {"default": False}),
                "include_baltic_european": ("BOOLEAN", {"default": False}),
                "include_alpine_european": ("BOOLEAN", {"default": False}),
                "include_balkan_european": ("BOOLEAN", {"default": False}),
                "include_greek_mediterranean": ("BOOLEAN", {"default": False}),
                "include_italian_mediterranean": ("BOOLEAN", {"default": False}),
                "include_iberian_mediterranean": ("BOOLEAN", {"default": False}),
                "strict_excludes": ("BOOLEAN", {"default": True}),
            }
        }

    RETURN_TYPES = (SXCP_ETHNICITY_LIST, SXCP_FILTER_CONFIG, "STRING")
    RETURN_NAMES = ("ethnicity_list", "filter_config", "summary")
    FUNCTION = "build"
    CATEGORY = "prompt_builder"

    def build(
        self,
        include_european,
        include_mediterranean_mena,
        include_latina,
        include_east_asian,
        include_southeast_asian,
        include_south_asian,
        include_black_african,
        include_indigenous,
        include_mixed,
        include_asian,
        include_white_asian,
        include_western_european,
        include_french_european,
        include_germanic_european,
        include_nordic_european,
        include_celtic_european,
        include_slavic_european,
        include_baltic_european,
        include_alpine_european,
        include_balkan_european,
        include_greek_mediterranean,
        include_italian_mediterranean,
        include_iberian_mediterranean,
        strict_excludes,
    ):
        result = build_ethnicity_list_json(
            include_european=include_european,
            include_mediterranean_mena=include_mediterranean_mena,
            include_latina=include_latina,
            include_east_asian=include_east_asian,
            include_southeast_asian=include_southeast_asian,
            include_south_asian=include_south_asian,
            include_black_african=include_black_african,
            include_indigenous=include_indigenous,
            include_mixed=include_mixed,
            include_asian=include_asian,
            include_white_asian=include_white_asian,
            include_western_european=include_western_european,
            include_french_european=include_french_european,
            include_germanic_european=include_germanic_european,
            include_nordic_european=include_nordic_european,
            include_celtic_european=include_celtic_european,
            include_slavic_european=include_slavic_european,
            include_baltic_european=include_baltic_european,
            include_alpine_european=include_alpine_european,
            include_balkan_european=include_balkan_european,
            include_greek_mediterranean=include_greek_mediterranean,
            include_italian_mediterranean=include_italian_mediterranean,
            include_iberian_mediterranean=include_iberian_mediterranean,
            strict_excludes=strict_excludes,
        )
        return result["ethnicity"], result["filter_config"], result["summary"]


NODE_CLASS_MAPPINGS = {
    "SxCPGenerationProfile": SxCPGenerationProfile,
    "SxCPAdvancedFilters": SxCPAdvancedFilters,
    "SxCPEthnicityList": SxCPEthnicityList,
}

NODE_DISPLAY_NAME_MAPPINGS = {
    "SxCPGenerationProfile": "SxCP Generation Profile",
    "SxCPAdvancedFilters": "SxCP Advanced Filters",
    "SxCPEthnicityList": "SxCP Ethnicity List",
}
