<script setup lang="ts">
import type { FormSubmitEvent, FormError } from '@nuxt/ui'
import type { UserFormState } from '../../../types'
import type { AuthUser } from '../../../types/auth'

const { session, user, fetchSession } = useAuth()

const { t } = useI18n()
const localePath = useLocalePath()
const log = useLogger('Account')
const selectedFile = ref<File | null>(null)
const isUpdating = ref(false)

// Form state based on user schema fields
const state = reactive<UserFormState>({
  name: user.value?.name || '',
  image: user.value?.image || ''
})

watch(() => user.value, (user) => {
  // Don't update form state if we're currently updating (to prevent overwriting user changes)
  if (isUpdating.value) return
  if (user) {
    state.name = user.name || ''
    state.image = user.image || ''
  }
}, { deep: true })

// Simple validation function
const validate = (formState: UserFormState): FormError[] => {
  const errors: FormError[] = []
  if (!formState.name) errors.push({ name: 'name', message: t('validation.required') })
  return errors
}

const { cardStatus, showStatus } = useCardStatus()

const uploadAvatar = async () => {
  try {
    if (!selectedFile.value) return ''
    showStatus(t('account.status.uploadingAvatar'), '', 'primary', useSolarIcon('upload'))
    const formData = new FormData()
    formData.append('image', selectedFile.value)
    const apiCall = useApiCall()
    const fileUrl = await apiCall('/api/upload-image', {
      method: 'POST',
      body: formData
    }) as { url: string }
    showStatus(t('account.status.avatarUploaded'), '', 'success', useSolarIcon('check-circle'))
    return fileUrl.url
  } catch (error: Error | unknown) {
    log.error('Failed to upload avatar:', error)
    showStatus(t('account.status.uploadFailed'), (error as Error).message, 'error', useSolarIcon('x-circle'))
    throw new Error('Failed to upload avatar')
  }
}

const handleFileSelected = (file: File | null) => {
  selectedFile.value = file
  if (!file) {
    state.image = ''
  }
}

async function onSubmit(event: FormSubmitEvent<UserFormState>): Promise<void> {
  let filePath = ''

  if (selectedFile.value) {
    filePath = await uploadAvatar()
  } else if (state.image) {
    filePath = state.image
  } else {
    filePath = `https://api.dicebear.com/9.x/glass/svg?seed=${event.data.name}`
  }

  const userData = {
    ...event.data,
    image: filePath
  }
  try {
    isUpdating.value = true
    // Call the API to update user details
    showStatus(t('account.status.savingProfile'), '', 'primary', useSolarIcon('menu-dots'))
    const apiCall = useApiCall()
    const updatedUser = await apiCall<{
      id: string
      name: string
      email: string
      image: string | null
      emailVerified: boolean
      updatedAt: Date
    }>('/api/user/profile', {
      method: 'PUT',
      body: {
        name: userData.name,
        image: userData.image || null
      }
    })

    // Update form state immediately with the response data
    state.name = updatedUser.name
    state.image = updatedUser.image || ''

    // Update the local user state directly to avoid Better Auth's cache
    // This ensures the form doesn't get reset with stale cached data
    // Access the internal userState ref for mutation
    const userState = useState<AuthUser | null>('auth:user', () => null)
    if (userState.value) {
      userState.value.name = updatedUser.name
      userState.value.image = updatedUser.image
    }

    // If we get here, the update was successful
    showStatus(t('account.status.profileSaved'), '', 'success', useSolarIcon('check-circle'))

    // Trigger a session refresh from the server after a short delay
    // This allows Better Auth's cache to expire and ensures the session is updated
    // We do this in the background so it doesn't block the UI
    setTimeout(async () => {
      try {
        await fetchSession()
      } catch (error) {
        log.error('Failed to refresh session:', error)
      }
    }, 1000)
  } catch (error: unknown) {
    log.error('Error updating user profile:', error)

    // Handle specific error messages from the API
    let errorMessage = t('account.updateErrorDescription')

    if (error && typeof error === 'object' && 'statusCode' in error) {
      if (error.statusCode === 409) {
        errorMessage = t('account.emailAlreadyTaken')
      } else if (error.statusCode === 400) {
        errorMessage = (error as { statusMessage?: string }).statusMessage || t('account.invalidData')
      }
    }
    showStatus(t('account.status.updateFailed'), errorMessage, 'error')
  } finally {
    isUpdating.value = false
  }
}
</script>

<template>
  <NuxtLayout
    :page-title="t('account.profile')"
    :parent="{
      label: t('account.title'),
      to: localePath('/dashboard/account')
    }"
    name="dashboard"
    type="account"
  >
    <UPageBody>
      <!-- Email Verification Banner -->
      <AccountEmailVerificationBanner />

      <UForm
        :state="state"
        :validate="validate"
        class="space-y-6"
        @submit="onSubmit"
      >
        <PageMainCard
          v-model:status="cardStatus"
          :title="t('account.editProfile')"
          :description="t('account.editProfileDescription')"
          :icon="useSolarIcon('user')"
          :loading="isUpdating"
          :show-refresh-button="false"
          @update:status="cardStatus = $event"
        >
          <UFormField
            label="Avatar"
            name="avatar"
          >
            <FormAvatarUploader
              v-model="state.image"
              @file-selected="handleFileSelected"
            />
          </UFormField>

          <!-- Name -->
          <UFormField
            :label="t('account.name')"
            name="name"
            required
          >
            <UInput
              v-model="state.name"
              :placeholder="t('account.namePlaceholder')"
              :icon="useSolarIcon('user')"
            />
          </UFormField>

          <UFormField :label="t('account.email')">
            <span class="ml-2 flex items-center gap-2 text-gray-500 h-6">
              <UIcon :name="useSolarIcon('letter')" />
              {{ user?.email }}
              <UBadge
                :color="user?.emailVerified ? 'success' : 'warning'"
                variant="soft"
              >
                {{ user?.emailVerified ? t('account.verified') : t('account.unverified') }}
              </UBadge>
            </span>
          </UFormField>
          <template #footer-actions>
            <div>
              <UButton
                color="neutral"
                variant="outline"
                @click="() => {
                  const user = (session as any)?.data?.user
                  if (user) {
                    state.name = user.name || ''
                    state.image = user.image || ''
                  }
                }"
              >
                {{ t('common.reset') }}
              </UButton>
            </div>
            <div>
              <UButton
                type="submit"
                loading-auto
                :icon="useSolarIcon('check-circle')"
              >
                {{ t('common.save') }}
              </UButton>
            </div>
          </template>
        </PageMainCard>
      </UForm>
    </UPageBody>
  </NuxtLayout>
</template>
