<script setup lang="ts">
import { Check, ChevronRight, Database, Loader2, RefreshCw, Server, ShieldCheck, User } from 'lucide-vue-next'
import { computed, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { toast } from 'vue-sonner'

import { resetInstallCheck } from '@/router/guard/index'

const { t } = useI18n()
const router = useRouter()

const loading = ref(false)
const testing = ref(false)
const step = ref(1)
const installStatus = ref<any>(null)
const checkingStatus = ref(true)

const form = ref({
  db_type: 'sqlite',
  db_host: 'localhost',
  db_port: '3306',
  db_name: 'verification_platform',
  db_username: 'root',
  db_password: '',
  jwt_secret: '',
  admin_user: 'admin',
  admin_pass: '',
  admin_email: '',
  use_redis: false,
  redis_host: 'localhost',
  redis_port: '6379',
  redis_password: '',
  redis_db: 0,
})

const dbTypes = computed(() => [
  { value: 'sqlite', label: t('install.dbTypeSqlite'), desc: t('install.dbTypeSqliteDesc') },
  { value: 'mysql', label: t('install.dbTypeMysql'), desc: t('install.dbTypeMysqlDesc') },
])

async function checkInstallStatus() {
  checkingStatus.value = true
  try {
    const res = await fetch('/api/install/status')
    const data = await res.json()
    installStatus.value = data?.data
    if (data?.data?.installed) {
      resetInstallCheck()
      router.push('/login')
    }
  }
  catch (error) {
    console.error('Check install status failed:', error)
  }
  finally {
    checkingStatus.value = false
  }
}

async function testDatabase() {
  testing.value = true
  try {
    const payload: any = {
      db_type: form.value.db_type,
    }
    if (form.value.db_type === 'mysql') {
      payload.host = form.value.db_host
      payload.port = form.value.db_port
      payload.name = form.value.db_name
      payload.username = form.value.db_username
      payload.password = form.value.db_password
    }
    const res = await fetch('/api/install/test-db', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload),
    })
    const result = await res.json()
    if (!res.ok || result.code !== 200) {
      throw new Error(result.message || t('install.dbConnectFailed'))
    }
    toast.success(result.data?.message || t('install.dbConnectSuccess'))
  }
  catch (error: any) {
    toast.error(error.message || t('install.dbConnectFailed'))
  }
  finally {
    testing.value = false
  }
}

function generateJwtSecret() {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  let result = ''
  for (let i = 0; i < 32; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length))
  }
  form.value.jwt_secret = result
}

const canProceed = computed(() => {
  if (step.value === 1) {
    if (form.value.db_type === 'sqlite') return true
    return form.value.db_host && form.value.db_port && form.value.db_name && form.value.db_username
  }
  if (step.value === 2) {
    return true
  }
  if (step.value === 3) {
    return form.value.admin_user && form.value.admin_pass && form.value.admin_pass.length >= 6
  }
  return true
})

async function handleInstall() {
  loading.value = true
  try {
    const payload: any = {
      db_type: form.value.db_type,
      jwt_secret: form.value.jwt_secret,
      admin_user: form.value.admin_user,
      admin_pass: form.value.admin_pass,
      admin_email: form.value.admin_email,
      use_redis: form.value.use_redis,
    }

    if (form.value.db_type === 'mysql') {
      payload.db_host = form.value.db_host
      payload.db_port = form.value.db_port
      payload.db_name = form.value.db_name
      payload.db_username = form.value.db_username
      payload.db_password = form.value.db_password
    }

    if (form.value.use_redis) {
      payload.redis_host = form.value.redis_host
      payload.redis_port = form.value.redis_port
      payload.redis_password = form.value.redis_password
      payload.redis_db = form.value.redis_db
    }

    const res = await fetch('/api/install/setup', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload),
    })
    const result = await res.json()
    if (!res.ok || result.code !== 200) {
      throw new Error(result.message || t('install.installFailed'))
    }
    toast.success(result.data?.message || t('install.installSuccess'))
    step.value = 4
  }
  catch (error: any) {
    toast.error(error.message || t('install.installFailed'))
  }
  finally {
    loading.value = false
  }
}

function goNext() {
  if (step.value < 3) {
    step.value++
  }
}

function goLogin() {
  localStorage.removeItem('token')
  localStorage.removeItem('user')
  resetInstallCheck()
  router.push('/login')
}

onMounted(() => {
  checkInstallStatus()
})
</script>

