component Popover {
  outputs {
    toggle(payload: { open: boolean; sourceEvent: Event; reason?: object })
    open(payload: { sourceEvent: Event })
    close(payload: { reason: string; sourceEvent: Event })
    action(payload: { href: string; sourceEvent: Event })
  }

  props {

    open: boolean = false
    defaultOpen: boolean = false
    triggerLabel: string = "Open popover"
    triggerIcon: string = ""
    title: string = ""
    description: string = ""
    icon: string = ""
    placement: string = "bottom-start"
    width: string = "md"
    size: string = "default"
    color: string = "primary"
    variant: string = "raised"
    showArrow: boolean = true
    showClose: boolean = false
    closeLabel: string = "Close popover"
    closeOnOutside: boolean = true
    closeOnEscape: boolean = true
    actionLabel: string = ""
    actionHref: string = ""
    actionIcon: string = ""
    closeOnAction: boolean = true
    disabled: boolean = false
    class: string = ""
  }

  state visible = defaultOpen

  functions {
    shared function isOpen() {
      return open || visible
    }

    client function showPopover(sourceEvent) {
      if (disabled) {
        return
      }
      visible = true
      output.open({ sourceEvent: sourceEvent })
      output.toggle({ open: true, sourceEvent: sourceEvent })
    }

    client function hidePopover(reason, sourceEvent) {
      visible = false
      output.close({ reason: reason, sourceEvent: sourceEvent })
      output.toggle({ open: false, reason: reason, sourceEvent: sourceEvent })
    }

    client function togglePopover(sourceEvent) {
      if (isOpen()) {
        hidePopover("toggle", sourceEvent)
      } else {
        showPopover(sourceEvent)
      }
    }

    client function activateAction(sourceEvent) {
      output.action({
        href: actionHref,
        sourceEvent: sourceEvent
      })
      if (closeOnAction) {
        hidePopover("action", sourceEvent)
      }
    }

    client function handleKeydown(sourceEvent) {
      if (closeOnEscape && sourceEvent.key === "Escape") {
        sourceEvent.preventDefault()
        hidePopover("escape", sourceEvent)
      }
    }
  }

  view {
    <div
      {...attrs}
      data-ui-component="Popover"
      data-open='{open || visible ? "true" : "false"}'
      data-placement='{placement}'
      data-width='{width}'
      data-size='{size}'
      data-color='{color}'
      data-variant='{variant}'
      class='wire-popover {class}'
      @keydown='handleKeydown(event)'
    >
      <button
        type="button"
        class="wire-popover__trigger"
        disabled='{disabled}'
        aria-haspopup="dialog"
        aria-expanded='{open || visible ? "true" : "false"}'
        @click='togglePopover(event)'
      >
        <slot name="trigger"></slot>
        {#if triggerIcon}
          <span class='{triggerIcon}' aria-hidden="true"></span>
        {/if}
        {#if triggerLabel}
          <span>{triggerLabel}</span>
        {/if}
      </button>

      {#if closeOnOutside}
        <button
          type="button"
          class="wire-popover__dismiss-layer"
          data-show='{open || visible}'
          aria-label='{closeLabel}'
          @click='hidePopover("outside", event)'
        ></button>
      {/if}

      <section
        class="wire-popover__panel"
        data-wrn-anchored="true"
        data-show='{open || visible}'
        role="dialog"
        aria-label='{title || triggerLabel}'
      >
        {#if showArrow}
          <span class="wire-popover__arrow" data-wrn-anchor-arrow="true" aria-hidden="true"></span>
        {/if}

        {#if title || description || icon || showClose}
          <header class="wire-popover__header">
            <div class="wire-popover__heading">
              {#if icon}
                <span class='wire-popover__icon {icon}' aria-hidden="true"></span>
              {/if}
              <div class="wire-popover__heading-copy">
                <slot name="header"></slot>
                {#if title}
                  <h3>{title}</h3>
                {/if}
                {#if description}
                  <p>{description}</p>
                {/if}
              </div>
            </div>

            {#if showClose}
              <button
                type="button"
                class="wire-popover__close"
                aria-label='{closeLabel}'
                @click='hidePopover("close-button", event)'
              >
                <span class="icon-[lucide--x]" aria-hidden="true"></span>
              </button>
            {/if}
          </header>
        {/if}

        <div class="wire-popover__body">
          <slot></slot>
        </div>

        {#if actionLabel}
          <footer class="wire-popover__footer">
            {#if actionHref}
              <a
                href='{actionHref}'
                class="wire-popover__action"
                @click='activateAction(event)'
              >
                <span>{actionLabel}</span>
                {#if actionIcon}
                  <span class='{actionIcon}' aria-hidden="true"></span>
                {:else}
                  <span class="icon-[lucide--arrow-right]" aria-hidden="true"></span>
                {/if}
              </a>
            {:else}
              <button
                type="button"
                class="wire-popover__action"
                @click='activateAction(event)'
              >
                <span>{actionLabel}</span>
                {#if actionIcon}
                  <span class='{actionIcon}' aria-hidden="true"></span>
                {:else}
                  <span class="icon-[lucide--arrow-right]" aria-hidden="true"></span>
                {/if}
              </button>
            {/if}
          </footer>
        {/if}

        <slot name="footer"></slot>
      </section>
    </div>
  }

  style {
    .wire-popover {
      --popover-accent: var(--wire-color-primary);
      --popover-soft: var(--wire-color-primary-soft);
      --popover-contrast: var(--wire-color-primary-contrast);
      position: relative;
      display: inline-flex;
    }

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

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

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

    .wire-popover[data-color="warning"] {
      --popover-accent: var(--wire-color-warning);
      --popover-soft: var(--wire-color-warning-soft);
      --popover-contrast: var(--wire-color-warning-text);
    }

    .wire-popover[data-color="danger"] {
      --popover-accent: var(--wire-color-danger);
      --popover-soft: var(--wire-color-danger-soft);
      --popover-contrast: var(--wire-color-on-danger);
    }

    .wire-popover__trigger {
      appearance: none;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 0.55rem;
      min-height: 2.55rem;
      padding: 0.65rem 0.9rem;
      color: var(--wire-color-text);
      background: var(--wire-color-surface-raised);
      border: 1px solid var(--wire-color-border);
      border-radius: 0.78rem;
      font: inherit;
      font-size: 0.84rem;
      font-weight: 600;
      cursor: pointer;
      transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
    }

    .wire-popover__trigger:hover,
    .wire-popover__trigger:focus-visible,
    .wire-popover[data-open="true"] .wire-popover__trigger {
      color: var(--popover-accent);
      background: var(--popover-soft);
      border-color: color-mix(in srgb, var(--popover-accent) 38%, var(--wire-color-border));
      outline: none;
    }

    .wire-popover__trigger:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }

    .wire-popover[data-size="sm"] .wire-popover__trigger {
      min-height: 2.2rem;
      padding: 0.5rem 0.72rem;
      font-size: 0.78rem;
    }

    .wire-popover[data-size="lg"] .wire-popover__trigger {
      min-height: 2.9rem;
      padding: 0.78rem 1.05rem;
      font-size: 0.9rem;
    }

    .wire-popover__dismiss-layer {
      position: fixed;
      inset: 0;
      z-index: 1120;
      appearance: none;
      padding: 0;
      background: transparent;
      border: 0;
    }

    .wire-popover__panel {
      position: absolute;
      z-index: 1121;
      top: calc(100% + 0.72rem);
      left: 0;
      width: 18rem;
      max-width: calc(100vw - 1.5rem);
      color: var(--wire-color-text);
      background:
        linear-gradient(145deg, color-mix(in srgb, var(--popover-accent) 5%, transparent), transparent 62%),
        color-mix(in srgb, var(--wire-color-surface-raised) 97%, transparent);
      border: 1px solid color-mix(in srgb, var(--popover-accent) 18%, var(--wire-color-border));
      border-radius: 1rem;
      box-shadow:
        0 1px 0 color-mix(in srgb, white 5%, transparent) inset,
        0 24px 64px color-mix(in srgb, black 22%, transparent);
      backdrop-filter: blur(18px);
    }

    .wire-popover[data-width="sm"] .wire-popover__panel {
      width: 14rem;
    }

    .wire-popover[data-width="lg"] .wire-popover__panel {
      width: 24rem;
    }

    .wire-popover[data-width="xl"] .wire-popover__panel {
      width: 32rem;
    }

    .wire-popover[data-width="trigger"] .wire-popover__panel {
      width: 100%;
      min-width: 100%;
    }

    .wire-popover[data-placement="bottom-end"] .wire-popover__panel {
      right: 0;
      left: auto;
    }

    .wire-popover[data-placement="top-start"] .wire-popover__panel {
      top: auto;
      bottom: calc(100% + 0.72rem);
    }

    .wire-popover[data-placement="top-end"] .wire-popover__panel {
      top: auto;
      right: 0;
      bottom: calc(100% + 0.72rem);
      left: auto;
    }

    .wire-popover[data-placement="left"] .wire-popover__panel {
      top: 50%;
      right: calc(100% + 0.72rem);
      left: auto;
      transform: translateY(-50%);
    }

    .wire-popover[data-placement="right"] .wire-popover__panel {
      top: 50%;
      left: calc(100% + 0.72rem);
      transform: translateY(-50%);
    }

    .wire-popover[data-variant="soft"] .wire-popover__panel {
      background:
        linear-gradient(145deg, var(--popover-soft), transparent 70%),
        var(--wire-color-surface-raised);
      box-shadow: 0 18px 48px color-mix(in srgb, black 16%, transparent);
    }

    .wire-popover[data-variant="outline"] .wire-popover__panel {
      background: var(--wire-color-surface-raised);
      box-shadow: none;
    }

    .wire-popover[data-variant="solid"] .wire-popover__panel {
      color: var(--popover-contrast);
      background: var(--popover-accent);
      border-color: color-mix(in srgb, white 20%, transparent);
    }

    .wire-popover__arrow {
      position: absolute;
      top: -0.35rem;
      left: 1.25rem;
      width: 0.7rem;
      height: 0.7rem;
      background: inherit;
      border-top: 1px solid color-mix(in srgb, var(--popover-accent) 18%, var(--wire-color-border));
      border-left: 1px solid color-mix(in srgb, var(--popover-accent) 18%, var(--wire-color-border));
      transform: rotate(45deg);
    }

    .wire-popover[data-placement="bottom-end"] .wire-popover__arrow {
      right: 1.25rem;
      left: auto;
    }

    .wire-popover[data-placement="top-start"] .wire-popover__arrow,
    .wire-popover[data-placement="top-end"] .wire-popover__arrow {
      top: auto;
      bottom: -0.35rem;
      transform: rotate(225deg);
    }

    .wire-popover[data-placement="left"] .wire-popover__arrow {
      top: 50%;
      right: -0.35rem;
      left: auto;
      transform: translateY(-50%) rotate(135deg);
    }

    .wire-popover[data-placement="right"] .wire-popover__arrow {
      top: 50%;
      left: -0.35rem;
      transform: translateY(-50%) rotate(-45deg);
    }

    .wire-popover__header {
      display: flex;
      align-items: flex-start;
      justify-content: space-between;
      gap: 0.8rem;
      padding: 1rem 1rem 0.8rem;
      border-bottom: 1px solid var(--wire-color-border);
    }

    .wire-popover__heading {
      display: flex;
      align-items: flex-start;
      gap: 0.7rem;
      min-width: 0;
    }

    .wire-popover__icon {
      flex: 0 0 auto;
      width: 1.05rem;
      height: 1.05rem;
      margin-top: 0.15rem;
      color: var(--popover-accent);
    }

    .wire-popover[data-variant="solid"] .wire-popover__icon {
      color: currentColor;
    }

    .wire-popover__heading-copy {
      display: grid;
      gap: 0.2rem;
      min-width: 0;
    }

    .wire-popover__heading-copy h3,
    .wire-popover__heading-copy p {
      margin: 0;
    }

    .wire-popover__heading-copy h3 {
      font-size: 0.9rem;
      font-weight: 650;
    }

    .wire-popover__heading-copy p {
      color: var(--wire-color-text-muted);
      font-size: 0.74rem;
      line-height: 1.5;
    }

    .wire-popover[data-variant="solid"] .wire-popover__heading-copy p {
      color: color-mix(in srgb, currentColor 76%, transparent);
    }

    /*
     * padding is reset explicitly: an app-level `button { padding: ... }` rule
     * outranks the browser default and crushes the icon inside this
     * fixed-size button. Same trap as Modal and Drawer.
     */
    .wire-popover__close {
      padding: 0;
      appearance: none;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      flex: 0 0 auto;
      width: 2rem;
      height: 2rem;
      color: var(--wire-color-text-muted);
      background: var(--wire-color-surface-soft);
      border: 1px solid var(--wire-color-border);
      border-radius: 0.65rem;
      cursor: pointer;
    }

    .wire-popover__body {
      padding: 1rem;
      color: var(--wire-color-text-muted);
      font-size: 0.8rem;
      line-height: 1.6;
    }

    .wire-popover__footer {
      padding: 0 1rem 1rem;
    }

    .wire-popover__action {
      appearance: none;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 0.45rem;
      min-height: 2.35rem;
      padding: 0.58rem 0.8rem;
      color: var(--popover-contrast);
      background: var(--popover-accent);
      border: 0;
      border-radius: 0.7rem;
      font: inherit;
      font-size: 0.78rem;
      font-weight: 650;
      text-decoration: none;
      cursor: pointer;
    }

    @media (max-width: 639px) {
      .wire-popover__panel {
        position: fixed;
        right: 0.75rem;
        bottom: 0.75rem;
        left: 0.75rem;
        top: auto;
        width: auto;
        max-width: none;
        transform: none;
      }

      .wire-popover__arrow {
        display: none;
      }
    }
  }
}
