package wang.yaojia.webterm.nav

/**
 * # LayoutPolicy (A26) — the single adaptive-layout decision point.
 *
 * The Android mirror of iOS `LayoutPolicy` (`ios/App/WebTerm/Wiring/LayoutMode.swift`): the **only**
 * place that turns a window size class into a layout decision. Views must never scatter
 * `if windowSizeClass == …` — every branch reads this one pure predicate, so the decision is 100%
 * JVM-unit-testable with plain enum inputs (no Compose, no device — plan §"iPad-equivalent", R13).
 *
 * The thin `WindowSizeClass → WindowWidth` extraction lives in the Compose layer
 * ([wang.yaojia.webterm.screens.AdaptiveHome]); everything HERE is pure Kotlin so it stays in the
 * JVM test path exactly like iOS's `LayoutPolicyTests`.
 */

/**
 * A plain, Compose-free mirror of `androidx.window.core.layout.WindowWidthSizeClass` (the analogue of
 * SwiftUI's `UserInterfaceSizeClass`). Kept as our own enum so [LayoutPolicy.mode] is a pure function
 * unit-tested without pulling the window/Compose types onto the JVM test classpath.
 */
public enum class WindowWidth {
    /** Phone portrait / small split / Slide-Over — the compact, single-pane path. */
    COMPACT,

    /** Large phone landscape / small foldable / medium split — wide enough for sidebar + detail. */
    MEDIUM,

    /** Tablet full-screen / large foldable / desktop-class window — sidebar + detail. */
    EXPANDED,
}

/**
 * The adaptive root's layout mode (mirrors iOS `LayoutMode.stack` / `.split`).
 *
 * - [STACK] — the compact path: single-pane navigation (list → push terminal), byte-for-byte the
 *   existing phone flow.
 * - [LIST_DETAIL] — the expanded/medium path: session list (list pane) + terminal (detail pane)
 *   side by side, driven by Material 3 Adaptive `ListDetailPaneScaffold`.
 */
public enum class LayoutMode {
    /** Compact: single pane, stack navigation (iPhone / Slide-Over analogue). */
    STACK,

    /** Medium / expanded: sidebar + detail split (iPad analogue). */
    LIST_DETAIL,
}

/**
 * The one size-class decision. [WindowWidth.COMPACT] → [LayoutMode.STACK]; [WindowWidth.MEDIUM] and
 * [WindowWidth.EXPANDED] → [LayoutMode.LIST_DETAIL]. Pure; mirrors iOS
 * `LayoutPolicy.mode(horizontalSizeClass:)`.
 */
public object LayoutPolicy {
    public fun mode(width: WindowWidth): LayoutMode = when (width) {
        WindowWidth.COMPACT -> LayoutMode.STACK
        WindowWidth.MEDIUM, WindowWidth.EXPANDED -> LayoutMode.LIST_DETAIL
    }
}

/**
 * The pointer-context-menu gating predicate (plan §5 A26, §"iPad-equivalent", R13, §8).
 *
 * A right-click / trackpad-secondary context menu is a large-screen affordance only — it is enabled
 * **iff** the layout is [LayoutMode.LIST_DETAIL] AND the device is a genuine tablet
 * (`smallestScreenWidthDp >= 600`, the Material tablet breakpoint). A large phone in landscape can
 * momentarily report an expanded width but keeps `smallestScreenWidthDp < 600`, so the two-part gate
 * blocks the desktop menu there. Pure so it is JVM-unit-tested with plain inputs.
 */
public object PointerMenuPolicy {
    /** The Material tablet breakpoint (dp). `smallestScreenWidthDp` at/above this = a real large screen. */
    public const val TABLET_MIN_WIDTH_DP: Int = 600

    public fun enabled(mode: LayoutMode, smallestScreenWidthDp: Int): Boolean =
        mode == LayoutMode.LIST_DETAIL && smallestScreenWidthDp >= TABLET_MIN_WIDTH_DP
}
