# File: pyos/printers/Accordion.py

from ..Attrs import BOLD, DIM, REVERSE

class Accordion:
    @staticmethod
    def layout(collapsed=False, max_height=None, flex=1, disabled=False):
        """
        Collapsed/disabled accordions are 1 line tall (title only).
        Expanded accordions are flex containers so their child can get space.
        """
        if collapsed or disabled:
            return {"height": 1}
        cfg = {"flex": flex, "min_height": 1}
        if max_height is not None:
            cfg["max_height"] = max_height
        return cfg

    @staticmethod
    def display_state(title, child, *, collapsed=False, disabled=False, max_height=None, flex=1, empty_text="(empty)"):
        """
        title: str
        child: display_state dict of the inner component (e.g., a ScrollList / ContextMenuList)
        collapsed: start collapsed?
        disabled: render as disabled and never expand; height=1
        """
        return {
            "title": str(title or ""),
            "child": child,
            "collapsed": bool(collapsed),
            "disabled": bool(disabled),
            "empty_text": str(empty_text or "(empty)"),
            "focused": False,
            "layout": Accordion.layout(collapsed=collapsed, max_height=max_height, flex=flex, disabled=disabled),
            "line_generator": make_accordion,
        }

    @staticmethod
    def set_state(ctx: dict, *, collapsed=None, disabled=None, max_height=None, flex=1):
        """
        Utility to keep layout in sync when toggling collapsed/disabled at runtime.
        """
        if collapsed is not None:
            ctx["collapsed"] = bool(collapsed)
        if disabled is not None:
            ctx["disabled"] = bool(disabled)
        ctx["layout"] = Accordion.layout(
            collapsed=ctx.get("collapsed", False),
            max_height=max_height,
            flex=flex,
            disabled=ctx.get("disabled", False),
        )

def make_accordion(context, remaining_height):
    def print_title(screen, y):
        _, num_cols = screen.getmaxyx()
        title = str(context.get("title", ""))
        collapsed = bool(context.get("collapsed", False))
        disabled = bool(context.get("disabled", False))
        focused = bool(context.get("focused", False))

        if disabled:
            tip = "[empty]"
            attr = DIM
        else:
            tip = "[→ expand]" if collapsed else "[← collapse]"
            attr = REVERSE if focused else BOLD

        text = f"{title}  {tip}"
        screen.addstr(y, 0, text[:num_cols], attr)

    lines = [print_title]

    # if expanded AND not disabled, print child
    if not context.get("collapsed", False) and not context.get("disabled", False) and remaining_height > 1:
        child = context.get("child")
        if child and callable(child.get("line_generator", None)):
            child_lines = child["line_generator"](child, max(0, remaining_height - 1))
            lines += child_lines

    return lines
