<script setup lang="ts">
import { FormInst, FormItemRule, FormRules, ScrollbarInst } from 'naive-ui'
import { nextTick, reactive, ref, shallowReadonly, useTemplateRef, watch, watchEffect } from 'vue'
import { useI18n } from 'vue-i18n'
import CustomModal from '@/components/custom-modal/custom-modal.vue'
import { DatabaseFormInterface } from '../type.d'
import { fetchTestConnectionDataBase } from '@/apis/database'

type DatabaseEditFormInterface = DatabaseFormInterface & { id: number }

interface Props {
  databaseDetail: DatabaseEditFormInterface
  btnLoading: boolean
}

const props = defineProps<Props>()

const emit = defineEmits<{
  (e: 'confirm', databaseFormData: DatabaseEditFormInterface): void
}>()

const { t } = useI18n()

const showModal = defineModel<boolean>('showModal', { required: true })

const databaseFormRef = ref<FormInst | null>(null)
const scrollbarRef = useTemplateRef<ScrollbarInst | null>('scrollbarRef')

let databaseFormData = reactive<DatabaseEditFormInterface>(databaseFormDataFactory())

const databaseFormRules = shallowReadonly<FormRules>({
  title: [
    {
      key: 'title',
      required: true,
      validator: (_rule: FormItemRule, value: string) => {
        const pattern = /^[\u4e00-\u9fa5a-zA-Z0-9_\-\\.]+$/

        if (!value) {
          return new Error(t('personal_space_module.database_module.please_enter_db_title'))
        } else if (!pattern.test(value)) {
          return new Error(t('personal_space_module.database_module.db_title_rule'))
        }

        return
      },
      trigger: 'blur',
    },
  ],
  dbPassword: [
    { required: true, message: t('personal_space_module.database_module.please_enter_db_password'), trigger: 'blur' },
  ],
})

const isConnectDBSuccess = ref(false)
const showConnectStatus = ref(false)
const connectBtnLoading = ref(false)

watchEffect(() => {
  if (showModal.value) {
    databaseFormData = Object.assign(databaseFormData, props.databaseDetail)
    showConnectStatus.value = false
    isConnectDBSuccess.value = false
  }
})

watch(
  () => [databaseFormData.dbPassword],
  () => {
    showConnectStatus.value = false
    isConnectDBSuccess.value = false
  },
)

function databaseFormDataFactory(): DatabaseEditFormInterface {
  return {
    id: 0,
    title: '',
    desc: '',
    dbType: '',
    dbHost: '',
    dbPort: 0,
    dbName: '',
    dbUsername: '',
    dbPassword: '',
  }
}

function handleConnectDatabase() {
  databaseFormRef.value?.validate(
    async (errors) => {
      if (!errors) {
        const { dbType, dbHost, dbPort, dbName, dbUsername, dbPassword } = databaseFormData
        const payload = {
          dbType,
          dbHost,
          dbPort,
          dbName,
          dbUsername,
          dbPassword,
        }

        connectBtnLoading.value = true

        const res = await fetchTestConnectionDataBase<{ status: 'success' | 'fail' }>(payload).finally(() => {
          showConnectStatus.value = true
          connectBtnLoading.value = false
          nextTick(() => {
            scrollbarRef.value?.scrollTo({ top: 9999, behavior: 'smooth' })
          })
        })

        if (res.code === 0) {
          isConnectDBSuccess.value = res.data.status === 'success'
        }
      }
    },
    (rule) => {
      return rule?.key !== 'title'
    },
  )
}

function handleUpdateDatabase() {
  databaseFormRef.value?.validate((errors) => {
    if (!errors) {
      if (!isConnectDBSuccess.value) {
        window.$message.warning(t('personal_space_module.database_module.connect_test_must_pass_to_update'))
        return
      }

      emit('confirm', databaseFormData)
    }
  })
}
</script>

