<script setup lang="ts">
// Right-side slide-out panel. Used for user/group/customer details where the
// underlying list should remain visible behind a dimmed scrim. Closes on
// Escape or backdrop click.

const props = withDefaults(
  defineProps<{
    open: boolean
    width?: 'sm' | 'md' | 'lg'
    title?: string
    eyebrow?: string
  }>(),
  { width: 'md' },
)

const emit = defineEmits<{ close: [] }>()

const widthPx = computed(() => ({ sm: 400, md: 600, lg: 800 })[props.width || 'md'])

onMounted(() => {
  const onKey = (e: KeyboardEvent) => {
    if (e.key === 'Escape' && props.open) emit('close')
  }
  document.addEventListener('keydown', onKey)
  onBeforeUnmount(() => document.removeEventListener('keydown', onKey))
})
</script>

<template>
  <Teleport to="body">
    <Transition name="scrim">
      <div v-if="open" class="scrim" @click="emit('close')" />
    </Transition>
    <Transition name="panel">
      <aside v-if="open" class="panel" :style="{ width: widthPx + 'px' }">
        <header>
          <div class="lhs">
            <Eyebrow v-if="eyebrow">{{ eyebrow }}</Eyebrow>
            <h3 v-if="title">{{ title }}</h3>
            <slot name="header" />
          </div>
          <button class="close" @click="emit('close')" aria-label="Close">
            <UiIcon name="x" :size="18" />
          </button>
        </header>
        <div v-if="$slots.tabs" class="tab-strip">
          <slot name="tabs" />
        </div>
        <div class="body">
          <slot />
        </div>
        <footer v-if="$slots.footer">
          <slot name="footer" />
        </footer>
      </aside>
    </Transition>
  </Teleport>
</template>

<style scoped>
.scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  z-index: 70;
}

.panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  max-width: calc(100vw - 32px);
  background: var(--bg);
  border-left: 1px solid var(--border);
  box-shadow: -24px 0 80px rgba(0, 0, 0, 0.32);
  z-index: 80;
  display: flex;
  flex-direction: column;
}

header {
  padding: 20px 24px 16px 24px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
}

.lhs { min-width: 0; flex: 1; }

h3 {
  margin: 6px 0 0 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 18px;
  letter-spacing: -0.015em;
}

.close {
  background: transparent;
  border: none;
  padding: 6px;
  border-radius: 4px;
  color: var(--text-dim);
  cursor: pointer;
}
.close:hover { background: var(--surface); }

.tab-strip {
  padding: 0 24px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.body {
  flex: 1;
  overflow-y: auto;
  padding: 22px 24px;
}

footer {
  padding: 14px 24px;
  border-top: 1px solid var(--border);
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  background: var(--surface);
  flex-shrink: 0;
}

.scrim-enter-active, .scrim-leave-active { transition: opacity 0.18s; }
.scrim-enter-from, .scrim-leave-to { opacity: 0; }
.panel-enter-active, .panel-leave-active { transition: transform 0.24s cubic-bezier(0.32, 0.72, 0, 1); }
.panel-enter-from, .panel-leave-to { transform: translateX(100%); }
</style>
