<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, locale, setLocale } = useI18n()
const log = useLogger('Account')
const selectedFile = ref<File | null>(null)
const isUpdating = ref(false)

// Language options
const languageOptions: { value: 'en' | 'nl', label: string, icon: string }[] = [
  { value: 'en', label: 'English', icon: 'i-circle-flags-en' },
  { value: 'nl', label: 'Nederlands', icon: 'i-circle-flags-nl' }
]

// Timezone options - common timezones
const timezoneOptions = [
  { value: 'Europe/Amsterdam', label: 'Europe/Amsterdam (CET)' },
  { value: 'Europe/London', label: 'Europe/London (GMT)' },
  { value: 'Europe/Paris', label: 'Europe/Paris (CET)' },
  { value: 'Europe/Berlin', label: 'Europe/Berlin (CET)' },
  { value: 'Europe/Brussels', label: 'Europe/Brussels (CET)' },
  { value: 'Europe/Madrid', label: 'Europe/Madrid (CET)' },
  { value: 'Europe/Rome', label: 'Europe/Rome (CET)' },
  { value: 'Europe/Stockholm', label: 'Europe/Stockholm (CET)' },
  { value: 'Europe/Oslo', label: 'Europe/Oslo (CET)' },
  { value: 'Europe/Copenhagen', label: 'Europe/Copenhagen (CET)' },
  { value: 'Europe/Helsinki', label: 'Europe/Helsinki (EET)' },
  { value: 'Europe/Athens', label: 'Europe/Athens (EET)' },
  { value: 'Europe/Moscow', label: 'Europe/Moscow (MSK)' },
  { value: 'America/New_York', label: 'America/New York (EST)' },
  { value: 'America/Chicago', label: 'America/Chicago (CST)' },
  { value: 'America/Denver', label: 'America/Denver (MST)' },
  { value: 'America/Los_Angeles', label: 'America/Los Angeles (PST)' },
  { value: 'America/Toronto', label: 'America/Toronto (EST)' },
  { value: 'America/Vancouver', label: 'America/Vancouver (PST)' },
  { value: 'America/Sao_Paulo', label: 'America/São Paulo (BRT)' },
  { value: 'Asia/Tokyo', label: 'Asia/Tokyo (JST)' },
  { value: 'Asia/Shanghai', label: 'Asia/Shanghai (CST)' },
  { value: 'Asia/Hong_Kong', label: 'Asia/Hong Kong (HKT)' },
  { value: 'Asia/Singapore', label: 'Asia/Singapore (SGT)' },
  { value: 'Asia/Seoul', label: 'Asia/Seoul (KST)' },
  { value: 'Asia/Dubai', label: 'Asia/Dubai (GST)' },
  { value: 'Asia/Kolkata', label: 'Asia/Kolkata (IST)' },
  { value: 'Australia/Sydney', label: 'Australia/Sydney (AEST)' },
  { value: 'Australia/Melbourne', label: 'Australia/Melbourne (AEST)' },
  { value: 'Australia/Perth', label: 'Australia/Perth (AWST)' },
  { value: 'Pacific/Auckland', label: 'Pacific/Auckland (NZST)' },
  { value: 'UTC', label: 'UTC (Coordinated Universal Time)' }
]

// Extended form state including preferences
interface ProfileFormState extends UserFormState {
  preferredLanguage: string
  timezone: string | undefined
}

const state = reactive<ProfileFormState>({
  name: user.value?.name || '',
  image: user.value?.image || '',
  preferredLanguage: locale.value,
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || undefined
})

// Handle language change - immediately switch locale for better UX
async function onLanguageSelect(langCode: 'en' | 'nl') {
  state.preferredLanguage = langCode
  await setLocale(langCode)
}

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<ProfileFormState>): 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}`
  }

  try {
    isUpdating.value = true
    // Call the API to update user details including preferences
    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
      preferredLanguage: string | null
      timezone: string | null
      updatedAt: Date
    }>('/api/user/profile', {
      method: 'PUT',
      body: {
        name: event.data.name,
        image: filePath || null,
        preferredLanguage: event.data.preferredLanguage,
        timezone: event.data.timezone
      }
    })

    // Update form state immediately with the response data
    state.name = updatedUser.name
    state.image = updatedUser.image || ''
    if (updatedUser.preferredLanguage) {
      state.preferredLanguage = updatedUser.preferredLanguage
    }
    if (updatedUser.timezone) {
      state.timezone = updatedUser.timezone
    } else {
      state.timezone = undefined
    }

    // 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.title')"
    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>

          <!-- Preferences Section -->
          <USeparator class="my-6" />

          <!-- Language -->
          <UFormField
            :label="t('account.preferences.language')"
            :help="t('account.preferences.languageHelp')"
            name="preferredLanguage"
          >
            <div class="flex gap-3">
              <UButton
                v-for="lang in languageOptions"
                :key="lang.value"
                :icon="lang.icon"
                :variant="state.preferredLanguage === lang.value ? 'subtle' : 'ghost'"
                @click="onLanguageSelect(lang.value)"
              >
                {{ lang.label }}
              </UButton>
            </div>
          </UFormField>

          <!-- Timezone -->
          <UFormField
            :label="t('account.preferences.timezone')"
            :help="t('account.preferences.timezoneHelp')"
            name="timezone"
          >
            <USelectMenu
              v-model="state.timezone"
              :items="timezoneOptions"
              :placeholder="t('account.preferences.timezonePlaceholder')"
              value-key="value"
              :search-input="{ placeholder: t('account.preferences.timezoneSearch') }"
            />
          </UFormField>

          <template #footer-actions>
            <div>
              <UButton
                color="neutral"
                variant="outline"
                @click="() => {
                  const userData = (session as any)?.data?.user
                  if (userData) {
                    state.name = userData.name || ''
                    state.image = userData.image || ''
                  }
                  state.preferredLanguage = locale
                  state.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || undefined
                }"
              >
                {{ 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>
