<template>
  <v-row align="center" class="pa-4" no-gutters v-bind="$attrs">
    <span v-if="title">{{ title }}</span>
    <v-spacer></v-spacer>

    <v-btn
      v-if="showCreate"
      class="mr-4"
      color="primary"
      prepend-icon="mdi-plus"
      @click="$emit('create')"
    >
      {{ createBtnText }}
    </v-btn>

    <v-tooltip :disabled="!searchToggleTooltipText" location="top" :text="searchToggleTooltipText">
      <template #activator="{ props }">
        <v-btn
          v-if="showSearchToggle"
          v-bind="props"
          density="comfortable"
          icon
          variant="text"
          @click="$emit('toggle-search')"
        >
          <v-icon :color="searchVisible ? 'primary-variant' : undefined"> mdi-magnify </v-icon>
        </v-btn>
      </template>
    </v-tooltip>

    <v-tooltip :disabled="!refreshTooltipText" location="top" :text="refreshTooltipText">
      <template #activator="{ props }">
        <v-btn v-bind="props" density="comfortable" icon variant="text" @click="$emit('refresh')">
          <v-icon>mdi-refresh</v-icon>
        </v-btn>
      </template>
    </v-tooltip>

    <v-menu v-if="settingsItems && settingsItems.length > 0">
      <template #activator="{ props: menuProps }">
        <v-tooltip :disabled="!settingsTooltipText" location="top" :text="settingsTooltipText">
          <template #activator="{ props: tooltipProps }">
            <v-btn
              v-bind="{ ...menuProps, ...tooltipProps }"
              density="comfortable"
              icon
              variant="text"
              @click="$emit('settings')"
            >
              <v-icon>mdi-cog</v-icon>
            </v-btn>
          </template>
        </v-tooltip>
      </template>

      <v-list density="compact">
        <v-list-item class="py-0">
          <v-checkbox
            color="primary"
            density="compact"
            :disabled="selectAllChecked"
            hide-details
            :indeterminate="selectAllIndeterminate"
            label="全選"
            :model-value="selectAllChecked"
            @update:model-value="toggleSelectAll"
          />
        </v-list-item>

        <v-list-item v-for="item in settingsItems" :key="item.key" class="py-0">
          <v-checkbox
            color="primary"
            density="compact"
            hide-details
            :label="item.label"
            :model-value="settingsSelectedKeys"
            :value="item.key"
            @update:model-value="updateSettingsSelectedKeys"
          />
        </v-list-item>
      </v-list>
    </v-menu>
  </v-row>
</template>

<script setup lang="ts">
import { computed, toRefs } from 'vue'

interface SettingsItem {
  key: string
  label: string
}

interface Props {
  title?: string
  createBtnText?: string
  showCreate?: boolean
  showSearchToggle?: boolean
  searchVisible?: boolean
  searchToggleTooltipText?: string
  refreshTooltipText?: string
  settingsTooltipText?: string
  settingsItems?: SettingsItem[]
  settingsSelectedKeys?: string[]
}

const props = withDefaults(defineProps<Props>(), {
  createBtnText: '新增',
  showCreate: true,
  showSearchToggle: false,
  searchVisible: true,
  searchToggleTooltipText: '顯示/隱藏搜尋條件',
  refreshTooltipText: '更新',
  settingsTooltipText: '欄位設定',
  settingsItems: () => [],
  settingsSelectedKeys: () => [],
})

const { settingsItems, settingsSelectedKeys } = toRefs(props)

const emit = defineEmits([
  'create',
  'refresh',
  'settings',
  'toggle-search',
  'update:settingsSelectedKeys',
])

const allSettingsKeys = computed(() => settingsItems.value.map((i) => i.key))

const selectAllChecked = computed(() => {
  if (allSettingsKeys.value.length === 0) {
    return false
  }
  return allSettingsKeys.value.every((k) => settingsSelectedKeys.value.includes(k))
})

const selectAllIndeterminate = computed(() => {
  if (allSettingsKeys.value.length === 0) {
    return false
  }
  const selectedCount = allSettingsKeys.value.filter((k) =>
    settingsSelectedKeys.value.includes(k)
  ).length
  return selectedCount > 0 && selectedCount < allSettingsKeys.value.length
})

function toggleSelectAll (checked: unknown) {
  const current = Array.isArray(settingsSelectedKeys.value) ? settingsSelectedKeys.value : []
  const nonSettingsKeys = current.filter((k) => !allSettingsKeys.value.includes(k))

  emit(
    'update:settingsSelectedKeys',
    checked ? [...nonSettingsKeys, ...allSettingsKeys.value] : nonSettingsKeys
  )
}

function updateSettingsSelectedKeys (value: unknown) {
  emit('update:settingsSelectedKeys', Array.isArray(value) ? value : [])
}
</script>
