<script lang="ts" setup>
import type { DataNode } from 'ant-design-vue/es/tree';

import type { Recordable } from '@vben/types';

import type { SentinelApi } from '#/api';

import { computed, nextTick, reactive, ref } from 'vue';

import { Tree, useVbenDrawer } from '@vben/common-ui';

import { message, Spin } from 'ant-design-vue';

import { useVbenForm } from '#/adapter/form';
import { addLottery, updateLottery } from '#/api';
import { $t } from '#/locales';

import { useFormSchema } from './data';

const emits = defineEmits(['success']);

const formData = ref<SentinelApi.Record>();
const uploadState = reactive<{
  sizeKb?: number;
  uploaded: boolean;
  uploadId?: string;
  uploading: boolean;
}>({
  uploading: false,
  uploaded: false,
});
const [Form, formApi] = useVbenForm({
  schema: useFormSchema(uploadState),
  showDefaultActions: false,
});

const roles = ref<DataNode[]>([]);
const loadingRoles = ref(false);

const id = ref();
const [Drawer, drawerApi] = useVbenDrawer({
  async onConfirm() {
    const { valid } = await formApi.validate();
    if (!valid) return;

    if (uploadState.uploading) {
      message.warning('文件正在上传，请稍后');
      return;
    }

    if (!uploadState.uploaded || !uploadState.uploadId) {
      message.warning('礼品照片尚未上传');
      return;
    }

    const values = await formApi.getValues();
    drawerApi.lock();
    (id.value
      ? updateLottery(id.value, uploadState.uploadId, values)
      : addLottery(uploadState.uploadId, values)
    )
      .then(() => {
        emits('success');
        drawerApi.close();
      })
      .catch(() => {
        drawerApi.unlock();
      });
  },

  async onOpenChange(isOpen) {
    if (isOpen) {
      const data = drawerApi.getData<SentinelApi.Record>();
      formApi.resetForm();

      if (data) {
        formData.value = data;
        id.value = data.id;
      } else {
        id.value = undefined;
      }

      // Wait for Vue to flush DOM updates (form fields mounted)
      await nextTick();
      if (data) {
        formApi.setValues(data);
      }
    }
  },
});

const getDrawerTitle = computed(() => {
  return formData.value?.id ? '修改' : '新增';
});

function getNodeClass(node: Recordable<any>) {
  const classes: string[] = [];
  if (node.value?.type === 'button') {
    classes.push('inline-flex');
  }

  return classes.join(' ');
}
</script>
<template>
  <Drawer :title="getDrawerTitle">
    <Form>
      <template #roles="slotProps">
        <Spin :spinning="loadingRoles" wrapper-class-name="w-full">
          <Tree
            :tree-data="roles"
            multiple
            bordered
            :default-expanded-level="2"
            :get-node-class="getNodeClass"
            v-bind="slotProps"
            value-field="id"
            label-field="title"
          >
            <template #node="{ value }">
              {{ $t(value.id) }}
            </template>
          </Tree>
        </Spin>
      </template>
    </Form>
  </Drawer>
</template>
<style lang="css" scoped>
:deep(.ant-tree-title) {
  .tree-actions {
    display: none;
    margin-left: 20px;
  }
}

:deep(.ant-tree-title:hover) {
  .tree-actions {
    display: flex;
    flex: auto;
    justify-content: flex-end;
    margin-left: 20px;
  }
}
</style>
