<template>
  <div class="vm-aside">
    <div class="vm-aside__head">
      <span class="vm-aside__title">{{ title }}</span>
      <div class="vm-aside__actions">
        <button
          v-if="refresh"
          type="button"
          class="vm-aside__icon-btn"
          :title="refreshTitle ?? crudLabel('refresh')"
          :disabled="loading"
          @click="emit('refresh')"
        >
          <i class="ri-refresh-line" :class="{ 'is-spin': loading }" />
        </button>
        <button
          v-if="add"
          type="button"
          class="vm-aside__icon-btn"
          :title="addTitle ?? crudLabel('add')"
          :disabled="addDisabled || loading"
          @click="emit('add')"
        >
          <i class="ri-add-line" />
        </button>
        <slot name="actions" />
      </div>
    </div>
    <div v-if="search" class="vm-aside__search">
      <i class="ri-search-line" />
      <input v-model.trim="keyword" type="search" :placeholder="placeholder ?? crudLabel('searchKey')" />
    </div>
    <div class="vm-aside__body vm-scroll">
      <slot />
      <p v-if="empty" class="vm-aside__empty">{{ empty }}</p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { crudLabel } from '../crud/style'

defineOptions({ name: 'vm-aside' })

withDefaults(
  defineProps<{
    title?: string
    /** 显示搜索框 */
    search?: boolean
    placeholder?: string
    /** 非空时在内容区底部显示空态文案 */
    empty?: string
    /** 内置刷新按钮（默认开） */
    refresh?: boolean
    /** 内置新增按钮（默认开） */
    add?: boolean
    /** 刷新中：禁用并旋转图标 */
    loading?: boolean
    addDisabled?: boolean
    refreshTitle?: string
    addTitle?: string
  }>(),
  {
    title: '',
    search: false,
    placeholder: undefined,
    empty: '',
    refresh: true,
    add: true,
    loading: false,
    addDisabled: false,
    refreshTitle: undefined,
    addTitle: undefined,
  },
)

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

const keyword = defineModel<string>('keyword', { default: '' })
</script>

<style lang="scss" scoped>
.vm-aside {
  display: flex;
  height: 100%;
  min-height: 0;
  flex-direction: column;
  border-right: 1px solid color-mix(in srgb, var(--foreground) 8%, transparent);
  background: var(--card);
}

.vm-aside__head {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 14px 14px 8px;
}

.vm-aside__title {
  font-size: 14px;
  font-weight: 700;
  color: var(--foreground);
}

.vm-aside__actions {
  display: inline-flex;
  gap: 4px;
}

.vm-aside__search {
  display: flex;
  flex-shrink: 0;
  height: 34px;
  align-items: center;
  gap: 8px;
  margin: 0 12px 10px;
  padding: 0 10px;
  border: 1px solid color-mix(in srgb, var(--foreground) 12%, transparent);
  border-radius: 10px;
  color: var(--muted-foreground);

  input {
    width: 100%;
    border: 0;
    background: transparent;
    color: var(--foreground);
    font-size: 13px;
    outline: none;
  }
}

.vm-aside__body {
  flex: 1;
  min-height: 0;
  padding: 0 8px 12px;
  overflow: auto;
}

.vm-aside__empty {
  margin: 16px 0;
  text-align: center;
  font-size: 12px;
  color: var(--muted-foreground);
}

.vm-aside__icon-btn {
  display: inline-flex;
  width: 28px;
  height: 28px;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;

  &:hover:not(:disabled) {
    background: var(--muted);
    color: var(--foreground);
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  &.is-sm {
    width: 22px;
    height: 22px;
    border-radius: 6px;
  }

  &.is-danger:hover:not(:disabled) {
    background: var(--danger-soft);
    color: var(--danger);
  }

  i.is-spin {
    animation: vm-aside-spin 0.8s linear infinite;
  }
}

/* 默认槽内业务按钮复用同一套样式 */
:slotted(.vm-aside__icon-btn) {
  display: inline-flex;
  width: 28px;
  height: 28px;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;

  &:hover:not(:disabled) {
    background: var(--muted);
    color: var(--foreground);
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  &.is-sm {
    width: 22px;
    height: 22px;
    border-radius: 6px;
  }

  &.is-danger:hover:not(:disabled) {
    background: var(--danger-soft);
    color: var(--danger);
  }
}

@keyframes vm-aside-spin {
  to {
    transform: rotate(360deg);
  }
}
</style>
