/**
 * VAPI Setup Helper
 *
 * Provides high-level functions for setting up VAPI resources
 * when stores are created and updating them when AI config changes.
 */

import { SupabaseClient } from 'https://esm.sh/@supabase/supabase-js@2'
import {
  registerPhoneNumber,
  createAssistant,
  updateAssistant,
  isVapiConfigured,
  VapiAssistantConfig
} from './vapi-client.ts'

export interface VapiSetupResult {
  success: boolean
  vapiPhoneNumberId?: string
  vapiAssistantId?: string
  error?: string
}

export interface VapiUpdateResult {
  success: boolean
  error?: string
}

/**
 * Default greeting message template
 */
function getDefaultGreetingMessage(storeName: string): string {
  return `Üdvözlöm! A ${storeName} ügyfélszolgálata vagyok. Miben segíthetek?`
}

/**
 * Pick a random enabled voice from the ai_voices table
 */
async function pickRandomVoice(
  supabase: SupabaseClient
): Promise<{ voiceId: string } | null> {
  const { data: voices, error } = await supabase
    .from('ai_voices')
    .select('provider_voice_id')
    .eq('is_enabled', true)

  if (error) {
    console.error('[VAPI Setup] Error fetching voices:', error)
    return null
  }

  if (!voices || voices.length === 0) {
    console.error('[VAPI Setup] No enabled voices found in database')
    return null
  }

  // Pick a random voice
  const randomIndex = Math.floor(Math.random() * voices.length)
  const selectedVoice = voices[randomIndex]

  console.log(`[VAPI Setup] Selected random voice: ${selectedVoice.provider_voice_id}`)
  return { voiceId: selectedVoice.provider_voice_id }
}

/**
 * Setup VAPI for a newly created store
 *
 * This function:
 * 1. Picks a random enabled voice from the database (or uses existing ai_config)
 * 2. Creates a default greeting message (or uses existing ai_config)
 * 3. Registers the phone number with VAPI
 * 4. Creates a VAPI assistant
 * 5. Updates the store's alt_data with VAPI IDs and ai_config
 *
 * @param supabase - Supabase client (with service role for admin operations)
 * @param storeId - The store UUID
 * @param storeName - The store name (for VAPI naming)
 * @param phoneNumber - The phone number in E.164 format
 */
export async function setupVapiForStore(
  supabase: SupabaseClient,
  storeId: string,
  storeName: string,
  phoneNumber: string
): Promise<VapiSetupResult> {
  console.log(`[VAPI Setup] Starting setup for store: ${storeName} (${storeId})`)

  // Check if VAPI is configured
  if (!isVapiConfigured()) {
    console.log('[VAPI Setup] VAPI_API_KEY not configured, skipping setup')
    return { success: false, error: 'VAPI_API_KEY not configured' }
  }

  try {
    // First, check if store already has ai_config with voice_type
    const { data: storeData } = await supabase
      .from('stores')
      .select('alt_data')
      .eq('id', storeId)
      .single()

    const existingAiConfig = storeData?.alt_data?.ai_config
    let voiceId: string
    let greetingMessage: string

    if (existingAiConfig?.voice_type) {
      // Use existing ai_config
      console.log(`[VAPI Setup] Using existing ai_config for store: ${storeId}`)
      voiceId = existingAiConfig.voice_type
      greetingMessage = existingAiConfig.greeting_message || getDefaultGreetingMessage(storeName)
    } else {
      // Step 1: Pick a random voice
      const voiceResult = await pickRandomVoice(supabase)
      if (!voiceResult) {
        const error = 'Failed to pick a voice from database'
        await updateStoreWithError(supabase, storeId, error)
        return { success: false, error }
      }
      voiceId = voiceResult.voiceId

      // Step 2: Create default greeting
      greetingMessage = getDefaultGreetingMessage(storeName)
    }

    // Step 3: Register phone number with VAPI
    console.log(`[VAPI Setup] Registering phone number: ${phoneNumber}`)
    const phoneResult = await registerPhoneNumber(phoneNumber, storeName)

    if (!phoneResult.success) {
      const error = `Failed to register phone number: ${phoneResult.error}`
      await updateStoreWithError(supabase, storeId, error)
      return { success: false, error }
    }

    // Step 4: Create VAPI assistant
    console.log(`[VAPI Setup] Creating assistant for store: ${storeName}`)
    const assistantConfig: VapiAssistantConfig = {
      storeName,
      storeId,
      voiceId,
      greetingMessage,
      phoneNumberId: phoneResult.phoneNumberId
    }

    const assistantResult = await createAssistant(assistantConfig)

    if (!assistantResult.success) {
      const error = `Failed to create assistant: ${assistantResult.error}`
      // Still store the phone number ID even if assistant creation fails
      await updateStoreWithPartialSuccess(
        supabase,
        storeId,
        phoneResult.phoneNumberId!,
        null,
        voiceId,
        greetingMessage,
        error
      )
      return {
        success: false,
        vapiPhoneNumberId: phoneResult.phoneNumberId,
        error
      }
    }

    // Step 5: Update store with VAPI IDs and ai_config
    console.log(`[VAPI Setup] Updating store with VAPI IDs`)
    await updateStoreWithSuccess(
      supabase,
      storeId,
      phoneResult.phoneNumberId!,
      assistantResult.assistantId!,
      voiceId,
      greetingMessage
    )

    console.log(`[VAPI Setup] Setup complete for store: ${storeName}`)
    return {
      success: true,
      vapiPhoneNumberId: phoneResult.phoneNumberId,
      vapiAssistantId: assistantResult.assistantId
    }
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : 'Unknown error'
    console.error(`[VAPI Setup] Setup failed:`, error)
    await updateStoreWithError(supabase, storeId, errorMessage)
    return { success: false, error: errorMessage }
  }
}

