<template>
  <BaseWizardStep
    :title="$t('wizard.database.database')"
    :description="$t('wizard.database.desc')"
    step-container="w-full p-8 mb-8 bg-white border border-gray-200 border-solid rounded md:w-full"
  >
    <component
      :is="databaseData.database_connection"
      :config-data="databaseData"
      :is-saving="isSaving"
      @on-change-driver="getDatabaseConfig"
      @submit-data="next"
    />
  </BaseWizardStep>
</template>

<script>
import { ref, computed, onMounted, watch } from 'vue'
import Mysql from './database/MysqlDatabase.vue'
import Pgsql from './database/PgsqlDatabase.vue'
import Sqlite from './database/SqliteDatabase.vue'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useInstallationStore } from '@/scripts/admin/stores/installation'
import { useI18n } from 'vue-i18n'

export default {
  components: {
    Mysql,
    Pgsql,
    Sqlite,
    // Resolved by <component :is="database_connection">. MariaDB takes the same
    // fields as MySQL, so it reuses that form rather than duplicating it —
    // without an entry here the step renders blank. See InvoiceShelf/docker#79.
    Mariadb: Mysql,
  },

  emits: ['next'],

  setup(props, { emit }) {
    const database_connection = ref('mysql')
    const isSaving = ref(false)
    const { t } = useI18n()
    const { global } = window.i18n

    const notificationStore = useNotificationStore()
    const installationStore = useInstallationStore()

    const databaseData = computed(() => installationStore.currentDataBaseData)

    watch(() => global.locale.value, (newLocale) => {
      installationStore.currentDataBaseData.app_locale = newLocale
    }, { immediate: true })

    async function getDatabaseConfig(connection) {
      let params = {}
      if (connection) {
        params.connection = connection
      }

      const res = await installationStore.fetchInstallationDatabase(params)

      if (res.data.success) {
        databaseData.value.database_connection =
          res.data.config.database_connection
      }

      if (res.data.config.database_connection === 'sqlite') {
        databaseData.value.database_name = res.data.config.database_name
      } else {
        databaseData.value.database_name = null
        if (res.data.config.database_host) {
          databaseData.value.database_hostname = res.data.config.database_host
        }
        if (res.data.config.database_port) {
          databaseData.value.database_port = res.data.config.database_port
        }
      }
    }

    async function next(databaseData) {
      isSaving.value = true

      try {
        let res = await installationStore.addInstallationDatabase(databaseData)
        isSaving.value = false

        if (res.data.success) {
          await installationStore.addInstallationFinish()

          emit('next', 3)

          let language = {
            profile_language: global.locale.value,
          }
          await installationStore.addInstallationLanguage(language)


          notificationStore.showNotification({
            type: 'success',
            message: t('wizard.success.' + res.data.success),
          })

          return
        } else if (res.data.error) {
          if (res.data.requirement) {
            notificationStore.showNotification({
              type: 'error',
              message: t('wizard.errors.' + res.data.error, {
                version: res.data.requirement.minimum,
                name: databaseData.value.database_connection,
              }),
            })
            return
          }

          notificationStore.showNotification({
            type: 'error',
            message: t('wizard.errors.' + res.data.error),
          })
        } else if (res.data.errors) {
          notificationStore.showNotification({
            type: 'error',
            message: res.data.errors[0],
          })
        } else if (res.data.error_message) {
          notificationStore.showNotification({
            type: 'error',
            message: res.data.error_message,
          })
        }
      } catch (e) {
        notificationStore.showNotification({
          type: 'error',
          message: t('validation.something_went_wrong'),
        })
        isSaving.value = false
      } finally {
        isSaving.value = false
      }
    }

    onMounted(() => {
      getDatabaseConfig()
    })

    return {
      databaseData,
      database_connection,
      isSaving,
      getDatabaseConfig,
      next,
    }
  },
}
</script>
