from __future__ import annotations

try:
    from aiohttp import web
    from server import PromptServer
except Exception:
    web = None
    PromptServer = None

SXCP_HAIR_CONFIG = "SXCP_HAIR_CONFIG"
SXCP_CHARACTERISTICS = "SXCP_CHARACTERISTICS"
SXCP_CHARACTER_MANUAL = "SXCP_CHARACTER_MANUAL"
SXCP_ETHNICITY_LIST = "SXCP_ETHNICITY_LIST"
SXCP_FILTER_CONFIG = "SXCP_FILTER_CONFIG"
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_CATEGORY_CONFIG = "SXCP_CATEGORY_CONFIG"
SXCP_CAST_CONFIG = "SXCP_CAST_CONFIG"
SXCP_GENERATION_PROFILE = "SXCP_GENERATION_PROFILE"
SXCP_INSTA_OF_OPTIONS = "SXCP_INSTA_OF_OPTIONS"
SXCP_STYLE_CONFIG = "SXCP_STYLE_CONFIG"
SXCP_HARDCORE_POSITION_CONFIG = "SXCP_HARDCORE_POSITION_CONFIG"
SXCP_CHARACTER_CAST = "SXCP_CHARACTER_CAST"
SXCP_CHARACTER_SLOT = "SXCP_CHARACTER_SLOT"
SXCP_CHARACTER_PROFILE = "SXCP_CHARACTER_PROFILE"
SXCP_SCENE = "SXCP_SCENE"
SXCP_SCENE_LAYER_SEED = "SXCP_SCENE_LAYER_SEED"
SXCP_SCENE_CAST_OPTIONS = "SXCP_SCENE_CAST_OPTIONS"
SXCP_SCENE_CHARACTER_OPTIONS = "SXCP_SCENE_CHARACTER_OPTIONS"
SXCP_SCENE_WARDROBE_OPTIONS = "SXCP_SCENE_WARDROBE_OPTIONS"
SXCP_SCENE_LOCATION_OPTIONS = "SXCP_SCENE_LOCATION_OPTIONS"
SXCP_SCENE_SET_OPTIONS = "SXCP_SCENE_SET_OPTIONS"
SXCP_SCENE_BLOCKING_OPTIONS = "SXCP_SCENE_BLOCKING_OPTIONS"
SXCP_SCENE_ACTION_OPTIONS = "SXCP_SCENE_ACTION_OPTIONS"
SXCP_SCENE_PERFORMANCE_OPTIONS = "SXCP_SCENE_PERFORMANCE_OPTIONS"
SXCP_SCENE_CAMERA_OPTIONS = "SXCP_SCENE_CAMERA_OPTIONS"
SXCP_SCENE_COMPOSITION_OPTIONS = "SXCP_SCENE_COMPOSITION_OPTIONS"
SXCP_SCENE_LIGHTING_OPTIONS = "SXCP_SCENE_LIGHTING_OPTIONS"
SXCP_SCENE_BRANCH_OPTIONS = "SXCP_SCENE_BRANCH_OPTIONS"

try:
    from .node_tooltips import install_input_tooltips as _install_input_tooltips
except ImportError:
    from node_tooltips import install_input_tooltips as _install_input_tooltips