<template>
  <div class="min-h-screen flex items-center justify-center p-4 bg-gradient-to-br from-primary/5 via-background to-background">
    <div v-if="checkingStatus" class="flex items-center gap-2">
      <Loader2 class="size-5 animate-spin" />
      <span>{{ t('install.checkingStatus') }}</span>
    </div>

    <div v-else class="w-full max-w-2xl">
      <div class="text-center mb-8">
        <div class="flex items-center justify-center gap-3 mb-4">
          <div class="size-12 rounded-xl bg-primary flex items-center justify-center">
            <ShieldCheck class="size-7 text-primary-foreground" />
          </div>
        </div>
        <h1 class="text-2xl font-bold">
          {{ t('install.wizardTitle') }}
        </h1>
        <p class="text-muted-foreground mt-2">
          {{ t('install.wizardDesc') }}
        </p>
      </div>

      <div class="flex items-center justify-center gap-2 mb-8">
        <div
          v-for="s in 4"
          :key="s"
          class="flex items-center"
        >
          <div
            class="size-8 rounded-full flex items-center justify-center text-sm font-medium transition-colors"
            :class="step >= s ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'"
          >
            <Check v-if="step > s" class="size-4" />
            <span v-else>{{ s }}</span>
          </div>
          <div
            v-if="s < 4"
            class="w-12 h-0.5 mx-1"
            :class="step > s ? 'bg-primary' : 'bg-muted'"
          />
        </div>
      </div>

      <UiCard>
        <UiCardContent class="p-6">
          <div v-if="step === 1">
            <div class="flex items-center gap-2 mb-6">
              <Database class="size-5 text-primary" />
              <h2 class="text-lg font-semibold">{{ t('install.dbConfig') }}</h2>
            </div>

            <div class="space-y-4">
              <div class="space-y-3">
                <UiLabel>{{ t('install.dbType') }}</UiLabel>
                <div class="grid grid-cols-2 gap-3">
                  <button
                    v-for="db in dbTypes"
                    :key="db.value"
                    type="button"
                    class="p-4 rounded-lg border-2 text-left transition-all"
                    :class="form.db_type === db.value ? 'border-primary bg-primary/5' : 'border-border hover:border-primary/50'"
                    @click="form.db_type = db.value"
                  >
                    <div class="font-medium">{{ db.label }}</div>
                    <div class="text-sm text-muted-foreground">{{ db.desc }}</div>
                  </button>
                </div>
              </div>

              <template v-if="form.db_type === 'mysql'">
                <div class="grid grid-cols-2 gap-4">
                  <div class="space-y-2">
                    <UiLabel for="db_host">{{ t('install.dbHost') }}</UiLabel>
                    <UiInput id="db_host" v-model="form.db_host" placeholder="localhost" />
                  </div>
                  <div class="space-y-2">
                    <UiLabel for="db_port">{{ t('install.dbPort') }}</UiLabel>
                    <UiInput id="db_port" v-model="form.db_port" placeholder="3306" />
                  </div>
                </div>
                <div class="space-y-2">
                  <UiLabel for="db_name">{{ t('install.dbName') }}</UiLabel>
                  <UiInput id="db_name" v-model="form.db_name" placeholder="verification_platform" />
                </div>
                <div class="grid grid-cols-2 gap-4">
                  <div class="space-y-2">
                    <UiLabel for="db_username">{{ t('install.dbUsername') }}</UiLabel>
                    <UiInput id="db_username" v-model="form.db_username" placeholder="root" />
                  </div>
                  <div class="space-y-2">
                    <UiLabel for="db_password">{{ t('install.dbPassword') }}</UiLabel>
                    <UiInput id="db_password" v-model="form.db_password" type="password" placeholder="••••••••" />
                  </div>
                </div>
                <UiButton variant="outline" :disabled="testing" @click="testDatabase">
                  <Loader2 v-if="testing" class="mr-2 size-4 animate-spin" />
                  {{ t('install.testConnection') }}
                </UiButton>
              </template>
            </div>
          </div>

          <div v-else-if="step === 2">
            <div class="flex items-center gap-2 mb-6">
              <ShieldCheck class="size-5 text-primary" />
              <h2 class="text-lg font-semibold">{{ t('install.securityConfig') }}</h2>
            </div>

            <div class="space-y-4">
              <div class="space-y-2">
                <UiLabel for="jwt_secret">{{ t('install.jwtSecret') }}</UiLabel>
                <div class="flex gap-2">
                  <UiInput
                    id="jwt_secret"
                    v-model="form.jwt_secret"
                    :placeholder="t('install.jwtSecretPlaceholder')"
                    class="flex-1"
                  />
                  <UiButton variant="outline" @click="generateJwtSecret">
                    <RefreshCw class="size-4" />
                  </UiButton>
                </div>
                <p class="text-sm text-muted-foreground">
                  {{ t('install.jwtSecretHint') }}
                </p>
              </div>

              <div class="p-4 rounded-lg bg-muted/50">
                <div class="flex items-center gap-2 mb-2">
                  <Server class="size-4 text-muted-foreground" />
                  <span class="font-medium">{{ t('install.redisCache') }}</span>
                </div>
                <div class="flex items-center gap-2 mb-3">
                  <UiCheckbox id="use_redis" v-model:checked="form.use_redis" />
                  <UiLabel for="use_redis" class="text-sm font-normal cursor-pointer">{{ t('install.enableRedis') }}</UiLabel>
                </div>
                <template v-if="form.use_redis">
                  <div class="grid grid-cols-2 gap-3">
                    <div class="space-y-2">
                      <UiLabel for="redis_host">{{ t('install.redisHost') }}</UiLabel>
                      <UiInput id="redis_host" v-model="form.redis_host" placeholder="localhost" />
                    </div>
                    <div class="space-y-2">
                      <UiLabel for="redis_port">{{ t('install.redisPort') }}</UiLabel>
                      <UiInput id="redis_port" v-model="form.redis_port" placeholder="6379" />
                    </div>
                  </div>
                  <div class="mt-3 space-y-2">
                    <UiLabel for="redis_password">{{ t('install.redisPassword') }}</UiLabel>
                    <UiInput id="redis_password" v-model="form.redis_password" type="password" :placeholder="t('install.redisPasswordPlaceholder')" />
                  </div>
                </template>
              </div>
            </div>
          </div>

          <div v-else-if="step === 3">
            <div class="flex items-center gap-2 mb-6">
              <User class="size-5 text-primary" />
              <h2 class="text-lg font-semibold">{{ t('install.adminAccount') }}</h2>
            </div>

            <div class="space-y-4">
              <div class="space-y-2">
                <UiLabel for="admin_user">{{ t('install.adminUser') }}</UiLabel>
                <UiInput id="admin_user" v-model="form.admin_user" placeholder="admin" />
              </div>
              <div class="space-y-2">
                <UiLabel for="admin_pass">{{ t('install.adminPass') }}</UiLabel>
                <UiInput id="admin_pass" v-model="form.admin_pass" type="password" :placeholder="t('install.adminPassPlaceholder')" />
                <p v-if="form.admin_pass && form.admin_pass.length < 6" class="text-sm text-destructive">
                  {{ t('install.adminPassMinLength') }}
                </p>
              </div>
              <div class="space-y-2">
                <UiLabel for="admin_email">{{ t('install.adminEmail') }}</UiLabel>
                <UiInput id="admin_email" v-model="form.admin_email" type="email" placeholder="admin@example.com" />
              </div>
            </div>
          </div>

          <div v-else-if="step === 4">
            <div class="text-center py-8">
              <div class="size-16 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center mx-auto mb-4">
                <Check class="size-8 text-green-600 dark:text-green-400" />
              </div>
              <h2 class="text-xl font-semibold mb-2">{{ t('install.installComplete') }}</h2>
              <p class="text-muted-foreground mb-6">
                {{ t('install.installCompleteDesc') }}
              </p>
              <UiButton @click="goLogin">
                {{ t('install.goToLogin') }}
                <ChevronRight class="ml-2 size-4" />
              </UiButton>
            </div>
          </div>
        </UiCardContent>

        <UiCardFooter v-if="step < 4" class="flex justify-between border-t p-6">
          <UiButton
            v-if="step > 1"
            variant="outline"
            @click="step--"
          >
            {{ t('install.prevStep') }}
          </UiButton>
          <div v-else />

          <UiButton
            v-if="step < 3"
            :disabled="!canProceed"
            @click="goNext"
          >
            {{ t('install.nextStep') }}
            <ChevronRight class="ml-2 size-4" />
          </UiButton>
          <UiButton
            v-else
            :disabled="!canProceed || loading"
            @click="handleInstall"
          >
            <Loader2 v-if="loading" class="mr-2 size-4 animate-spin" />
            {{ loading ? t('install.installing') : t('install.startInstall') }}
          </UiButton>
        </UiCardFooter>
      </UiCard>
    </div>
  </div>
</template>
