<script setup lang="ts">
import { useForm, useRequest } from 'alova/client';
import type { VxeFormListeners, VxeFormProps } from 'vxe-pc-ui';
import { getPatientTagsMethod, searchTagsFromSelectableMethod, updatePatientTagMethod } from '@/request/api/patient.api';
import type { PatientTagVO } from '@/model';
import { list2Groups } from '@/tools/data';
import { message as Message } from 'ant-design-vue';

interface FormModel {
  tags: string[];
}

const props = defineProps<{
  id: string;
  tags?: PatientTagVO[];
}>();

const emits = defineEmits<{
  destroy: [refreshValue?: PatientTagVO[]];
}>();

const {
  form,
  send: submit,
  loading: submitting,
} = useForm((model) => updatePatientTagMethod(props.id, model.tags), {
  initialForm: {
    selected: [],
    tags: props.tags ? [...props.tags] : [],
  },
}).onSuccess(({ data }) => {
  Message.success(`标签更新成功`);
  emits('destroy', data);
});

const {
  data: patientTags,
  loading,
  send: loadPatientTags,
} = useRequest(() => getPatientTagsMethod(props.id), {
  initialData: props.tags ? [...props.tags] : [],
  immediate: false,
}).onSuccess(({ data: tags }) => {
  form.value.tags = [...tags];
});

onMounted(() => {
  if (!patientTags.value.length) loadPatientTags();
});

const { data: searchTags, loading: tagsLoading } = useRequest(searchTagsFromSelectableMethod, {
  initialData: [],
});

const selected = computed(() => form.value.tags.map((item) => item.id));

const formProps = reactive<VxeFormProps<FormModel>>({
  titleWidth: 0,
  titleAlign: 'right',
  titleColon: true,
  items: [
    {
      field: 'selected',
      title: '',
      span: 24,
      itemRender: {
        name: 'VxeSelect',
        props: {
          loading: tagsLoading,
          optionGroups: computed(() =>
            list2Groups(
              searchTags.value.filter((tag) => !(tag.disabled || selected.value.includes(tag.id))),
              'category',
              (key) => ({ 1: '系统标签', 2: '个人标签' })[key]!
            )
          ),
          optionProps: { value: 'id', label: 'name' },
          optionGroupProps: { options: 'groups' },
          multiple: true,
          clearable: true,
          filterable: true,
        },
        events: {
          visibleChange(ref, { visible }) {
            if (!visible) ref.data.selected?.forEach(appendTag);
          },
        },
      },
    },
    { align: 'center', span: 24, slots: { default: 'active' } },
  ],
  rules: {},
});
const formEmits: VxeFormListeners<FormModel> = {
  submit({ data }) {
    submit(data);
  },
  reset() {
    form.value = { tags: [...patientTags.value], selected: [] };
  },
};

function appendTag(id: PatientTagVO['id']) {
  const tag = searchTags.value.find((tag) => tag.id === id);
  if (tag) form.value.tags.push(tag);
  form.value.selected = [];
}

function remove(tag: PatientTagVO, index: number) {
  form.value.tags.splice(index, 1);
}
</script>

<template>
  <a-spin :spinning="loading">
    <div class="flex flex-wrap mt--2">
      <a-tag class="mt-2" v-for="(item, index) in form.tags" :key="item.id" :color="item.color" :closable="!submitting" @close="remove(item, index)">
        {{ item.name }}
      </a-tag>
    </div>
    <vxe-form :data="form" v-bind="formProps" v-on="formEmits">
      <template #active>
        <vxe-button type="submit" status="primary" content="提交" :loading="submitting"></vxe-button>
        <vxe-button type="reset" content="重置" :disabled="submitting"></vxe-button>
      </template>
    </vxe-form>
  </a-spin>
</template>

<style scoped lang="scss"></style>