try:
    from .loop_nodes import (
        LOOP_NODE_CLASS_MAPPINGS,
        LOOP_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from .node_camera import (
        NODE_CLASS_MAPPINGS as CAMERA_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as CAMERA_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from .node_builder import (
        NODE_CLASS_MAPPINGS as BUILDER_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as BUILDER_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from .node_character import (
        NODE_CLASS_MAPPINGS as CHARACTER_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as CHARACTER_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from .node_hardcore_position import (
        NODE_CLASS_MAPPINGS as HARDCORE_POSITION_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as HARDCORE_POSITION_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from .node_choice_board import (
        NODE_CLASS_MAPPINGS as CHOICE_BOARD_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as CHOICE_BOARD_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from .node_formatter import (
        NODE_CLASS_MAPPINGS as FORMATTER_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as FORMATTER_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from .node_insta import (
        NODE_CLASS_MAPPINGS as INSTA_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as INSTA_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from .node_profile_filter import (
        NODE_CLASS_MAPPINGS as PROFILE_FILTER_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as PROFILE_FILTER_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from .node_route_config import (
        NODE_CLASS_MAPPINGS as ROUTE_CONFIG_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as ROUTE_CONFIG_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from .node_seed_resolution import (
        NODE_CLASS_MAPPINGS as SEED_RESOLUTION_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as SEED_RESOLUTION_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from .node_scene import (
        NODE_CLASS_MAPPINGS as SCENE_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as SCENE_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from .server_routes import (
        accumulator_delete_payload,
        accumulator_list_payload,
        accumulator_move_payload,
        accumulator_retake_payload,
        accumulator_save_payload,
        profile_save_cached_payload,
    )
except ImportError:
    from loop_nodes import (
        LOOP_NODE_CLASS_MAPPINGS,
        LOOP_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from node_camera import (
        NODE_CLASS_MAPPINGS as CAMERA_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as CAMERA_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from node_builder import (
        NODE_CLASS_MAPPINGS as BUILDER_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as BUILDER_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from node_character import (
        NODE_CLASS_MAPPINGS as CHARACTER_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as CHARACTER_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from node_hardcore_position import (
        NODE_CLASS_MAPPINGS as HARDCORE_POSITION_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as HARDCORE_POSITION_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from node_choice_board import (
        NODE_CLASS_MAPPINGS as CHOICE_BOARD_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as CHOICE_BOARD_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from node_formatter import (
        NODE_CLASS_MAPPINGS as FORMATTER_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as FORMATTER_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from node_insta import (
        NODE_CLASS_MAPPINGS as INSTA_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as INSTA_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from node_profile_filter import (
        NODE_CLASS_MAPPINGS as PROFILE_FILTER_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as PROFILE_FILTER_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from node_route_config import (
        NODE_CLASS_MAPPINGS as ROUTE_CONFIG_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as ROUTE_CONFIG_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from node_seed_resolution import (
        NODE_CLASS_MAPPINGS as SEED_RESOLUTION_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as SEED_RESOLUTION_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from node_scene import (
        NODE_CLASS_MAPPINGS as SCENE_NODE_CLASS_MAPPINGS,
        NODE_DISPLAY_NAME_MAPPINGS as SCENE_NODE_DISPLAY_NAME_MAPPINGS,
    )
    from server_routes import (
        accumulator_delete_payload,
        accumulator_list_payload,
        accumulator_move_payload,
        accumulator_retake_payload,
        accumulator_save_payload,
        profile_save_cached_payload,
    )


if PromptServer is not None and web is not None:
    @PromptServer.instance.routes.post("/sxcp/profile/save_cached")
    async def sxcp_save_cached_profile(request):
        try:
            payload = await request.json()
            result = profile_save_cached_payload(payload)
            return web.json_response(result)
        except Exception as exc:
            return web.json_response({"error": str(exc)}, status=400)

    @PromptServer.instance.routes.post("/sxcp/accumulator/list")
    async def sxcp_accumulator_list(request):
        try:
            payload = await request.json()
            result = accumulator_list_payload(payload)
            return web.json_response(result)
        except Exception as exc:
            return web.json_response({"error": str(exc)}, status=400)

    @PromptServer.instance.routes.post("/sxcp/accumulator/delete")
    async def sxcp_accumulator_delete(request):
        try:
            payload = await request.json()
            result = accumulator_delete_payload(payload)
            return web.json_response(result)
        except Exception as exc:
            return web.json_response({"error": str(exc)}, status=400)

    @PromptServer.instance.routes.post("/sxcp/accumulator/save")
    async def sxcp_accumulator_save(request):
        try:
            payload = await request.json()
            result = accumulator_save_payload(payload)
            return web.json_response(result)
        except Exception as exc:
            return web.json_response({"error": str(exc)}, status=400)

    @PromptServer.instance.routes.post("/sxcp/accumulator/move")
    async def sxcp_accumulator_move(request):
        try:
            payload = await request.json()
            result = accumulator_move_payload(payload)
            return web.json_response(result)
        except Exception as exc:
            return web.json_response({"error": str(exc)}, status=400)

    @PromptServer.instance.routes.post("/sxcp/accumulator/retake")
    async def sxcp_accumulator_retake(request):
        try:
            payload = await request.json()
            result = accumulator_retake_payload(payload)
            return web.json_response(result)
        except Exception as exc:
            return web.json_response({"error": str(exc)}, status=400)


NODE_CLASS_MAPPINGS = {}
NODE_CLASS_MAPPINGS.update(BUILDER_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(SEED_RESOLUTION_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(CAMERA_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(CHARACTER_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(HARDCORE_POSITION_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(CHOICE_BOARD_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(FORMATTER_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(INSTA_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(ROUTE_CONFIG_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(PROFILE_FILTER_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(SCENE_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(LOOP_NODE_CLASS_MAPPINGS)
_install_input_tooltips(NODE_CLASS_MAPPINGS)

NODE_DISPLAY_NAME_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS.update(BUILDER_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(SEED_RESOLUTION_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(CAMERA_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(CHARACTER_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(HARDCORE_POSITION_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(CHOICE_BOARD_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(FORMATTER_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(INSTA_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(ROUTE_CONFIG_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(PROFILE_FILTER_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(SCENE_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(LOOP_NODE_DISPLAY_NAME_MAPPINGS)

WEB_DIRECTORY = "./web"

__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
