component Collapse {
  outputs {
    toggle(payload: { index: number; item: string | number | boolean | null | object; open: boolean; openIndexes: number[] })
    open(payload: { index: number; item: string | number | boolean | null | object })
    close(payload: { index: number; item: string | number | boolean | null | object })
  }

  props {
size: string = "default"
    color: string = "primary"
    items: unknown[] = []
    multiple: boolean = false
    mode: string = "panel"
    initialOpenIndexes: unknown[] = []
    ariaLabel: string = "Collapsible content"
    class: string = ""
  }

  state openIndexes = initialOpenIndexes

  functions {
    shared function isOpen(index) {
      return openIndexes.includes(index)
    }

    client function toggleItem(index, item, opening) {
      if (item.disabled) {
        return
      }
      opening = !isOpen(index)
      if (opening) {
        if (multiple) {
          openIndexes = openIndexes.concat(index)
        } else {
          openIndexes = [index]
        }
        output.open({ index: index, item: item })
      } else {
        openIndexes = openIndexes.filter((openIndex) => openIndex !== index)
        output.close({ index: index, item: item })
      }
      output.toggle({
        index: index,
        item: item,
        open: opening,
        openIndexes: openIndexes
      })
    }
  }

  view {
    <section
      {...attrs}
      class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--collapse {class}"
      data-mode="{mode}"
      aria-label="{ariaLabel}"
    >
      {#each items as item, index}
        <article class="wrn-next__collapse-item" data-open="{isOpen(index)}">
          {#if mode === "inline" && item.preview}
            <p class="wrn-next__collapse-preview">{item.preview}</p>
          {/if}

          <button
            class="wrn-next__collapse-trigger"
            type="button"
            aria-expanded="{isOpen(index) ? 'true' : 'false'}"
            aria-controls="{item.id || 'collapse-panel-' + index}"
            disabled="{item.disabled}"
            @click="toggleItem(index, item)"
          >
            <span>{isOpen(index) ? (item.closeLabel || "Read less") : item.label}</span>
            <span class="icon-[lucide--chevron-down] wrn-next__collapse-chevron" aria-hidden="true"></span>
          </button>

          <div
            id="{item.id || 'collapse-panel-' + index}"
            class="wrn-next__collapse-panel"
            data-open="{isOpen(index)}"
            aria-hidden="{isOpen(index) ? 'false' : 'true'}"
            inert="{!isOpen(index)}"
          >
            <div class="wrn-next__collapse-content">
              {#if item.title}<h4>{item.title}</h4>{/if}
              {#if item.content}<p>{item.content}</p>{/if}
              {#if item.links && item.links.length}
                <nav aria-label="Related links">
                  {#each item.links as link}<a href="{link.href || '#'}">{link.label}</a>{/each}
                </nav>
              {/if}
            </div>
          </div>
        </article>
      {/each}
      <slot />
    </section>
  }

  style {
    .wrn-next--collapse.wrn-component--size-sm {
      font-size: 0.875rem;
    }
    .wrn-next--collapse.wrn-component--size-lg {
      font-size: 1.0625rem;
    }

    .wrn-next--collapse {
      --wrn-collapse-color: var(--wrn-component-color, var(--wrn-color-primary));
      display: grid;
      width: 100%;
      min-width: 0;
      gap: 0.75rem;
      color: var(--wrn-color-text);
    }

    .wrn-next__collapse-item {
      display: grid;
      min-width: 0;
      justify-items: start;
      gap: 0;
    }

    .wrn-next__collapse-trigger {
      display: inline-flex;
      min-height: 2.75rem;
      align-items: center;
      justify-content: center;
      gap: 0.55rem;
      padding: 0.7rem 1rem;
      border: 1px solid var(--wrn-collapse-color);
      border-radius: var(--wrn-radius-sm);
      background: var(--wrn-collapse-color);
      color: var(--wrn-color-primary-contrast, #fff);
      font: inherit;
      font-weight: 700;
      cursor: pointer;
    }

    .wrn-next__collapse-trigger:focus-visible {
      outline: 2px solid var(--wrn-collapse-color);
      outline-offset: 3px;
    }

    .wrn-next__collapse-trigger:disabled {
      cursor: not-allowed;
      opacity: 0.5;
    }

    .wrn-next__collapse-chevron {
      transition: transform var(--wrn-motion-fast) var(--wrn-ease-standard);
    }

    .wrn-next__collapse-item[data-open="true"] .wrn-next__collapse-chevron {
      transform: rotate(180deg);
    }

    .wrn-next__collapse-panel {
      width: min(100%, 42rem);
      max-height: 0;
      overflow: hidden;
      margin-top: 0;
      opacity: 0;
      transition:
        max-height 350ms var(--wrn-ease-emphasized),
        margin-top 300ms var(--wrn-ease-emphasized),
        opacity 200ms var(--wrn-ease-standard);
    }

    .wrn-next__collapse-panel[data-open="true"] {
      max-height: 40rem;
      margin-top: 0.75rem;
      opacity: 1;
    }

    .wrn-next__collapse-content {
      display: grid;
      overflow: hidden;
      min-height: 0;
      gap: 0.65rem;
      padding: 1rem;
      border: 1px solid var(--wrn-color-border);
      border-radius: var(--wrn-radius-md);
      background: var(--wrn-color-surface-raised, var(--wrn-color-surface));
    }

    .wrn-next__collapse-content h4,
    .wrn-next__collapse-content p,
    .wrn-next__collapse-preview {
      margin: 0;
    }

    .wrn-next__collapse-content nav {
      display: flex;
      flex-wrap: wrap;
      gap: 0.75rem;
    }

    .wrn-next__collapse-content a {
      color: var(--wrn-collapse-color);
      font-weight: 650;
      text-decoration: none;
    }

    .wrn-next--collapse[data-mode="inline"] .wrn-next__collapse-item {
      gap: 0;
    }

    .wrn-next--collapse[data-mode="inline"] .wrn-next__collapse-preview {
      order: 1;
      margin-bottom: 0.5rem;
    }

    .wrn-next--collapse[data-mode="inline"] .wrn-next__collapse-panel {
      order: 2;
      width: 100%;
    }

    .wrn-next--collapse[data-mode="inline"] .wrn-next__collapse-panel[data-open="true"] {
      margin-top: 0;
    }

    .wrn-next--collapse[data-mode="inline"] .wrn-next__collapse-trigger {
      order: 3;
      margin-top: 0.5rem;
      min-height: auto;
      padding: 0;
      border: 0;
      border-radius: 0;
      background: transparent;
      color: var(--wrn-collapse-color);
    }

    .wrn-next--collapse[data-mode="inline"] .wrn-next__collapse-content {
      padding: 0;
      border: 0;
      background: transparent;
    }

    @media (prefers-reduced-motion: reduce) {
    .wrn-next__collapse-chevron,
      .wrn-next__collapse-panel {
        transition: none;
      }
    }

    /* Shared component foundation. */

        .wrn-component {
          --wrn-component-color: var(--wrn-color-primary);
          --wrn-component-scale: 1;
          margin: 0;
          color: var(--wrn-color-text);
          font-family: var(--wrn-font-sans, inherit);
        }

        .wrn-component--color-primary {
          --wrn-component-color: var(--wrn-color-primary);
        }

        .wrn-component--color-secondary {
          --wrn-component-color: var(--wrn-color-secondary);
        }

        .wrn-component--color-success {
          --wrn-component-color: var(--wrn-color-success);
        }

        .wrn-component--color-warning {
          --wrn-component-color: var(--wrn-color-warning);
        }

        .wrn-component--color-danger {
          --wrn-component-color: var(--wrn-color-danger);
        }

        .wrn-component--color-info {
          --wrn-component-color: var(--wrn-color-info);
        }

        .wrn-component--size-xs {
          --wrn-component-scale: 0.78;
        }

        .wrn-component--size-sm {
          --wrn-component-scale: 0.88;
        }

        .wrn-component--size-default,
        .wrn-component--size-md {
          --wrn-component-scale: 1;
        }

        .wrn-component--size-lg {
          --wrn-component-scale: 1.14;
        }

        .wrn-component--size-xl {
          --wrn-component-scale: 1.28;
        }

        .wrn-component:not(.wrn-btn) {
          font-size: calc(1em * var(--wrn-component-scale));
        }

        .wrn-component :is(a, button, input, select, textarea):focus-visible {
          outline-color: var(--wrn-component-color);
        }

        .wrn-component p {
          margin: 0;
          color: var(--wrn-color-muted);
          line-height: 1.6;
        }
  }
}