<template>
  <CustomModal
    v-model:is-show="showModal"
    :title="t('personal_space_module.database_module.edit_database')"
    :width="534"
    :btn-loading="btnLoading"
    :content-style="{ padding: '0 12px 24px' }"
    @confirm="handleUpdateDatabase"
  >
    <template #content>
      <n-scrollbar ref="scrollbarRef" style="max-height: 550px" class="px-3">
        <n-form ref="databaseFormRef" :model="databaseFormData" :rules="databaseFormRules">
          <n-form-item
            path="title"
            :label="t('personal_space_module.database_module.db_title')"
            :feedback-style="{ fontSize: '13px' }"
          >
            <div class="flex w-full flex-col">
              <n-input
                v-model:value="databaseFormData.title"
                :placeholder="t('personal_space_module.database_module.please_enter_db_title')"
                show-count
                :maxlength="50"
              />
              <span class="text-gray-font-color mt-1 px-2.5 text-[12px]">
                {{ t('personal_space_module.database_module.db_title_rule') }}
              </span>
            </div>
          </n-form-item>

          <n-form-item :label="t('personal_space_module.database_module.db_desc')">
            <n-input
              v-model:value="databaseFormData.desc"
              :placeholder="t('personal_space_module.database_module.please_enter_db_desc')"
              show-count
              :maxlength="100"
              type="textarea"
              :autosize="{ minRows: 4, maxRows: 6 }"
            />
          </n-form-item>

          <h3 class="font-family-medium mb-4 text-[18px]">
            {{ t('personal_space_module.database_module.db_source_info') }}
          </h3>

          <n-form-item
            show-require-mark
            :label="t('personal_space_module.database_module.db_source_type')"
            :feedback-style="{ fontSize: '13px' }"
          >
            <div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]">
              {{ databaseFormData.dbType }}
            </div>
          </n-form-item>

          <n-form-item
            show-require-mark
            :label="t('personal_space_module.database_module.db_host')"
            :feedback-style="{ fontSize: '13px' }"
          >
            <div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]">
              {{ databaseFormData.dbHost }}
            </div>
          </n-form-item>

          <n-form-item
            show-require-mark
            :label="t('personal_space_module.database_module.db_port')"
            :feedback-style="{ fontSize: '13px' }"
          >
            <div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]">
              {{ databaseFormData.dbPort }}
            </div>
          </n-form-item>

          <n-form-item
            show-require-mark
            :label="t('personal_space_module.database_module.db_name')"
            :feedback-style="{ fontSize: '13px' }"
          >
            <div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]">
              {{ databaseFormData.dbName }}
            </div>
          </n-form-item>

          <n-form-item
            show-require-mark
            :label="t('personal_space_module.database_module.db_username')"
            :feedback-style="{ fontSize: '13px' }"
          >
            <div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]">
              {{ databaseFormData.dbUsername }}
            </div>
          </n-form-item>

          <n-form-item
            path="dbPassword"
            :label="t('personal_space_module.database_module.db_password')"
            :feedback-style="{ fontSize: '13px' }"
          >
            <n-input
              v-model:value="databaseFormData.dbPassword"
              type="password"
              show-password-on="click"
              :input-props="{ autocomplete: 'off' }"
              :placeholder="t('personal_space_module.database_module.please_enter_db_password')"
              class="font-sans"
            />
          </n-form-item>
        </n-form>

        <div
          v-show="showConnectStatus"
          class="flex items-center gap-[8px] rounded-[10px] px-3 py-[5px]"
          :class="isConnectDBSuccess ? 'bg-[#ECFFE6]' : 'bg-[#FFE8E6]'"
        >
          <div class="h-[16px] w-[16px]" :class="isConnectDBSuccess ? 'bg-svg-success' : 'bg-svg-error'" />
          <span class="text-[12px] leading-[16px]">
            {{
              isConnectDBSuccess
                ? t('personal_space_module.database_module.connect_test_success')
                : t('personal_space_module.database_module.connect_test_fail')
            }}
          </span>
        </div>

        <div class="flex-center mt-5">
          <n-button
            type="primary"
            color="#6F77FF"
            class="h-[34px]!"
            :bordered="false"
            :focusable="false"
            :loading="connectBtnLoading"
            @click="handleConnectDatabase"
          >
            {{ t('personal_space_module.database_module.connect_test') }}
          </n-button>
        </div>
      </n-scrollbar>
    </template>
  </CustomModal>
</template>

<style lang="scss" scoped>
:deep(.n-form-item-label__text) {
  font-family: 'SourceHanSansCN-Medium';
}
</style>
