<script setup lang="ts">
import { computed, ref, useSlots } from 'vue';
import type { ComponentPublicInstance } from 'vue';
import type { FormInstance } from 'element-plus';
import { $t } from '@/locales';

defineOptions({ name: 'TableSearchPanel' });

interface Props {
  model: object;
  rules?: Record<string, App.Global.FormRule | App.Global.FormRule[]>;
  formRef?: ((instance: FormInstance | null) => void) | null;
  labelWidth?: string | number;
  labelPosition?: 'left' | 'right' | 'top';
  gutter?: number;
  actionColLg?: number;
  actionColMd?: number;
  actionColSm?: number;
  disabled?: boolean;
  defaultExpanded?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  rules: undefined,
  formRef: null,
  labelWidth: 80,
  labelPosition: 'right',
  gutter: 24,
  actionColLg: 6,
  actionColMd: 24,
  actionColSm: 24,
  disabled: false,
  defaultExpanded: false
});

interface Emits {
  (e: 'reset'): void;
  (e: 'search'): void;
}

const emit = defineEmits<Emits>();

const slots = useSlots();
const expanded = ref(props.defaultExpanded);

const hasExtra = computed(() => Boolean(slots.extra));

function handleReset() {
  emit('reset');
}

function handleSearch() {
  emit('search');
}

function toggleExpanded() {
  if (!hasExtra.value) {
    return;
  }

  expanded.value = !expanded.value;
}

function handleFormRef(instance: Element | ComponentPublicInstance | null) {
  props.formRef?.(instance as FormInstance | null);
}
</script>

<template>
  <ElCard class="card-wrapper">
    <ElForm
      :ref="handleFormRef"
      :model="props.model"
      :rules="props.rules"
      :label-position="props.labelPosition"
      :label-width="props.labelWidth"
      @submit.prevent
      @keyup.enter="handleSearch"
    >
      <ElRow :gutter="props.gutter">
        <slot />

        <ElCol
          v-if="!hasExtra"
          class="table-search-panel__action-col"
          :lg="props.actionColLg"
          :md="props.actionColMd"
          :sm="props.actionColSm"
        >
          <ElSpace class="w-full justify-end" alignment="end">
            <ElButton :disabled="props.disabled" @click="handleReset">
              <template #icon>
                <icon-ic-round-refresh class="text-icon" />
              </template>
              {{ $t('common.reset') }}
            </ElButton>
            <ElButton type="primary" plain :disabled="props.disabled" @click="handleSearch">
              <template #icon>
                <icon-ic-round-search class="text-icon" />
              </template>
              {{ $t('common.search') }}
            </ElButton>
          </ElSpace>
        </ElCol>
      </ElRow>

      <ElRow v-if="hasExtra && expanded" :gutter="props.gutter">
        <slot name="extra" />

        <ElCol
          class="table-search-panel__action-col"
          :lg="props.actionColLg"
          :md="props.actionColMd"
          :sm="props.actionColSm"
        >
          <ElSpace class="w-full justify-end" alignment="end">
            <ElButton circle :disabled="props.disabled" @click="toggleExpanded">
              <icon-mdi-chevron-double-up class="text-16px" />
            </ElButton>
            <ElButton :disabled="props.disabled" @click="handleReset">
              <template #icon>
                <icon-ic-round-refresh class="text-icon" />
              </template>
              {{ $t('common.reset') }}
            </ElButton>
            <ElButton type="primary" plain :disabled="props.disabled" @click="handleSearch">
              <template #icon>
                <icon-ic-round-search class="text-icon" />
              </template>
              {{ $t('common.search') }}
            </ElButton>
          </ElSpace>
        </ElCol>
      </ElRow>

      <div v-if="hasExtra && !expanded" class="flex justify-end">
        <ElSpace>
          <ElButton circle :disabled="props.disabled" @click="toggleExpanded">
            <icon-mdi-chevron-double-down class="text-16px" />
          </ElButton>
          <ElButton :disabled="props.disabled" @click="handleReset">
            <template #icon>
              <icon-ic-round-refresh class="text-icon" />
            </template>
            {{ $t('common.reset') }}
          </ElButton>
          <ElButton type="primary" plain :disabled="props.disabled" @click="handleSearch">
            <template #icon>
              <icon-ic-round-search class="text-icon" />
            </template>
            {{ $t('common.search') }}
          </ElButton>
        </ElSpace>
      </div>
    </ElForm>
  </ElCard>
</template>

<style scoped>
.table-search-panel__action-col {
  margin-left: auto;
}
</style>
