# retoor <retoor@molodetz.nl>

from __future__ import annotations

from .schema import InteractionRequest, WidgetModel, flatten_widgets


def project_markdown(request: InteractionRequest, interaction_id: str) -> str:
    lines: list[str] = [f"### {request.title}", ""]
    if request.description:
        lines.append(request.description)
        lines.append("")
    for widget in request.widgets:
        lines.extend(_widget_lines(widget))
    actions = f"[{request.submit_label}]"
    if request.cancelable:
        actions += f" [{request.cancel_label}]"
    lines.append("")
    lines.append(actions)
    lines.append(f"<!-- ai-interaction:{interaction_id} -->")
    return "\n".join(lines).strip() + "\n"


def project_plain_menu(request: InteractionRequest) -> str:
    lines: list[str] = [request.title]
    if request.description:
        lines.append(request.description)
    lines.append("")
    widgets = [
        w
        for w in flatten_widgets(request.widgets)
        if w.type != "//"
    ]
    if len(widgets) == 1 and widgets[0].type == "confirm":
        lines.append(f"Reply: yes | no | cancel")
        return "\n".join(lines).strip() + "\n"
    if len(widgets) == 1 and widgets[0].type in ("choice", "select"):
        options = widgets[0].options[:12]
        lines.append(f"{widgets[0].label}")
        for index, option in enumerate(options, start=1):
            lines.append(f"{index}. {option.label} (`{option.value}`)")
        lines.append("")
        lines.append(f"Reply with a number (1-{len(options)}) or `cancel`.")
        return "\n".join(lines).strip() + "\n"
    for widget in widgets:
        if widget.type in ("choice", "choice_multi", "select"):
            lines.append(f"{widget.label}:")
            for index, option in enumerate(widget.options[:12], start=1):
                lines.append(f"  {index}. {option.label} (`{option.value}`)")
        elif widget.type == "confirm":
            lines.append(f"{widget.label}: yes | no")
        else:
            lines.append(f"{widget.label}: (free text)")
    lines.append("")
    lines.append("Reply with values, or `cancel`.")
    return "\n".join(lines).strip() + "\n"


def _widget_lines(widget: WidgetModel, indent: str = "") -> list[str]:
    if widget.type == "//":
        return [f"{indent}{widget.text or widget.label}", ""]
    if widget.type == "group":
        lines = [f"{indent}**{widget.label}**", ""]
        for child in widget.widgets:
            lines.extend(_widget_lines(child, indent + "  "))
        return lines
    req = "required" if widget.required else "optional"
    lines = [f"{indent}- [ ] **{widget.name}** ({req}) — {widget.label}"]
    if widget.help:
        lines.append(f"{indent}  _{widget.help}_")
    if widget.type == "confirm":
        default = widget.default
        yes = "•" if default is True else " "
        no = "•" if default is False else " "
        lines.append(f"{indent}  - ({yes}) `true` — Yes")
        lines.append(f"{indent}  - ({no}) `false` — No")
    elif widget.type in ("choice", "select"):
        default = str(widget.default) if widget.default is not None else ""
        for option in widget.options:
            mark = "•" if option.value == default else " "
            desc = f" — {option.description}" if option.description else ""
            lines.append(
                f"{indent}  - ({mark}) `{option.value}` — {option.label}{desc}"
            )
    elif widget.type == "choice_multi":
        defaults = set(widget.default or []) if isinstance(widget.default, list) else set()
        for option in widget.options:
            mark = "x" if option.value in defaults else " "
            desc = f" — {option.description}" if option.description else ""
            lines.append(
                f"{indent}  - [{mark}] `{option.value}` — {option.label}{desc}"
            )
    elif widget.type == "text":
        extra = f", max {widget.max_length}" if widget.max_length else ""
        lines.append(f"{indent}  - _free text{extra}_")
    elif widget.type == "number":
        parts = []
        if widget.min is not None:
            parts.append(f"min {widget.min}")
        if widget.max is not None:
            parts.append(f"max {widget.max}")
        hint = (", " + ", ".join(parts)) if parts else ""
        lines.append(f"{indent}  - _number{hint}_")
    elif widget.type == "date":
        lines.append(f"{indent}  - _date DD/MM/YYYY_")
    return lines
