<script setup lang="ts">
import type { CSSProperties } from 'vue';

import { computed, useSlots } from 'vue';

interface Props {
  contentPadding?: number | string;
  dense?: boolean;
  stickyToolbar?: boolean;
  surface?: 'panel' | 'plain' | 'subtle';
}

const props = withDefaults(defineProps<Props>(), {
  contentPadding: 0,
  dense: false,
  stickyToolbar: false,
  surface: 'panel',
});

const slots = useSlots();

const hasToolbar = computed(() => Boolean(slots.filters || slots.actions));

const contentStyle = computed((): CSSProperties => {
  const padding =
    typeof props.contentPadding === 'number'
      ? `${props.contentPadding}px`
      : props.contentPadding;

  return padding ? { '--list-page-shell-content-padding': padding } : {};
});
</script>

<template>
  <section
    class="list-page-shell"
    :class="[
      `is-${surface}`,
      {
        'is-dense': dense,
      },
    ]"
  >
    <div
      v-if="hasToolbar"
      class="list-page-shell__toolbar"
      :class="{
        'is-sticky': stickyToolbar,
      }"
    >
      <div v-if="$slots.filters" class="list-page-shell__filters">
        <slot name="filters"></slot>
      </div>
      <div v-if="$slots.actions" class="list-page-shell__actions">
        <slot name="actions"></slot>
      </div>
    </div>

    <div class="list-page-shell__content" :style="contentStyle">
      <slot></slot>
      <slot name="empty"></slot>
    </div>
  </section>
</template>

<style scoped>
.list-page-shell {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 16px;
  min-height: 0;
}

.list-page-shell.is-dense {
  gap: 12px;
}

.list-page-shell__toolbar {
  position: relative;
  display: flex;
  gap: 16px;
  align-items: flex-start;
  justify-content: space-between;
  padding: 8px 6px 2px;
  background: transparent;
  border: none;
  border-radius: 0;
}

.list-page-shell__toolbar.is-sticky {
  position: sticky;
  top: 12px;
  z-index: 5;
  padding: 10px 10px 6px;
  background: hsl(var(--glass-tint) / 70%);
  border: 1px solid hsl(var(--glass-border) / 44%);
  border-radius: 20px;
  box-shadow: var(--shadow-toolbar);
  backdrop-filter: blur(var(--glass-blur)) saturate(155%);
}

.list-page-shell__filters,
.list-page-shell__actions {
  min-width: 0;
}

.list-page-shell__filters {
  flex: 1;
}

.list-page-shell__content {
  --list-page-shell-content-padding: 0px;

  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  padding: var(--list-page-shell-content-padding);
  overflow: hidden;
  background: linear-gradient(
    180deg,
    hsl(var(--glass-border) / 84%) 0%,
    hsl(var(--surface-panel) / 94%) 28%,
    hsl(var(--surface-panel) / 97%) 100%
  );
  border: 1px solid hsl(var(--glass-border) / 58%);
  border-radius: 24px;
  box-shadow:
    inset 0 1px 0 hsl(var(--glass-border) / 72%),
    0 24px 54px -42px hsl(var(--primary) / 22%),
    0 18px 42px -34px hsl(var(--foreground) / 10%);
  backdrop-filter: var(--persistent-surface-backdrop-filter);
}

.list-page-shell.is-subtle .list-page-shell__content {
  background: linear-gradient(
    180deg,
    hsl(var(--glass-tint) / 84%) 0%,
    hsl(var(--surface-contrast-soft) / 94%) 100%
  );
  box-shadow: none;
}

.list-page-shell.is-plain .list-page-shell__content {
  background: hsl(var(--surface-panel) / 96%);
  border: 1px solid hsl(var(--divider-faint) / 58%);
  border-radius: 20px;
  box-shadow: none;
  backdrop-filter: none;
}

.list-page-shell.is-plain .list-page-shell__content::before {
  display: none;
}

.list-page-shell__content::before {
  position: absolute;
  inset: 0 0 auto;
  height: 220px;
  pointer-events: none;
  content: '';
  background:
    radial-gradient(
      ellipse 84% 72% at 10% 0%,
      hsl(var(--nav-ambient) / 18%) 0%,
      transparent 68%
    ),
    linear-gradient(180deg, hsl(var(--nav-flow-trace) / 8%) 0%, transparent 78%);
}

.list-page-shell__content > * {
  position: relative;
  z-index: 1;
}

.list-page-shell__content :deep(.page-data-container) {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.list-page-shell__content :deep(.el-empty) {
  margin: auto;
}

.list-page-shell__content :deep(.el-table) {
  --el-table-bg-color: transparent;
  --el-table-tr-bg-color: transparent;
  --el-table-header-bg-color: hsl(var(--table-header-bg));
  --el-table-border-color: hsl(var(--table-row-border));
  --el-table-current-row-bg-color: hsl(var(--table-row-hover));
  --el-fill-color-blank: transparent;

  background: transparent;
}

.list-page-shell__content :deep(.el-table--border),
.list-page-shell__content :deep(.el-table__inner-wrapper),
.list-page-shell__content :deep(.el-table__header-wrapper),
.list-page-shell__content :deep(.el-table__body-wrapper) {
  border: none;
}

.list-page-shell__content :deep(.el-table__inner-wrapper::before),
.list-page-shell__content :deep(.el-table--border::before),
.list-page-shell__content :deep(.el-table--border::after) {
  display: none;
}

.list-page-shell__content :deep(.el-table th.el-table__cell) {
  padding: 12px 0;
  font-size: 13px;
  font-weight: 600;
  color: hsl(var(--text-strong));
  background: hsl(var(--table-header-bg) / 86%);
  border-bottom: 1px solid hsl(var(--divider-faint) / 38%);
}

.list-page-shell__content :deep(.el-table th.el-table__cell:first-child) {
  border-top-left-radius: 12px;
}

.list-page-shell__content :deep(.el-table th.el-table__cell:last-child) {
  border-top-right-radius: 12px;
}

.list-page-shell__content :deep(.el-table td.el-table__cell),
.list-page-shell__content :deep(.el-table--border .el-table__cell) {
  padding: 14px 0;
  border-right: none;
  border-bottom: 1px solid hsl(var(--divider-faint) / 46%);
}

.list-page-shell__content :deep(.el-table__row:hover > td.el-table__cell) {
  background: hsl(var(--table-row-hover)) !important;
}

.list-page-shell__content :deep(.el-tag) {
  border-color: transparent;
  box-shadow: none;
}

.list-page-shell__content :deep(.el-pagination) {
  padding: 0 2px;
}

.list-page-shell__content :deep(.el-pagination button),
.list-page-shell__content :deep(.el-pager li) {
  border-radius: 10px;
}

.list-page-shell__toolbar :deep(.custom-header) {
  width: 100%;
}

@media (max-width: 768px) {
  .list-page-shell {
    gap: 12px;
  }

  .list-page-shell__toolbar {
    flex-direction: column;
    align-items: stretch;
    padding: 2px 0 0;
  }

  .list-page-shell__actions {
    width: 100%;
  }
}
</style>
