<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue';
import { fetchGetOvertimeApplicationStatusDict } from '@/service/api';
import TableSearchFields, { type SearchField } from '@/components/custom/table-search-fields.vue';

defineOptions({ name: 'OvertimeApplicationSearch' });

interface Option {
  label: string;
  value: string | number;
}

interface Props {
  teamMode?: boolean;
  subordinateOptions?: Option[];
}

const props = withDefaults(defineProps<Props>(), {
  teamMode: false,
  subordinateOptions: () => []
});

const emit = defineEmits<{
  reset: [];
  search: [];
}>();

const model = defineModel<Api.OvertimeApplication.OvertimeApplicationSearchParams>('model', {
  required: true
});

const searchModel = reactive<Record<string, any>>({
  applicantIds: undefined,
  overtimeDate: undefined,
  statusCode: undefined,
  approverName: ''
});

const statusOptions = ref<Array<{ label: string; value: string }>>([]);

let syncingFromSource = false;

watch(
  () => [model.value.applicantIds, model.value.overtimeDate, model.value.statusCode, model.value.approverName] as const,
  ([applicantIds, overtimeDate, statusCode, approverName]) => {
    syncingFromSource = true;
    searchModel.applicantIds = applicantIds;
    searchModel.overtimeDate = overtimeDate;
    searchModel.statusCode = statusCode;
    searchModel.approverName = approverName ?? '';
    syncingFromSource = false;
  },
  { immediate: true, flush: 'sync' }
);

watch(
  () => [searchModel.applicantIds, searchModel.overtimeDate, searchModel.statusCode, searchModel.approverName] as const,
  ([applicantIds, overtimeDate, statusCode, approverName]) => {
    if (syncingFromSource) {
      return;
    }

    model.value.applicantIds = applicantIds;
    model.value.applicantName = undefined;
    model.value.overtimeDate = overtimeDate;
    model.value.statusCode = statusCode;
    model.value.approverName = approverName?.trim() || undefined;
  },
  { flush: 'sync' }
);

async function loadStatusOptions() {
  const { error, data } = await fetchGetOvertimeApplicationStatusDict();

  if (error || !data) {
    statusOptions.value = [];
    return;
  }

  statusOptions.value = data.map(item => ({
    label: item.statusName,
    value: item.statusCode
  }));
}

onMounted(async () => {
  await loadStatusOptions();
});

const fields = computed<SearchField[]>(() => {
  const baseFields: SearchField[] = [
    ...(props.teamMode
      ? [
          {
            key: 'applicantIds',
            label: '申请人',
            type: 'select' as const,
            options: props.subordinateOptions,
            placeholder: '请选择申请人',
            filterable: true,
            transformValue: (value: string | number | null | undefined) => (value ? [value] : undefined),
            resolveValue: (value: unknown) => (Array.isArray(value) ? value[0] : value)
          }
        ]
      : []),
    {
      key: 'overtimeDate',
      label: '学习日期',
      type: 'dateRange',
      placeholder: '请选择学习日期'
    },
    {
      key: 'statusCode',
      label: '状态',
      type: 'select',
      options: statusOptions.value,
      placeholder: '请选择状态'
    }
  ];

  if (props.teamMode) {
    baseFields.push({
      key: 'approverName',
      label: '审批人',
      type: 'input',
      placeholder: '请输入审批人'
    });
  }

  return baseFields;
});

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

function handleSearch() {
  emit('search');
}
</script>

<template>
  <TableSearchFields v-model="searchModel" :fields="fields" :columns="4" @reset="handleReset" @search="handleSearch" />
</template>
