<script setup lang="ts">
/**
 * User profile page.
 *
 * Displays user info including avatar, editable display name, linked OAuth
 * accounts, and logout options. Users can link additional OAuth providers
 * and unlink existing ones (except the last one).
 */
import { onMounted, computed } from 'vue'

import { useProfile } from '@/composables/useProfile'
import { useAuth } from '@/composables/useAuth'
import { useUiStore } from '@/stores/ui'
import LinkedAccountCard from '@/components/profile/LinkedAccountCard.vue'
import DisplayNameEditor from '@/components/profile/DisplayNameEditor.vue'
import type { OAuthProvider } from '@/composables/useProfile'

const ui = useUiStore()
const {
  profile,
  displayName,
  avatarUrl,
  linkedAccounts,
  sessionCount,
  isLoading,
  isUpdatingName,
  isLoadingUnlink,
  error,
  fetchProfile,
  updateDisplayName,
  initiateLink,
  unlinkAccount,
  fetchSessionCount,
  isProviderLinked,
} = useProfile()

const { logout, logoutAll, isLoading: isLoggingOut } = useAuth()

/** Avatar display - either image or initial */
const avatarInitial = computed(() => {
  return displayName.value?.charAt(0).toUpperCase() || '?'
})

/** Check if there's only one linked account */
const hasOnlyOneAccount = computed(() => linkedAccounts.value.length <= 1)

/** Available providers that can be linked */
const availableProviders = computed(() => {
  const allProviders: OAuthProvider[] = ['google', 'discord']
  return allProviders.filter((p) => !isProviderLinked(p))
})

// Fetch profile data on mount
onMounted(async () => {
  await fetchProfile()
  await fetchSessionCount()
})

/** Handle display name save */
async function handleDisplayNameSave(newName: string): Promise<void> {
  const result = await updateDisplayName(newName)
  if (result.success) {
    ui.showSuccess('Display name updated')
  } else {
    ui.showError(result.error || 'Failed to update display name')
  }
}

/** Handle unlinking an account */
async function handleUnlink(provider: OAuthProvider): Promise<void> {
  const result = await unlinkAccount(provider)
  if (result.success) {
    ui.showSuccess(`${provider} account unlinked`)
  } else {
    ui.showError(result.error || 'Failed to unlink account')
  }
}

/** Handle logout (current session) */
async function handleLogout(): Promise<void> {
  await logout()
}

/** Handle logout all (all devices) */
async function handleLogoutAll(): Promise<void> {
  const confirmed = window.confirm(
    'This will log you out from all devices. Continue?'
  )
  if (confirmed) {
    await logoutAll()
  }
}
</script>

<template>
  <div class="p-4 md:p-6 max-w-2xl mx-auto">
    <h1 class="mb-6 text-2xl font-bold text-white">
      Profile
    </h1>

    <!-- Loading state -->
    <div
      v-if="isLoading && !profile"
      class="flex justify-center py-12"
    >
      <div class="animate-spin h-8 w-8 border-4 border-primary border-t-transparent rounded-full" />
    </div>

    <!-- Error state -->
    <div
      v-else-if="error && !profile"
      class="p-4 bg-red-900/20 border border-red-500 rounded-lg text-red-400"
    >
      {{ error }}
    </div>

    <!-- Profile content -->
    <div
      v-else
      class="space-y-8"
    >
      <!-- Avatar and Name Section -->
      <section class="bg-surface-dark rounded-lg p-6">
        <div class="flex items-start gap-6">
          <!-- Avatar -->
          <div class="flex-shrink-0">
            <div
              v-if="avatarUrl"
              class="h-20 w-20 rounded-full overflow-hidden ring-2 ring-primary/50"
            >
              <img
                :src="avatarUrl"
                :alt="displayName"
                class="h-full w-full object-cover"
              >
            </div>
            <div
              v-else
              class="h-20 w-20 rounded-full bg-primary/20 flex items-center justify-center text-3xl font-bold text-primary-light ring-2 ring-primary/50"
            >
              {{ avatarInitial }}
            </div>
          </div>

          <!-- Name editor -->
          <div class="flex-1 min-w-0">
            <DisplayNameEditor
              :model-value="displayName"
              :is-saving="isUpdatingName"
              @save="handleDisplayNameSave"
            />
            <p class="mt-2 text-sm text-gray-400">
              Member since {{ profile?.createdAt ? new Date(profile.createdAt).toLocaleDateString() : 'Unknown' }}
            </p>
          </div>
        </div>
      </section>

      <!-- Linked Accounts Section -->
      <section class="bg-surface-dark rounded-lg p-6">
        <h2 class="text-lg font-semibold text-white mb-4">
          Linked Accounts
        </h2>

        <div
          v-if="linkedAccounts.length > 0"
          class="space-y-3"
        >
          <LinkedAccountCard
            v-for="account in linkedAccounts"
            :key="account.provider"
            :account="account"
            :is-only-account="hasOnlyOneAccount"
            :is-unlinking="isLoadingUnlink"
            @unlink="handleUnlink"
          />
        </div>
        <p
          v-else
          class="text-gray-400"
        >
          No linked accounts
        </p>

        <!-- Link additional provider buttons -->
        <div
          v-if="availableProviders.length > 0"
          class="mt-4 pt-4 border-t border-gray-700"
        >
          <p class="text-sm text-gray-400 mb-3">
            Link additional accounts:
          </p>
          <div class="flex flex-wrap gap-2">
            <button
              v-for="provider in availableProviders"
              :key="provider"
              class="px-4 py-2 rounded-lg transition-colors"
              :class="[
                provider === 'google'
                  ? 'bg-blue-600 hover:bg-blue-700'
                  : 'bg-indigo-600 hover:bg-indigo-700'
              ]"
              @click="initiateLink(provider)"
            >
              <span class="mr-2">{{ provider === 'google' ? '🔵' : '🟣' }}</span>
              Link {{ provider === 'google' ? 'Google' : 'Discord' }}
            </button>
          </div>
        </div>
      </section>

      <!-- Session Info Section -->
      <section class="bg-surface-dark rounded-lg p-6">
        <h2 class="text-lg font-semibold text-white mb-4">
          Sessions
        </h2>

        <p
          v-if="sessionCount !== null"
          class="text-gray-400"
        >
          You have <span class="text-white font-medium">{{ sessionCount }}</span> active session{{ sessionCount === 1 ? '' : 's' }}.
        </p>
        <p
          v-else
          class="text-gray-400"
        >
          Session information unavailable
        </p>
      </section>

      <!-- Logout Section -->
      <section class="bg-surface-dark rounded-lg p-6">
        <h2 class="text-lg font-semibold text-white mb-4">
          Account Actions
        </h2>

        <div class="flex flex-col sm:flex-row gap-3">
          <button
            class="flex-1 px-4 py-3 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
            :disabled="isLoggingOut"
            @click="handleLogout"
          >
            <span v-if="isLoggingOut">Logging out...</span>
            <span v-else>Logout</span>
          </button>

          <button
            class="flex-1 px-4 py-3 bg-red-900 text-red-200 rounded-lg hover:bg-red-800 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
            :disabled="isLoggingOut"
            @click="handleLogoutAll"
          >
            Logout All Devices
          </button>
        </div>

        <p class="mt-3 text-xs text-gray-500">
          "Logout" ends this session. "Logout All Devices" revokes all active sessions.
        </p>
      </section>
    </div>
  </div>
</template>
