<script setup lang="ts">
import { Camera, Check, Copy, Eye, EyeOff, Key, Loader2, Mail, RefreshCw, Shield, User } from 'lucide-vue-next'
import { computed, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { toast } from 'vue-sonner'

import { BasicPage } from '@/components/global-layout'
import api from '@/services/api'

const { t } = useI18n()

interface UserProfile {
  id: number
  username: string
  email: string
  phone: string
  avatar: string
  role: string
  status: string
  api_token: string
  created_at: string
  last_login_at: string
}

const loading = ref(true)
const saving = ref(false)
const changingPassword = ref(false)
const user = ref<UserProfile | null>(null)

const profileForm = ref({
  username: '',
  email: '',
  phone: '',
})

const passwordForm = ref({
  currentPassword: '',
  newPassword: '',
  confirmPassword: '',
})

const avatarInputRef = ref<HTMLInputElement | null>(null)
const avatarPreview = ref<string | null>(null)
const uploadingAvatar = ref(false)
const showPasswordDialog = ref(false)
const showApiToken = ref(false)
const regeneratingToken = ref(false)

const isPasswordFormValid = computed(() => {
  return passwordForm.value.currentPassword
    && passwordForm.value.newPassword
    && passwordForm.value.confirmPassword
    && passwordForm.value.newPassword === passwordForm.value.confirmPassword
})

const roleLabel = computed(() => {
  const roles: Record<string, string> = {
    admin: t('profile.roleAdmin'),
    agent: t('profile.roleAgent'),
  }
  return roles[user.value?.role || ''] || user.value?.role || '-'
})

async function fetchProfile() {
  loading.value = true
  try {
    const data = await api.get<{ user: UserProfile }>('/dev/profile')
    user.value = data?.user || data

    if (user.value) {
      profileForm.value = {
        username: user.value.username,
        email: user.value.email || '',
        phone: user.value.phone || '',
      }
      if (user.value.avatar) {
        avatarPreview.value = user.value.avatar
      }
    }
  }
  catch {
    toast.error(t('profile.loadUserFailed'))
  }
  finally {
    loading.value = false
  }
}

async function handleUpdateProfile() {
  if (!profileForm.value.username || !profileForm.value.email) {
    toast.error(t('profile.fillComplete'))
    return
  }

  saving.value = true
  try {
    await api.put('/dev/profile', {
      username: profileForm.value.username,
      email: profileForm.value.email,
      phone: profileForm.value.phone,
    })
    toast.success(t('profile.profileUpdateSuccess'))

    if (user.value) {
      user.value.username = profileForm.value.username
      user.value.email = profileForm.value.email
      user.value.phone = profileForm.value.phone
      localStorage.setItem('user', JSON.stringify(user.value))
    }
  }
  catch (error: any) {
    toast.error(error.message || t('profile.profileUpdateFailed'))
  }
  finally {
    saving.value = false
  }
}

async function handleChangePassword() {
  if (!passwordForm.value.currentPassword) {
    toast.error(t('profile.currentPasswordRequired'))
    return
  }
  if (!passwordForm.value.newPassword) {
    toast.error(t('profile.newPasswordRequired'))
    return
  }
  if (passwordForm.value.newPassword !== passwordForm.value.confirmPassword) {
    toast.error(t('profile.passwordMismatch'))
    return
  }
  if (passwordForm.value.newPassword.length < 6) {
    toast.error(t('profile.passwordMinLength'))
    return
  }

  changingPassword.value = true
  try {
    await api.put('/dev/profile/password', {
      current_password: passwordForm.value.currentPassword,
      new_password: passwordForm.value.newPassword,
    })
    toast.success(t('profile.passwordChangeSuccess'))
    showPasswordDialog.value = false
    passwordForm.value = { currentPassword: '', newPassword: '', confirmPassword: '' }
  }
  catch (error: any) {
    toast.error(error.message || t('profile.passwordChangeFailed'))
  }
  finally {
    changingPassword.value = false
  }
}

function handleAvatarClick() {
  avatarInputRef.value?.click()
}

async function handleAvatarChange(event: Event) {
  const input = event.target as HTMLInputElement
  const file = input.files?.[0]
  if (!file) return

  if (!file.type.startsWith('image/')) {
    toast.error(t('profile.selectImageFile'))
    return
  }
  if (file.size > 2 * 1024 * 1024) {
    toast.error(t('profile.imageSizeExceeded'))
    return
  }

  const reader = new FileReader()
  reader.onload = (e) => {
    avatarPreview.value = e.target?.result as string
  }
  reader.readAsDataURL(file)

  uploadingAvatar.value = true
  try {
    const formData = new FormData()
    formData.append('avatar', file)
    const data = await api.postFormData<{ avatar: string }>('/dev/profile/avatar', formData)
    if (data?.avatar) {
      avatarPreview.value = data.avatar
      if (user.value) {
        user.value.avatar = data.avatar
        localStorage.setItem('user', JSON.stringify(user.value))
      }
      toast.success(t('profile.avatarUpdateSuccess'))
    }
  }
  catch (error: any) {
    toast.error(error.message || t('profile.avatarUpdateFailed'))
  }
  finally {
    uploadingAvatar.value = false
  }
}

async function handleRegenerateApiToken() {
  regeneratingToken.value = true
  try {
    const data = await api.post<{ api_token: string }>('/dev/profile/api-token')
    if (data?.api_token && user.value) {
      user.value.api_token = data.api_token
      toast.success(t('profile.tokenRegenerated'))
    }
  }
  catch (error: any) {
    toast.error(error.message || t('profile.tokenRegenerateFailed'))
  }
  finally {
    regeneratingToken.value = false
  }
}

function copyApiToken() {
  if (user.value?.api_token) {
    navigator.clipboard.writeText(user.value.api_token)
    toast.success(t('profile.tokenCopied'))
  }
}

function maskToken(token: string) {
  if (!token || token.length < 16) return token
  return `${token.slice(0, 8)}${'•'.repeat(24)}${token.slice(-8)}`
}

function formatDate(dateStr: string) {
  if (!dateStr) return '-'
  return new Date(dateStr).toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
  })
}

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

