/**
 * Sync Service for Anonymous Auth & Data Sync
 * Handles opt-in personalization for premium users
 */

import { logger } from '../utils/logger'

import { supabase } from '@/src/shared/supabase'
import type {
  UserProfileData,
  WorkoutSessionData,
  SyncState,
  EnableSyncResult,
  SyncWorkoutResult,
  DeleteDataResult,
} from '@/src/shared/types'

/**
 * Enable sync by creating anonymous user and syncing all data
 * Called when user accepts sync after first workout
 */
export async function enableSync(
  profileData: UserProfileData,
  workoutHistory: WorkoutSessionData[]
): Promise<EnableSyncResult> {
  try {
    // 1. Create anonymous user
    const { data: authData, error: authError } =
      await supabase.auth.signInAnonymously()
    if (authError) throw authError
    if (!authData.user) throw new Error('Failed to create anonymous user')

    const userId = authData.user.id

    // 2. Create user profile in Supabase
    const { error: profileError } = await (supabase as any)
      .from('user_profiles')
      .insert({
        id: userId,
        name: profileData.name,
        fitness_level: profileData.fitnessLevel,
        goal: profileData.goal,
        weekly_frequency: profileData.weeklyFrequency,
        barriers: profileData.barriers,
        is_anonymous: true,
        sync_enabled: true,
        subscription_plan: 'premium-yearly',
        onboarding_completed_at: profileData.onboardingCompletedAt,
      })
    if (profileError) throw profileError

    // 3. Sync all workout history retroactively
    if (workoutHistory.length > 0) {
      const { error: historyError } = await (supabase as any)
        .from('workout_sessions')
        .insert(
          workoutHistory.map((session) => ({
            user_id: userId,
            workout_id: session.workoutId,
            completed_at: session.completedAt,
            duration_seconds: session.durationSeconds,
            calories_burned: session.caloriesBurned,
            feeling_rating: session.feelingRating,
          }))
        )
      if (historyError) throw historyError
    }

    // 4. Initialize default preferences
    const { error: prefError } = await (supabase as any)
      .from('user_preferences')
      .insert({
        user_id: userId,
        preferred_categories: [],
        preferred_trainers: [],
        preferred_durations: [],
        difficulty_preference: 'matched',
      })
    if (prefError) throw prefError

    return { success: true, userId }
  } catch (error) {
    logger.error('Failed to enable sync:', error)
    return {
      success: false,
      error: error instanceof Error ? error.message : 'Unknown error',
    }
  }
}

/**
 * Sync a single workout session (called after each workout completion)
 */
export async function syncWorkoutSession(
  session: WorkoutSessionData
): Promise<SyncWorkoutResult> {
  try {
    const {
      data: { user },
    } = await supabase.auth.getUser()
    if (!user) return { success: false, error: 'No authenticated user' }

    const { error } = await (supabase.from('workout_sessions') as any).insert({
      user_id: user.id,
      workout_id: session.workoutId,
      completed_at: session.completedAt,
      duration_seconds: session.durationSeconds,
      calories_burned: session.caloriesBurned,
      feeling_rating: session.feelingRating,
    })

    if (error) throw error
    return { success: true }
  } catch (error) {
    logger.error('Failed to sync workout:', error)
    return {
      success: false,
      error: error instanceof Error ? error.message : 'Unknown error',
    }
  }
}

/**
 * Delete all synced data from Supabase (keep local)
 * User becomes "unsynced" - can opt-in again later
 */
export async function deleteSyncedData(): Promise<DeleteDataResult> {
  try {
    const {
      data: { user },
    } = await supabase.auth.getUser()
    if (!user) return { success: false, error: 'No authenticated user' }

    // Note: Deleting the user will cascade delete all related data
    // due to ON DELETE CASCADE in the schema
    // However, supabase.auth.admin.deleteUser requires admin privileges
    // Instead, we'll delete from our tables manually

    // Delete user's preferences
    const { error: prefError } = await supabase
      .from('user_preferences')
      .delete()
      .eq('user_id', user.id)
    if (prefError) throw prefError

    // Delete user's workout sessions
    const { error: sessionsError } = await supabase
      .from('workout_sessions')
      .delete()
      .eq('user_id', user.id)
    if (sessionsError) throw sessionsError

    // Delete user's profile
    const { error: profileError } = await supabase
      .from('user_profiles')
      .delete()
      .eq('id', user.id)
    if (profileError) throw profileError

    // Sign out locally
    await supabase.auth.signOut()

    return { success: true }
  } catch (error) {
    logger.error('Failed to delete synced data:', error)
    return {
      success: false,
      error: error instanceof Error ? error.message : 'Unknown error',
    }
  }
}

/**
 * Get current sync state
 */
export async function getSyncState(): Promise<SyncState> {
  const { data: session } = await supabase.auth.getSession()

  if (!session.session?.user) {
    return {
      status: 'never-synced',
      userId: null,
      lastSyncAt: null,
      pendingWorkouts: 0,
    }
  }

  const userId = session.session.user.id

  // Get latest workout session to determine last sync
  const { data: latestSession } = await supabase
    .from('workout_sessions')
    .select('created_at')
    .eq('user_id', userId)
    .order('created_at', { ascending: false })
    .limit(1)

  return {
    status: 'synced',
    userId: userId,
    lastSyncAt: (latestSession as any)?.[0]?.created_at || null,
    pendingWorkouts: 0,
  }
}

/**
 * Check if user has synced data (for determining if we can show personalized features)
 */
export async function hasSyncedData(): Promise<boolean> {
  const { data: session } = await supabase.auth.getSession()
  return !!session.session?.user
}

/**
 * Check if user is currently authenticated with Supabase
 */
export async function isAuthenticated(): Promise<boolean> {
  const { data: session } = await supabase.auth.getSession()
  return !!session.session?.user
}
