<script lang="ts" setup>
import type { VbenFormSchema } from '#/adapter/form';
import type { SysTenantApi } from '#/api/system/sysTenant';
import type { TenantPackageApi } from '#/api/system/sysTenantPackage';

import { computed, h, ref } from 'vue';
import { useRouter } from 'vue-router';

import { useVbenDrawer } from '@vben/common-ui';
import { getVxePopupContainer } from '@vben/utils';

import { Button, message, Skeleton } from 'ant-design-vue';
import dayjs from 'dayjs';

import { useVbenForm, z } from '#/adapter/form';
import { apiAdd, apiUpdate } from '#/api/system/sysTenant';
import { apiSelectList } from '#/api/system/sysTenantPackage';
import { useTenantStore } from '#/store/tenant';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';

const emit = defineEmits<{
  success: [];
}>();
const formData = ref<SysTenantApi.Tenant>();
const loading = ref(false);
const tenantStore = useTenantStore();
const router = useRouter();

const defaultExpireTime = dayjs()
  .add(365, 'days')
  .startOf('day')
  .format('YYYY-MM-DD HH:mm:ss');

const formSchema: VbenFormSchema[] = [
  {
    component: 'Input',
    dependencies: {
      show: () => false,
      triggerFields: [''],
    },
    fieldName: 'id',
    label: 'id',
  },
  {
    component: 'Divider',
    componentProps: {
      orientation: 'center',
    },
    fieldName: 'divider1',
    hideLabel: true,
    renderComponentContent: () => ({
      default: () => '基本信息',
    }),
  },
  {
    component: 'Input',
    dependencies: {
      show: () => false,
      triggerFields: [''],
    },
    fieldName: 'tenantCode',
    label: '租户编号',
  },
  {
    component: 'Input',
    fieldName: 'companyName',
    label: '企业名称',
    rules: 'required',
  },
  {
    component: 'Input',
    fieldName: 'contactUserName',
    label: '联系人',
    rules: 'required',
  },
  {
    component: 'Input',
    fieldName: 'contactPhone',
    label: '联系电话',
    rules: z
      .string()
      .regex(/^1[3-9]\d{9}$/, { message: '请输入正确的联系电话' }),
  },
  {
    component: 'Divider',
    componentProps: {
      orientation: 'center',
    },
    fieldName: 'divider2',
    hideLabel: true,
    renderComponentContent: () => ({
      default: () => '管理员信息',
    }),
    dependencies: {
      if: (values) => !values?.tenantCode,
      triggerFields: ['tenantCode'],
    },
  },
  {
    component: 'Input',
    fieldName: 'username',
    label: '用户账号',
    rules: 'required',
    dependencies: {
      if: (values) => !values?.tenantCode,
      triggerFields: ['tenantCode'],
    },
  },
  {
    component: 'InputPassword',
    fieldName: 'password',
    label: '用户密码',
    rules: z.string().min(5, { message: '请输入密码' }),
    dependencies: {
      if: (values) => !values?.tenantCode,
      triggerFields: ['tenantCode'],
    },
  },
  {
    component: 'Divider',
    componentProps: {
      orientation: 'center',
    },
    fieldName: 'divider3',
    hideLabel: true,
    renderComponentContent: () => ({
      default: () => '租户设置',
    }),
  },
  {
    component: 'ApiSelect',
    componentProps: {
      api: apiSelectList,
      // 接口转options格式
      afterFetch: (data: TenantPackageApi.TenantPackage[]) => {
        /**
         * 检测是否存在租户套餐 你也不想表单填完了发现套餐为0无法选中吧
         */
        if (data.length === 0) {
          const closeMessage = message.error(
            h('span', {}, [
              '请先配置租户套餐',
              h(
                Button,
                {
                  onClick: () => {
                    router.push('/system/tenant/package/list');
                    closeMessage();
                  },
                  type: 'link',
                  size: 'small',
                },
                '前往配置',
              ),
            ]),
          );
          throw new Error('请先配置租户套餐');
        }
        return data.map((item) => ({
          label: item.packageName,
          // title用于选中后回填到输入框 默认为label
          title: item.packageName,
          value: item.id,
        }));
      },
      getVxePopupContainer,
      showSearch: true,
      // mode: 'multiple',
      optionFilterProp: 'title',
      optionLabelProp: 'title',
    },
    fieldName: 'packageId',
    label: '租户套餐',
    rules: 'selectRequired',
  },
  {
    component: 'DatePicker',
    componentProps: {
      format: 'YYYY-MM-DD HH:mm:ss',
      showTime: true,
      valueFormat: 'YYYY-MM-DD HH:mm:ss',
      getVxePopupContainer,
    },
    defaultValue: defaultExpireTime,
    fieldName: 'expireTime',
    help: `已经设置过期时间不允许重置为'无期限'\n即在开通时未设置无期限 以后都不允许设置\n不填就是'无期限'`,
    label: '过期时间',
  },
  {
    component: 'InputNumber',
    componentProps: {
      min: -1,
    },
    defaultValue: -1,
    fieldName: 'accountCount',
    help: '-1不限制用户数量',
    label: '用户数量',
    renderComponentContent(model) {
      return {
        addonBefore: () =>
          model.accountCount === -1 ? '不限制数量' : '输入数量',
      };
    },
    rules: 'required',
  },
  {
    component: 'Input',
    fieldName: 'domain',
    help: '可填写域名/端口 填写域名如: www.test.com 或者 www.test.com:8080 填写ip:端口如: 127.0.0.1:8080',
    label: '绑定域名',
    renderComponentContent() {
      return {
        addonBefore: () => 'http(s)://',
      };
    },
    rules: z
      .string()
      .refine(
        (domain) =>
          !(domain.startsWith('http://') || domain.startsWith('https://')),
        { message: '请输入正确的域名, 不需要http(s)' },
      )
      .optional(),
  },
  {
    component: 'Divider',
    componentProps: {
      orientation: 'center',
    },
    fieldName: 'divider4',
    hideLabel: true,
    renderComponentContent: () => ({
      default: () => '企业信息',
    }),
  },
  {
    component: 'Input',
    fieldName: 'address',
    label: '企业地址',
  },
  {
    component: 'Input',
    fieldName: 'licenseNumber',
    label: '企业代码',
  },
  {
    component: 'Textarea',
    fieldName: 'intro',
    formItemClass: 'items-start',
    label: '企业介绍',
  },
  {
    component: 'Textarea',
    fieldName: 'remark',
    formItemClass: 'items-start',
    label: '备注',
  },
];