<template>
  <BasicPage
    :title="t('profile.title')"
    :description="t('profile.description')"
  >
    <div v-if="loading" class="flex items-center justify-center py-12">
      <Loader2 class="size-8 animate-spin text-muted-foreground" />
    </div>

    <div v-else class="grid gap-6 lg:grid-cols-3">
      <div class="lg:col-span-2 space-y-6">
        <UiCard>
          <UiCardHeader>
            <UiCardTitle class="flex items-center gap-2">
              <User class="size-5" />
              {{ t('profile.basicInfo') }}
            </UiCardTitle>
            <UiCardDescription>
              <span class="flex items-center gap-2 mt-1">
                <UiBadge variant="outline" class="gap-1">
                  <Shield class="size-3" />
                  {{ roleLabel }}
                </UiBadge>
                <span class="text-muted-foreground">{{ t('profile.joinedAt') }} {{ formatDate(user?.created_at || '') }}</span>
              </span>
            </UiCardDescription>
          </UiCardHeader>
          <UiCardContent class="space-y-6">
            <div class="flex items-start gap-6">
              <div class="relative shrink-0">
                <div
                  class="size-24 rounded-full bg-muted flex items-center justify-center overflow-hidden cursor-pointer group border"
                  @click="handleAvatarClick"
                >
                  <img
                    v-if="avatarPreview"
                    :src="avatarPreview"
                    alt="Avatar"
                    class="size-full object-cover"
                  >
                  <User v-else class="size-10 text-muted-foreground" />
                  <div class="absolute inset-0 bg-black/50 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity rounded-full">
                    <Camera class="size-6 text-white" />
                  </div>
                </div>
                <div
                  v-if="uploadingAvatar"
                  class="absolute inset-0 rounded-full bg-black/50 flex items-center justify-center"
                >
                  <Loader2 class="size-6 animate-spin text-white" />
                </div>
              </div>
              <input
                ref="avatarInputRef"
                type="file"
                accept="image/*"
                class="hidden"
                @change="handleAvatarChange"
              >

              <div class="flex-1 grid gap-4 sm:grid-cols-2">
                <div class="space-y-2">
                  <UiLabel for="username">{{ t('profile.username') }}</UiLabel>
                  <UiInput
                    id="username"
                    v-model="profileForm.username"
                    :placeholder="t('profile.usernamePlaceholder')"
                  />
                </div>
                <div class="space-y-2">
                  <UiLabel for="email">{{ t('profile.email') }}</UiLabel>
                  <UiInput
                    id="email"
                    v-model="profileForm.email"
                    type="email"
                    :placeholder="t('profile.emailPlaceholder')"
                  />
                </div>
                <div class="space-y-2">
                  <UiLabel for="phone">{{ t('profile.phone') }}</UiLabel>
                  <UiInput
                    id="phone"
                    v-model="profileForm.phone"
                    type="tel"
                    :placeholder="t('profile.phonePlaceholder')"
                  />
                </div>
                <div class="flex items-end gap-2">
                  <UiButton
                    :disabled="saving"
                    @click="handleUpdateProfile"
                  >
                    <Loader2 v-if="saving" class="mr-2 h-4 w-4 animate-spin" />
                    <Check v-else class="mr-2 h-4 w-4" />
                    {{ t('profile.saveChanges') }}
                  </UiButton>
                  <UiButton variant="outline" @click="showPasswordDialog = true">
                    <Key class="mr-2 h-4 w-4" />
                    {{ t('profile.changePassword') }}
                  </UiButton>
                </div>
              </div>
            </div>
          </UiCardContent>
        </UiCard>

        <UiCard>
          <UiCardHeader>
            <UiCardTitle class="flex items-center gap-2">
              <Key class="size-5" />
              API Token
            </UiCardTitle>
            <UiCardDescription>{{ t('profile.apiTokenDesc') }}</UiCardDescription>
          </UiCardHeader>
          <UiCardContent class="space-y-4">
            <div class="flex items-center gap-2">
              <code class="flex-1 p-3 bg-muted rounded-lg text-sm font-mono break-all border">
                {{ showApiToken ? user?.api_token : maskToken(user?.api_token || '') }}
              </code>
              <UiButton variant="outline" size="icon" @click="showApiToken = !showApiToken">
                <EyeOff v-if="showApiToken" class="size-4" />
                <Eye v-else class="size-4" />
              </UiButton>
              <UiButton variant="outline" size="icon" :disabled="!user?.api_token" @click="copyApiToken">
                <Copy class="size-4" />
              </UiButton>
            </div>
            <UiButton
              variant="outline"
              size="sm"
              :disabled="regeneratingToken"
              @click="handleRegenerateApiToken"
            >
              <Loader2 v-if="regeneratingToken" class="mr-2 h-4 w-4 animate-spin" />
              <RefreshCw v-else class="mr-2 h-4 w-4" />
              {{ user?.api_token ? t('profile.regenerateToken') : t('profile.generateToken') }}
            </UiButton>
          </UiCardContent>
        </UiCard>
      </div>

      <div class="space-y-6">
        <UiCard>
          <UiCardHeader>
            <UiCardTitle class="flex items-center gap-2">
              <Shield class="size-5" />
              {{ t('profile.accountOverview') }}
            </UiCardTitle>
          </UiCardHeader>
          <UiCardContent>
            <div class="space-y-4">
              <div class="flex items-center justify-between py-2">
                <span class="text-sm text-muted-foreground">{{ t('profile.accountType') }}</span>
                <UiBadge variant="outline">{{ roleLabel }}</UiBadge>
              </div>
              <div class="flex items-center justify-between py-2 border-t">
                <span class="text-sm text-muted-foreground">{{ t('profile.accountStatus') }}</span>
                <UiBadge :class="user?.status === 'active' ? 'bg-green-500/10 text-green-500' : ''" variant="outline">
                  {{ user?.status === 'active' ? t('profile.statusActive') : user?.status }}
                </UiBadge>
              </div>
              <div class="flex items-center justify-between py-2 border-t">
                <span class="text-sm text-muted-foreground">{{ t('profile.email') }}</span>
                <span class="text-sm font-medium flex items-center gap-1">
                  <Mail class="size-3.5 text-muted-foreground" />
                  {{ user?.email || '-' }}
                </span>
              </div>
              <div v-if="user?.last_login_at" class="flex items-center justify-between py-2 border-t">
                <span class="text-sm text-muted-foreground">{{ t('profile.lastLogin') }}</span>
                <span class="text-sm font-medium">{{ formatDate(user.last_login_at) }}</span>
              </div>
            </div>
          </UiCardContent>
        </UiCard>
      </div>
    </div>

    <UiDialog v-model:open="showPasswordDialog">
      <UiDialogContent class="sm:max-w-md">
        <UiDialogHeader>
          <UiDialogTitle>{{ t('profile.changePassword') }}</UiDialogTitle>
          <UiDialogDescription>{{ t('profile.changePasswordDesc') }}</UiDialogDescription>
        </UiDialogHeader>
        <div class="space-y-4 py-4">
          <div class="space-y-2">
            <UiLabel for="currentPassword">{{ t('profile.currentPassword') }}</UiLabel>
            <UiInput
              id="currentPassword"
              v-model="passwordForm.currentPassword"
              type="password"
              :placeholder="t('profile.currentPasswordPlaceholder')"
            />
          </div>
          <div class="space-y-2">
            <UiLabel for="newPassword">{{ t('profile.newPassword') }}</UiLabel>
            <UiInput
              id="newPassword"
              v-model="passwordForm.newPassword"
              type="password"
              :placeholder="t('profile.newPasswordPlaceholder')"
            />
          </div>
          <div class="space-y-2">
            <UiLabel for="confirmPassword">{{ t('profile.confirmPassword') }}</UiLabel>
            <UiInput
              id="confirmPassword"
              v-model="passwordForm.confirmPassword"
              type="password"
              :placeholder="t('profile.confirmPasswordPlaceholder')"
            />
          </div>
        </div>
        <UiDialogFooter>
          <UiButton variant="outline" @click="showPasswordDialog = false">
            {{ t('profile.cancel') }}
          </UiButton>
          <UiButton :disabled="changingPassword || !isPasswordFormValid" @click="handleChangePassword">
            <Loader2 v-if="changingPassword" class="mr-2 h-4 w-4 animate-spin" />
            {{ t('profile.confirmChange') }}
          </UiButton>
        </UiDialogFooter>
      </UiDialogContent>
    </UiDialog>
  </BasicPage>
</template>
