<script setup lang="ts">
import type { FetchDataCallback, FetchSelectedDataCallback, PageParameters, SelectPageKey } from 'v-selectpage';
import { SelectPageList }                                                                   from 'v-selectpage';


const props = withDefaults(defineProps<{
  load(page: number, size: number, query?: Record<string, any>): Promise<{ data: any[]; total: number }>;
  query?: Record<string, any>;

  keyProp?: string;
  labelProp?: string;
}>(), {
  keyProp: 'id',
  labelProp: 'name',
});

const emits = defineEmits<{
  update: [ value: any ]
}>();

const attrs = useAttrs() as {
  multiple?: boolean;
};

const [ modelValue, modifiers ] = defineModel<any, 'complex'>('value', {
  get(v: any) {
    if ( !v || !v?.length ) return [];
    if ( !Array.isArray(v) ) v = [ v ];

    return v;
  },
  set(v: SelectPageKey[]) {
    return v[ 0 ];
  },
});

async function fetchData(data: PageParameters, callback: FetchDataCallback) {
  const { search: keyword, pageNumber, pageSize } = data;
  try {
    const { data, total } = await props.load(pageNumber, pageSize, { ...props.query, keyword });
    callback(data, total);
  } catch ( e ) {
    callback([], 0);
  }
}

async function fetchSelectedData(keys: SelectPageKey[], callback: FetchSelectedDataCallback) {
  if ( attrs.multiple ) {
    callback(keys.map(key => (
      {
        [ props.labelProp ]: key,
        [ props.labelProp ]: key,
      }
    )));
  } else {
    try {
      const { data } = await props.load(1, 1, { keyword: keys[ 0 ] });
      callback(data);
    } catch ( e ) {
      callback([]);
    }
  }
}

function onSelect(items: Record<string, unknown>[]) {
  emits('update', attrs.multiple ? items : items?.[ 0 ]);
}
</script>
<template>
  <SelectPageList
    language="zh-chs"
    :key-prop="props.keyProp" :label-prop="props.labelProp"
    v-model="modelValue" @fetch-data="fetchData"
    @fetch-selected-data="fetchSelectedData"
    @selection-change="onSelect"
  />
</template>
<style lang="scss">
.v-dropdown-trigger {
  width: 100%;

  .sp-trigger-container {
    padding: 3px 6px;
    border-radius: 6px;

    &.sp-opened,
    &:hover {
      border-color: #6bceff !important;
    }

    &.sp-opened,
    &:focus {
      border-color: #6bceff !important;
      box-shadow: 0 0 0 2px rgba(5, 205, 255, 0.06);
      border-inline-end-width: 1px;
      outline: 0;
    }
  }

  .sp-placeholder {
    color: #e0e0e0 !important;
  }
}
</style>
