"""Input field molecule: a labeled text input with optional helper/error text."""

from __future__ import annotations

import pydivkit as dk

from smarty_ui.primitives.text import label, caption
from smarty_ui._helpers import vstack
from smarty_ui.tokens.theme import Theme, default_theme


def input_field(
    placeholder: str,
    *,
    field_label: str | None = None,
    helper_text: str | None = None,
    error_text: str | None = None,
    variable_name: str = "input_value",
    keyboard_type: str = "default",
    max_visible_lines: int = 1,
    corner_radius: int = 8,
    theme: Theme = default_theme,
) -> dk.DivContainer:
    """Labeled text input with optional helper or error message.

    Composes a label atom, a DivInput, and a caption atom into
    a vertical stack.
    """
    items: list[dk.Div] = []

    # Optional label above the input
    if field_label:
        items.append(
            label(
                field_label,
                size=theme.typography.caption_size,
                weight=theme.typography.medium_weight,
                theme=theme,
            )
        )

    # The input element itself
    kb_map = {
        "default": dk.DivInputKeyboardType.SINGLE_LINE_TEXT,
        "multiline": dk.DivInputKeyboardType.MULTI_LINE_TEXT,
        "email": dk.DivInputKeyboardType.EMAIL,
        "number": dk.DivInputKeyboardType.NUMBER,
        "phone": dk.DivInputKeyboardType.PHONE,
        "uri": dk.DivInputKeyboardType.URI,
        "password": dk.DivInputKeyboardType.PASSWORD,
    }
    text_input = dk.DivInput(
        text_variable=variable_name,
        font_size=theme.typography.body_size,
        text_color=theme.colors.text_primary,
        hint_text=placeholder,
        hint_color=theme.colors.text_secondary,
        keyboard_type=kb_map.get(
            keyboard_type, dk.DivInputKeyboardType.SINGLE_LINE_TEXT
        ),
        max_visible_lines=max_visible_lines,
        width=dk.DivMatchParentSize(),
        height=dk.DivFixedSize(value=44),
        paddings=dk.DivEdgeInsets(
            left=theme.spacing.md,
            right=theme.spacing.md,
            top=theme.spacing.sm,
            bottom=theme.spacing.sm,
        ),
        border=dk.DivBorder(
            corner_radius=corner_radius,
            stroke=dk.DivStroke(
                color=theme.colors.error if error_text else theme.colors.border,
                width=1,
            ),
        ),
    )
    items.append(text_input)

    # Helper or error text below the input
    if error_text:
        items.append(caption(error_text, color=theme.colors.error, theme=theme))
    elif helper_text:
        items.append(caption(helper_text, theme=theme))

    return vstack(*items, gap=theme.spacing.xs)