/**
 * Update store alt_data with successful VAPI setup
 */
async function updateStoreWithSuccess(
  supabase: SupabaseClient,
  storeId: string,
  vapiPhoneNumberId: string,
  vapiAssistantId: string,
  voiceId: string,
  greetingMessage: string
): Promise<void> {
  // First fetch existing alt_data
  const { data: store, error: fetchError } = await supabase
    .from('stores')
    .select('alt_data')
    .eq('id', storeId)
    .single()

  if (fetchError) {
    console.error('[VAPI Setup] Error fetching store:', fetchError)
    return
  }

  const existingAltData = store?.alt_data || {}

  const { error: updateError } = await supabase
    .from('stores')
    .update({
      alt_data: {
        ...existingAltData,
        vapi_phone_number_id: vapiPhoneNumberId,
        vapi_assistant_id: vapiAssistantId,
        vapi_setup_completed_at: new Date().toISOString(),
        ai_config: {
          voice_type: voiceId,
          greeting_message: greetingMessage
        }
      },
      updated_at: new Date().toISOString()
    })
    .eq('id', storeId)

  if (updateError) {
    console.error('[VAPI Setup] Error updating store:', updateError)
  }
}

/**
 * Update store alt_data with partial success (phone registered but assistant failed)
 */
async function updateStoreWithPartialSuccess(
  supabase: SupabaseClient,
  storeId: string,
  vapiPhoneNumberId: string,
  vapiAssistantId: string | null,
  voiceId: string,
  greetingMessage: string,
  error: string
): Promise<void> {
  const { data: store, error: fetchError } = await supabase
    .from('stores')
    .select('alt_data')
    .eq('id', storeId)
    .single()

  if (fetchError) {
    console.error('[VAPI Setup] Error fetching store:', fetchError)
    return
  }

  const existingAltData = store?.alt_data || {}

  const { error: updateError } = await supabase
    .from('stores')
    .update({
      alt_data: {
        ...existingAltData,
        vapi_phone_number_id: vapiPhoneNumberId,
        vapi_assistant_id: vapiAssistantId,
        vapi_setup_error: error,
        vapi_setup_attempted_at: new Date().toISOString(),
        ai_config: {
          voice_type: voiceId,
          greeting_message: greetingMessage
        }
      },
      updated_at: new Date().toISOString()
    })
    .eq('id', storeId)

  if (updateError) {
    console.error('[VAPI Setup] Error updating store:', updateError)
  }
}

/**
 * Update store alt_data with error
 */
async function updateStoreWithError(
  supabase: SupabaseClient,
  storeId: string,
  error: string
): Promise<void> {
  const { data: store, error: fetchError } = await supabase
    .from('stores')
    .select('alt_data')
    .eq('id', storeId)
    .single()

  if (fetchError) {
    console.error('[VAPI Setup] Error fetching store:', fetchError)
    return
  }

  const existingAltData = store?.alt_data || {}

  const { error: updateError } = await supabase
    .from('stores')
    .update({
      alt_data: {
        ...existingAltData,
        vapi_setup_error: error,
        vapi_setup_attempted_at: new Date().toISOString()
      },
      updated_at: new Date().toISOString()
    })
    .eq('id', storeId)

  if (updateError) {
    console.error('[VAPI Setup] Error updating store:', updateError)
  }
}

/**
 * Update VAPI assistant when AI config changes
 *
 * @param supabase - Supabase client
 * @param storeId - The store UUID
 * @param voiceId - New voice ID (provider_voice_id)
 * @param greetingMessage - New greeting message
 */
export async function updateVapiAssistant(
  supabase: SupabaseClient,
  storeId: string,
  voiceId: string,
  greetingMessage: string
): Promise<VapiUpdateResult> {
  console.log(`[VAPI Update] Updating assistant for store: ${storeId}`)

  // Check if VAPI is configured
  if (!isVapiConfigured()) {
    console.log('[VAPI Update] VAPI_API_KEY not configured, skipping update')
    return { success: false, error: 'VAPI_API_KEY not configured' }
  }

  try {
    // Fetch the store to get vapi_assistant_id
    const { data: store, error: fetchError } = await supabase
      .from('stores')
      .select('alt_data')
      .eq('id', storeId)
      .single()

    if (fetchError || !store) {
      const error = 'Store not found'
      console.error('[VAPI Update] Error fetching store:', fetchError)
      return { success: false, error }
    }

    const vapiAssistantId = store.alt_data?.vapi_assistant_id

    if (!vapiAssistantId) {
      console.log('[VAPI Update] No VAPI assistant ID found for store, skipping update')
      return { success: false, error: 'No VAPI assistant configured for this store' }
    }

    // Update the assistant in VAPI
    const result = await updateAssistant(vapiAssistantId, voiceId, greetingMessage)

    if (!result.success) {
      console.error('[VAPI Update] Failed to update assistant:', result.error)
      return { success: false, error: result.error }
    }

    console.log(`[VAPI Update] Successfully updated assistant: ${vapiAssistantId}`)
    return { success: true }
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : 'Unknown error'
    console.error('[VAPI Update] Update failed:', error)
    return { success: false, error: errorMessage }
  }
}
