<script setup lang="ts">
  import { computed, ref, watch } from 'vue';
  import { jsonClone } from '@sa/utils';
  import { fetchCreate${BusinessName}, fetchUpdate${BusinessName}#if($tplCategory == 'tree'), fetchGet${BusinessName}List#end } from '@/service/api/${moduleName}/${business__name}';
  import { useFormRules, useNaiveForm } from '@/hooks/common/form';
      #if($tplCategory == 'tree')
      import { handleTree } from '@/utils/common';
      #end
  import { $t } from '@/locales';

  defineOptions({
    name: '${BusinessName}OperateDrawer'
  });

  interface Props {
    /** the type of operation */
    operateType: NaiveUI.TableOperateType;
    /** the edit row data */
    rowData?: Api.$ModuleName.${BusinessName} | null;
  }

  const props = defineProps<Props>();

  interface Emits {
    (e: 'submitted'): void;
  }

  const emit = defineEmits<Emits>();

  const visible = defineModel<boolean>('visible', {
    default: false
  });
      #if($tplCategory == 'tree')

      const treeList = ref<Api.Demo.Tree[]>([]);
      #end

  const { formRef, validate, restoreValidation } = useNaiveForm();
  const { createRequiredRule } = useFormRules();

  const title = computed(() => {
    const titles: Record<NaiveUI.TableOperateType, string> = {
      add: '新增${functionName}',
      edit: '编辑${functionName}'
    };
    return titles[props.operateType];
  });

  type Model = Api.$ModuleName.${BusinessName}OperateParams;

  const model = ref<Model>(createDefaultModel());

  function createDefaultModel(): Model {
    return {
        #foreach($column in $columns)
            #if($column.insert() || $column.isEdit())
                ${column.javaField}:#if($column.javaType == 'String' || ($!column.dictType && $column.dictType != '')) ''#else null#end#if($foreach.hasNext),#end
            #end
        #end
    };
  }

  type RuleKey = Extract<
      keyof Model,
      #foreach($column in $columns)
          #if($column.required)
              | '$column.javaField'#if($foreach.hasNext)#end
          #end#end>;

  const rules: Record<RuleKey, App.Global.FormRule> = {
      #foreach($column in $columns)
          #if($column.required)
                  $column.javaField: createRequiredRule('${column.columnComment}不能为空')#if($foreach.hasNext),#end
          #end
      #end
  };

  function handleUpdateModelWhenEdit() {
    model.value = createDefaultModel();
      #if($tplCategory == 'tree')
        model.value.$treeParentCode = props.rowData?.$treeCode || 0;
      #end

    if (props.operateType === 'edit' && props.rowData) {
      Object.assign(model.value, jsonClone(props.rowData));
    }
  }

  function closeDrawer() {
    visible.value = false;
  }

  async function handleSubmit() {
    await validate();

      #set($operateColumns = [])
      #foreach($column in $columns)#if($column.insert || $column.edit)#set($dummy = $operateColumns.add($column))#end#end
    const { #foreach($column in $operateColumns)$column.javaField#if($foreach.hasNext), #end#end } = model.value;

    // request
    if (props.operateType === 'add') {
        #set($addFields = [])
        #foreach($column in $columns)#if($column.insert)#set($dummy = $addFields.add($column.javaField))#end#end
    const { error } = await fetchCreate${BusinessName}({ #foreach($field in $addFields)$field#if($foreach.hasNext), #end#end });
      if (error) return;
    }

    if (props.operateType === 'edit') {
        #set($editFields = [])
        #foreach($column in $columns)#if($column.edit)#set($dummy = $editFields.add($column.javaField))#end#end
    const { error } = await fetchUpdate${BusinessName}({ #foreach($field in $editFields)$field#if($foreach.hasNext), #end#end });
      if (error) return;
    }

    window.$message?.success($t('common.updateSuccess'));
    closeDrawer();
    emit('submitted');
  }
      #if($tplCategory == 'tree')

      async function getTreeList() {
        const { data, error } = await fetchGet${BusinessName}List();
        if (error) {
          return;
        }
        const { tree } = handleTree(data);
        treeList.value = tree;
      }
      #end

  watch(visible, () => {
    if (visible.value) {
      handleUpdateModelWhenEdit();
      restoreValidation();
        #if($tplCategory == 'tree')
          getTreeList();
        #end
    }
  });
      #if($tplCategory == 'tree')

      const treeOptions = computed(() => {
        return [
          {
            id: 0,
            treeName: '顶级节点',
            children: treeList.value
          }
        ];
      });
      #end
</script>

<template>
  <NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
    <NDrawerContent :title="title" :native-scrollbar="false" closable>
      <NForm ref="formRef" :model="model" :rules="rules">
          #set($immediateDictList = [])
          #foreach($column in $columns)
              #set($field=$column.javaField)
              #if(($column.insert || $column.edit) && !$column.pk)
                  #set($isImmediate = !$column.isList() && !$column.isQuery() && !$immediateDictList.contains($column.dictType))
                <NFormItem label="$column.columnComment" path="$column.javaField">
                    #if($tplCategory == 'tree' && $column.javaField == $treeParentCode)
                      <NTreeSelect
                          v-model:value="model.$treeParentCode"
                          filterable
                          class="h-full"
                          key-field="$treeCode"
                          label-field="$treeName"
                          :options="treeOptions"
                          :default-expanded-keys="[0]"
                      />
                    #elseif($column.htmlType == "textarea" || $column.htmlType == "editor")
                      <NInput
                          v-model:value="model.$column.javaField"
                          :rows="3"
                          type="textarea"
                          placeholder="请输入$column.columnComment"
                      />
                    #elseif($column.htmlType == "select" && $column.dictType)
                      <DictSelect
                          v-model:value="model.$column.javaField"
                          placeholder="请选择$column.columnComment"
                          dict-code="$column.dictType"
                          clearable
                          #if($isImmediate)#set($void = $immediateDictList.add($column.dictType))
                          immediate
                          #end
                      />
                    #elseif($column.htmlType == "select" && !$column.dictType)
                      <NSelect
                          v-model:value="model.$column.javaField"
                          placeholder="请选择$column.columnComment"
                          :options="[{ value: '0', label: '请选择字典生成' }]"
                          clearable
                      />
                    #elseif($column.htmlType == "radio" && $column.dictType)
                      <DictRadio
                          v-model:value="model.$column.javaField"
                          placeholder="请选择$column.columnComment"
                          dict-code="$column.dictType"
                          clearable
                          #if($isImmediate)#set($void = $immediateDictList.add($column.dictType))
                          immediate
                          #end
                      />
                    #elseif($column.htmlType == "radio" && !$column.dictType)
                      <NRadioGroup v-model:value="model.$column.javaField">
                        <NSpace>
                          <NRadio value="0" label="请选择字典生成" />
                        </NSpace>
                      </NRadioGroup>
                    #elseif($column.htmlType == "checkbox" && $column.dictType)
                      <DictCheckbox
                          v-model:value="model.$column.javaField"
                          placeholder="请选择$column.columnComment"
                          dict-code="$column.dictType"
                          clearable
                          #if($isImmediate)#set($void = $immediateDictList.add($column.dictType))
                          immediate
                          #end
                      />
                    #elseif($column.htmlType == "checkbox" && $column.dictType)
                      <NCheckboxGroup v-model:value="model.$column.javaField">
                        <NSpace>
                          <NCheckbox value="0" label="请选择字典生成" />
                        </NSpace>
                      </NCheckboxGroup>
                    #elseif($column.htmlType == 'datetime')
                      <NDatePicker
                          v-model:formatted-value="model.$column.javaField"
                          type="datetime"
                          value-format="yyyy-MM-dd HH:mm:ss"
                          clearable
                      />
                    #elseif($column.htmlType == "imageUpload")
                      <OssUpload v-model:value="model.$column.javaField" upload-type="image" />
                    #elseif($column.htmlType == "fileUpload")
                      <OssUpload v-model:value="model.$column.javaField" upload-type="file" />
                    #elseif($column.htmlType == "editor")
                      <TinymceEditor v-model:value="model.$column.javaField" />
                    #else          <NInput v-model:value="model.$column.javaField" placeholder="请输入$column.columnComment" />
                    #end
                </NFormItem>
              #end
          #end
      </NForm>
      <template #footer>
        <NSpace :size="16">
          <NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton>
          <NButton type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</NButton>
        </NSpace>
      </template>
    </NDrawerContent>
  </NDrawer>
</template>

<style scoped></style>
