// MegaMenu -- a trigger and a wide panel of grouped links.
//
//   <MegaMenu label="Products" columns='[{"heading":"Platform",
//     "items":[{"label":"Runtime","href":"/runtime"}]}]' />
//
// Deliberately one level deep. A mega menu exists to show breadth flat, so
// everything is one click away; nesting inside the panel buries content behind
// hover-within-hover and is close to unusable by keyboard and touch. Use Nav
// when you actually want cascading submenus.
//
// The panel carries data-wrn-anchored so the runtime clamp keeps it inside the
// viewport instead of hanging off the edge of a wide layout.
//
// NOTE: the style block uses /* */ comments only -- // is not a CSS comment
// and silently swallows the rule that follows it.
component MegaMenu {
  outputs {
    open(payload: { sourceEvent: Event })
    close(payload: { reason: string })
    select(payload: { item: object; value: string })
  }

  props {
    color: string = "primary"
    size: string = "default"
    label: string = "Menu"
    icon: string = ""
    columns: unknown[] = []
    footer: string = ""
    defaultOpen: boolean = false
    class: string = ""
  }

  state visible = defaultOpen

  functions {
    shared function columnList() {
      return Array.isArray(columns) ? columns : []
    }

    shared function itemsOf(column) {
      return column && Array.isArray(column.items) ? column.items : []
    }

    client function showPanel(sourceEvent) {
      visible = true
      output.open({ sourceEvent: sourceEvent })
    }

    client function hidePanel(reason) {
      visible = false
      output.close({ reason: reason })
    }

    client function togglePanel(sourceEvent) {
      if (visible) {
        hidePanel("toggle")
      } else {
        showPanel(sourceEvent)
      }
    }

    client function handleKeydown(sourceEvent) {
      if (sourceEvent.key === "Escape" && visible) {
        sourceEvent.preventDefault()
        hidePanel("escape")
      }
    }

    client function choose(item) {
      if (item.disabled) {
        return
      }
      output.select({ item: item, value: item.value || item.label || "" })
      hidePanel("select")
    }
  }

  view {
    <div
      {...attrs}
      data-ui-component="MegaMenu"
      class='wire-mega {class}'
      data-color='{color}'
      data-size='{size}'
      data-open='{visible}'
      @keydown='handleKeydown(event)'
      @mouseleave='hidePanel("pointer-leave")'
    >
      <button
        type="button"
        class="wire-mega__trigger"
        aria-haspopup="true"
        aria-expanded='{visible}'
        @click='togglePanel(event)'
        @mouseenter='showPanel(event)'
        @focus='showPanel(event)'
      >
        <span class='wire-mega__trigger-icon {icon}' data-show="icon" aria-hidden="true"></span>
        <span class="wire-mega__trigger-label">{label}</span>
        <span class="wire-mega__arrow" aria-hidden="true">&#8250;</span>
      </button>

      <div
        class="wire-mega__panel"
        data-wrn-anchored="true"
        data-show="visible"
        data-wrn-roving="both"
      >
        <div class="wire-mega__columns">
          {#each columnList() as column}
            <section class="wire-mega__column">
              <h3 class="wire-mega__heading" data-show="column.heading">{column.heading}</h3>
              <ul class="wire-mega__list">
                {#each itemsOf(column) as item}
                  <li>
                    <a
                      class="wire-mega__link"
                      href='{item.href || "#"}'
                      data-wrn-roving-item="true"
                      aria-disabled='{item.disabled ? "true" : "false"}'
                      @click='choose(item)'
                    >
                      <span
                        class='wire-mega__link-icon {item.icon}'
                        data-show="item.icon"
                        aria-hidden="true"
                      ></span>
                      <span class="wire-mega__link-body">
                        <span class="wire-mega__link-label">{item.label}</span>
                        <span class="wire-mega__link-description" data-show="item.description">
                          {item.description}
                        </span>
                      </span>
                    </a>
                  </li>
                {/each}
              </ul>
            </section>
          {/each}
        </div>

        <p class="wire-mega__footer" data-show="footer">{footer}</p>
        <slot />
      </div>
    </div>
  }

  style {
    .wire-mega {
      --mega-accent: var(--wire-color-primary);
      position: relative;
      display: inline-block;
      max-width: 100%;
    }

    .wire-mega[data-color="secondary"] {
      --mega-accent: var(--wire-color-secondary);
    }

    .wire-mega[data-color="success"] {
      --mega-accent: var(--wire-color-success);
    }

    .wire-mega[data-color="danger"] {
      --mega-accent: var(--wire-color-danger);
    }

    .wire-mega[data-color="info"] {
      --mega-accent: var(--wire-color-info);
    }

    .wire-mega[data-size="sm"] {
      font-size: 0.82rem;
    }

    .wire-mega[data-size="lg"] {
      font-size: 1rem;
    }

    .wire-mega__trigger {
      appearance: none;
      display: inline-flex;
      align-items: center;
      gap: 0.4rem;
      padding: 0.45rem 0.7rem;
      border: 1px solid transparent;
      border-radius: var(--wire-radius-sm);
      background: transparent;
      color: var(--wire-color-text-muted);
      font: inherit;
      font-size: 0.9rem;
      font-weight: 600;
      cursor: pointer;
    }

    .wire-mega__trigger:hover,
    .wire-mega[data-open="true"] .wire-mega__trigger {
      background: var(--wire-color-surface-soft);
      color: var(--wire-color-text);
    }

    .wire-mega__trigger:focus-visible {
      outline: 2px solid var(--mega-accent);
      outline-offset: 2px;
    }

    .wire-mega__arrow {
      display: inline-block;
      transition: transform 160ms ease;
    }

    .wire-mega[data-open="true"] .wire-mega__arrow {
      transform: rotate(90deg);
    }

    /*
     * The panel is offset below the trigger for looks, which used to close the
     * menu on the way to it: that offset is dead space belonging to neither
     * element, so crossing it fired mouseleave on the root. The bridge below
     * covers the gap with a descendant, so the pointer never actually leaves.
     */
    .wire-mega__panel::before {
      content: "";
      position: absolute;
      left: 0;
      right: 0;
      bottom: 100%;
      height: 0.6rem;
    }

    .wire-mega__panel {
      position: absolute;
      z-index: 40;
      top: calc(100% + 0.4rem);
      left: 0;
      width: max-content;
      max-width: min(60rem, calc(100vw - 2rem));
      padding: 1rem;
      border: 1px solid var(--wire-color-border);
      border-radius: var(--wire-radius-lg);
      background: var(--wire-color-surface);
      box-shadow: var(--wire-shadow-1);
    }

    .wire-mega__columns {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
      gap: 1.25rem;
    }

    .wire-mega__column {
      min-width: 0;
    }

    .wire-mega__heading {
      margin: 0 0 0.5rem;
      color: var(--wire-color-text-muted);
      font-size: 0.72rem;
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
    }

    .wire-mega__list {
      display: grid;
      gap: 0.15rem;
      margin: 0;
      padding: 0;
      list-style: none;
    }

    .wire-mega__link {
      display: flex;
      align-items: flex-start;
      gap: 0.5rem;
      padding: 0.45rem 0.5rem;
      border-radius: var(--wire-radius-sm);
      color: var(--wire-color-text);
      text-decoration: none;
    }

    .wire-mega__link:hover {
      background: var(--wire-color-surface-soft);
    }

    .wire-mega__link:focus-visible {
      outline: 2px solid var(--mega-accent);
      outline-offset: 2px;
    }

    .wire-mega__link[aria-disabled="true"] {
      opacity: 0.5;
      pointer-events: none;
    }

    .wire-mega__link-body {
      display: flex;
      flex-direction: column;
      min-width: 0;
    }

    .wire-mega__link-label {
      font-size: 0.88rem;
      font-weight: 600;
    }

    .wire-mega__link-description {
      color: var(--wire-color-text-muted);
      font-size: 0.78rem;
      line-height: 1.5;
    }

    .wire-mega__footer {
      margin: 1rem 0 0;
      padding-top: 0.75rem;
      border-top: 1px solid var(--wire-color-border);
      color: var(--wire-color-text-muted);
      font-size: 0.8rem;
    }

    /*
     * On a phone the panel stops floating and becomes part of the flow. A
     * pointer-opened overlay pinned to a trigger is unreachable on touch, and
     * a 60rem grid has nowhere to go on a 360px screen.
     */
    @media (max-width: 767px) {
      .wire-mega {
        display: block;
      }

      .wire-mega__panel {
        position: static;
        width: auto;
        max-width: 100%;
        box-shadow: none;
      }

      .wire-mega__columns {
        grid-template-columns: 1fr;
      }
    }
  }
}
