<template>
  <article class="enterprise-list-page" :class="[variant, { panel }]">
    <slot name="before"></slot>

    <nav v-if="hasTabs" class="status-tabs" :aria-label="tabsLabel">
      <slot
        name="tabs"
        :tabs="normalizedTabs"
        :active-tab="activeTab"
        :select-tab="selectTab"
      >
        <button
          v-for="tab in normalizedTabs"
          :key="tab.value"
          type="button"
          :class="{ active: activeTab === tab.value }"
          @click="selectTab(tab.value)"
        >
          <span>{{ tab.label }}</span>
          <small v-if="tab.count !== null">{{ tab.count }}</small>
        </button>
      </slot>
    </nav>

    <div v-if="hasToolbar" class="list-toolbar">
      <slot name="toolbar">
        <div v-if="hasFilterRegion" class="filter-set">
          <slot name="filters">
            <label v-if="searchable" class="list-search">
              <i class="mdi mdi-magnify"></i>
              <input
                :value="keyword"
                type="search"
                :placeholder="searchPlaceholder"
                @input="emit('update:keyword', $event.target.value)"
              />
            </label>
          </slot>
        </div>

        <div v-if="$slots.actions" class="toolbar-actions">
          <slot name="actions"></slot>
        </div>
      </slot>
    </div>

    <p v-if="hasHint" class="hint">
      <slot name="hint">
        <i v-if="hintIcon" :class="hintIcon"></i>
        <span>{{ hint }}</span>
      </slot>
    </p>

    <slot name="meta"></slot>

    <div class="table-wrap" :class="{ 'is-empty': empty, 'has-error': Boolean(error) }">
      <div v-if="loading" class="table-state">
        <TableLoadingState
          :title="loadingTitle"
          :message="loadingMessage"
          :icon="loadingIcon"
          floating
        />
      </div>

      <div v-else-if="error" class="table-state error">
        <slot name="error" :error="error">
          <i class="mdi mdi-alert-circle-outline"></i>
          <strong>{{ errorTitle }}</strong>
          <p>{{ error }}</p>
          <button v-if="retryLabel" class="state-action retry-btn" type="button" @click="emit('retry')">
            {{ retryLabel }}
          </button>
        </slot>
      </div>

      <slot v-else-if="empty" name="empty">
        <TableEmptyState
          v-if="emptyState"
          :eyebrow="emptyState.eyebrow"
          :title="emptyState.title"
          :description="emptyState.desc || emptyState.description"
          :icon="emptyState.icon"
          :action-label="emptyState.actionLabel"
          :action-icon="emptyState.actionIcon"
          :tone="emptyState.tone"
          :art-label="emptyState.artLabel"
          :tips="emptyState.tips || []"
          @action="emit('empty-action')"
        />
      </slot>

      <slot v-else name="table"></slot>
    </div>

    <slot name="footer">
      <EnterprisePagination
        v-if="showPagination"
        :current-page="currentPage"
        :page-size="pageSize"
        :page-size-options="pageSizeOptions"
        :show-page-size="showPageSize"
        :summary="summary"
        :total="total"
        :total-pages="totalPages"
        @update:current-page="emit('update:currentPage', $event)"
        @update:page-size="emit('update:pageSize', $event)"
        @page-size-change="emit('page-size-change', $event)"
      />
    </slot>
  </article>
</template>

<script setup>
import { computed, useSlots } from 'vue'

import EnterprisePagination from './EnterprisePagination.vue'
import TableEmptyState from './TableEmptyState.vue'
import TableLoadingState from './TableLoadingState.vue'

const props = defineProps({
  activeTab: { type: [String, Number], default: '' },
  currentPage: { type: Number, default: 1 },
  empty: { type: Boolean, default: false },
  emptyState: { type: Object, default: null },
  error: { type: String, default: '' },
  errorTitle: { type: String, default: '列表加载失败' },
  hint: { type: String, default: '' },
  hintIcon: { type: String, default: 'mdi mdi-information-outline' },
  keyword: { type: String, default: '' },
  loading: { type: Boolean, default: false },
  loadingIcon: { type: String, default: 'mdi mdi-file-document-outline' },
  loadingMessage: { type: String, default: '' },
  loadingTitle: { type: String, default: '数据同步中' },
  pageSize: { type: Number, default: 10 },
  pageSizeOptions: {
    type: Array,
    default: () => []
  },
  panel: { type: Boolean, default: true },
  retryLabel: { type: String, default: '重新加载' },
  searchable: { type: Boolean, default: false },
  searchPlaceholder: { type: String, default: '搜索' },
  showPageSize: { type: Boolean, default: true },
  showPagination: { type: Boolean, default: false },
  summary: { type: String, default: '' },
  tabs: {
    type: Array,
    default: () => []
  },
  tabsLabel: { type: String, default: '列表视图' },
  total: { type: Number, default: 0 },
  totalPages: { type: Number, default: 1 },
  variant: { type: String, default: '' }
})

const emit = defineEmits([
  'empty-action',
  'page-size-change',
  'retry',
  'update:activeTab',
  'update:currentPage',
  'update:keyword',
  'update:pageSize'
])

const slots = useSlots()

const normalizedTabs = computed(() =>
  props.tabs.map((tab) => {
    if (tab && typeof tab === 'object') {
      const value = tab.value ?? tab.label ?? ''
      return {
        value,
        label: String(tab.label ?? value),
        count: tab.count ?? null
      }
    }

    return {
      value: tab,
      label: String(tab),
      count: null
    }
  })
)

const hasTabs = computed(() => normalizedTabs.value.length > 0 || Boolean(slots.tabs))
const hasToolbar = computed(() => props.searchable || Boolean(slots.filters || slots.actions || slots.toolbar))
const hasFilterRegion = computed(() => props.searchable || Boolean(slots.filters))
const hasHint = computed(() => Boolean(props.hint || slots.hint))

function selectTab(tab) {
  emit('update:activeTab', tab)
}
</script>
