<template>
  <ADialog v-model:show="showDialog"
    :closed="dialogCloseHandler"
    title="预览"
  >
    <div class="content">
      <ElForm :model="formData"
        class="sys_user-form"
        ref="codeForm"
        :rules="rules"
      >
        <ElFormItem label="表名称">
          <ElTooltip
            :content="currentTable.tableComment"
            placement="top">
            <ElInput
              v-model="currentTable.tableName"
              readonly
            />
          </ElTooltip>
        </ElFormItem>
        <ElFormItem label="前端/后端" prop="lang">
          <ElSelect
            v-model="formData.lang"
            placeholder="前端/后端"
            @change="changeTplHandler">
            <ElOption
              label="前端"
              value="ts"/>
            <ElOption
              label="后端"
              value="java"/>
          </ElSelect>
        </ElFormItem>
        <ElFormItem label="表前缀" prop="data.prefix">
          <ElInput
            v-model="formData.data.prefix"
            placeholder="表前缀"/>
        </ElFormItem>
        <ElFormItem v-if="formData.lang === 'java'" label="基础包名称" prop="data.basePackage">
          <ElInput
            v-model="formData.data.basePackage"
            placeholder="基础包名称"/>
        </ElFormItem>
        <ElFormItem v-if="formData.lang === 'java'" label="模块名称" prop="data.moduleName">
          <ElInput
            v-model="formData.data.moduleName"
            placeholder="模块名称"/>
        </ElFormItem>
        <ElFormItem v-if="formData.lang === 'ts'" label="目录名称" prop="data.moduleName">
          <ElTooltip
            content="相对于 pages 目录"
            placement="top">
            <ElInput
              v-model="formData.data.moduleName"
              placeholder="目录名称"/>
          </ElTooltip>
        </ElFormItem>
        <ElFormItem v-if="formData.lang === 'ts'" label="子目录名称" prop="data.subModuleName">
          <ElInput
            v-model="formData.data.subModuleName"
            placeholder="子目录名称"/>
        </ElFormItem>
      </ElForm>
      <ElDivider direction="vertical"/>
      <ElTabs v-model="activeName" class="code-panel">
        <ElTabPane v-for="tab in tpls" :label="tab.tplName!" :name="tab.tplName!">
          <div style="margin-bottom: 10px;">
            文件名：{{ codeInfo[tab.tplName!]?.path }}
          </div>
          <ElInput :model-value="codeInfo[tab.tplName!]?.content" :rows="12" :spellcheck="false" resize="none" type="textarea"/>
        </ElTabPane>
      </ElTabs>
    </div>
    <template #footer>
      <ElButton @click="showDialog = false">关闭</ElButton>
      <ElButton :loading="previewing" type="primary" @click="previewHandler">预览</ElButton>
      <ElButton :loading="downloading" type="primary" @click="downloadHandler">下载</ElButton>
    </template>
  </ADialog>
</template>
<script lang="ts" setup>
import {
  ElMessage,
  type FormInstance,
  type FormRules,
} from 'element-plus'
import TplApi from '@/pages/sys/gen/tpl/tpl-api.ts'
import Strings from '@/common/utils/strings.ts'
import FormUtil from '@/common/utils/formUtil.ts'
import ADialog from '@/components/a-dialog/ADialog.vue'

const activeName = ref('')
const showDialog = ref(false)
const downloading = ref(false)
const previewing = ref(false)
const codeInfo = ref<TplTypes.CodeInfo>({})
const tpls = ref<TplTypes.SearchTplResult[]>([])
const codeFormIns = useTemplateRef<FormInstance>('codeForm')

const currentTable = reactive<DbTableTypes.TableInfo>({})

interface FormType {
  lang: 'java' | 'ts'
  data: {
    prefix: string
    basePackage: string
    moduleName: string
    subModuleName: string
  }
}

const formData = ref<FormType>({
  lang: 'ts',
  data: {
    prefix: '',
    basePackage: '',
    moduleName: '',
    subModuleName: '',
  },
})

const rules = reactive<FormRules<FormType>>({
  'data.prefix': [ {
    validator(_: any, value: string, callback: any) {
      if (Strings.isBlank(value)) {
        callback(new Error('请填写表前缀'))
      } else if (!value.endsWith('_')) {
        callback(new Error('表前缀要以下划线结束'))
      } else {
        callback()
      }
    }, trigger: 'blur',
  } ],
  'data.basePackage': [ {
    validator(_: any, value: string, callback: any) {
      if (formData.value.lang != 'java') {
        callback()
        return
      }
      if (Strings.isBlank(value)) {
        callback(new Error('请填写基础包名'))
      } else {
        callback()
      }
    }, trigger: 'blur',
  } ],
  'data.moduleName': [ {
    validator(_: any, value: string, callback: any) {
      if (Strings.isBlank(value)) {
        callback(new Error(formData.value.lang === 'ts' ? '请填写目录名称' : '请填写模块名称'))
      } else {
        callback()
      }
    }, trigger: 'blur',
  } ],
  'data.subModuleName': [ {
    validator(_: any, value: string, callback: any) {
      if (formData.value.lang != 'ts') {
        callback()
        return
      }
      if (Strings.isBlank(value)) {
        callback(new Error('请填写子目录名称'))
      } else {
        callback()
      }
    }, trigger: 'blur',
  } ],
})

function changeTplHandler() {
  TplApi.listAll(formData.value.lang)
    .then(res => {
      tpls.value = res.data
      if (tpls.value.length > 0) {
        activeName.value = tpls.value[0].tplName!
      } else {
        activeName.value = ''
      }
    })
}

function dialogCloseHandler() {
  Object.assign(currentTable, {})
  tpls.value = []
  codeInfo.value = {}
  formData.value = {
    lang: 'ts',
    data: {
      ...formData.value.data,
    },
  }
}

function downloadHandler() {
  downloading.value = true
  FormUtil.submit(codeFormIns, () => TplApi.download(formData.value.lang, currentTable.tableName!, formData.value.data)
    .then(() => {
      ElMessage.success('下载成功')
    }))
    .finally(() => {
      downloading.value = false
    })
}

function previewHandler() {
  previewing.value = true
  FormUtil.submit(codeFormIns, () => TplApi.preview(formData.value.lang, currentTable.tableName!, formData.value.data))
    .then(res => {
      codeInfo.value = res.data
    })
    .finally(() => {
      previewing.value = false
    })
}

defineExpose({
  open(data?: DbTableTypes.TableInfo) {
    Object.assign(currentTable, data)
    showDialog.value = true
    formData.value = {
      lang: 'ts',
      data: {
        ...formData.value.data,
      },
    }
    changeTplHandler()
  },
})
</script>
<style lang="stylus" scoped>
.content {
  display: flex;
  box-sizing: border-box;
  width: 800px;
  height: 400px;

  & > form, & > div:nth-child(3) {
    padding 20px
    border 1px solid #D3D7DE
  }

  & > form {
    width: 270px;
    flex-shrink: 0;
    box-sizing: border-box;
  }

  & > div:nth-child(2) {
    height auto
    width: 2px;
    flex-shrink: 0;
    box-sizing: border-box;
  }

  & > div:nth-child(3) {
    width: calc(800px - 288px);
    height: 100%;
    box-sizing: border-box;
  }
}
</style>