const [BasicForm, formApi] = useVbenForm({
  commonConfig: {
    componentProps: {
      class: 'w-full',
    },
    formItemClass: 'col-span-2',
    labelWidth: 90,
  },
  schema: formSchema,
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2',
});

const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
  {
    initializedGetter: defaultFormValueGetter(formApi),
    currentGetter: defaultFormValueGetter(formApi),
  },
);

const [Drawer, drawerApi] = useVbenDrawer({
  onBeforeClose,
  onClosed: handleClosed,
  onConfirm: onSubmit,
  async onOpenChange(isOpen) {
    if (!isOpen) {
      return null;
    }
    drawerApi.drawerLoading(true);
    loading.value = true;

    const data = drawerApi.getData<SysTenantApi.Tenant>();
    if (data) {
      formData.value = data;
      await formApi.setValues(formData.value);
    } else {
      formApi.resetForm();
    }
    await markInitialized();
    drawerApi.drawerLoading(false);
    loading.value = false;
  },
});

async function onSubmit() {
  const { valid } = await formApi.validate();
  if (valid) {
    drawerApi.lock();
    const data = await formApi.getValues<SysTenantApi.Tenant>();
    try {
      await (formData.value?.id
        ? apiUpdate({ id: formData.value.id, ...data })
        : apiAdd(data));
      resetInitialized();
      emit('success');
      drawerApi.close();
      // 重新加载租户信息
      tenantStore.initTenant();
    } finally {
      drawerApi.unlock();
    }
  }
}

async function handleClosed() {
  await formApi.resetForm();
  resetInitialized();
}

const getDrawerTitle = computed(() =>
  formData.value?.id ? '修改租户' : '新增租户',
);
</script>
<template>
  <Drawer class="w-[600px]" :title="getDrawerTitle">
    <Skeleton v-if="loading" active />
    <BasicForm v-show="!loading" />
  </Drawer>
</template>

<style lang="scss" scoped>
:deep(.ant-divider) {
  margin: 8px 0;
}
</style>
