/**
 * 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'
import {
  loadSystemPrompt,
  loadStoreBusinessHours,
  loadStoreSpecialHours,
  buildCompleteSystemPrompt
} from './prompt-utils.ts'

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

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

/**
 * Default language code used when integrating webshops
 */
const DEFAULT_LANGUAGE_CODE = 'hu'

/**
 * Load default greeting message from database
 * Falls back to hardcoded message if not found
 */
async function loadDefaultGreetingMessage(
  supabase: SupabaseClient,
  storeName: string,
  languageCode: string = DEFAULT_LANGUAGE_CODE
): Promise<string> {
  const prompts = await loadSystemPrompt(supabase, languageCode)

  if (prompts?.greetingMessage) {
    // Replace ${storeName} placeholder in greeting
    return prompts.greetingMessage.replace(/\$\{storeName\}/g, storeName)
  }

  // Fallback to hardcoded message
  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. Creates a VAPI assistant
 * 4. Registers the phone number with VAPI (with assistantId to link them)
 * 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
    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
    const languageCode = existingAiConfig?.language_code || DEFAULT_LANGUAGE_CODE

    // Step 1: Load base system prompt from database
    console.log(`[VAPI Setup] Loading system prompt for language: ${languageCode}`)
    const promptData = await loadSystemPrompt(supabase, languageCode)
    if (!promptData?.systemPrompt) {
      const error = `Failed to load system prompt for language: ${languageCode}`
      console.error(`[VAPI Setup] ${error}`)
      await updateStoreWithError(supabase, storeId, error)
      return { success: false, error }
    }

    // Step 2: Use existing greeting from DB if available, otherwise use default from database
    if (existingAiConfig?.greeting_message) {
      greetingMessage = existingAiConfig.greeting_message
      console.log(`[VAPI Setup] Using existing greeting from store config: ${storeId}`)
    } else if (promptData.greetingMessage) {
      // Replace ${storeName} placeholder in greeting from DB
      greetingMessage = promptData.greetingMessage.replace(/\$\{storeName\}/g, storeName)
      console.log(`[VAPI Setup] Using default greeting from database for store: ${storeId}`)
    } else {
      greetingMessage = `Üdvözlöm! A ${storeName} ügyfélszolgálata vagyok. Miben segíthetek?`
      console.log(`[VAPI Setup] Using hardcoded fallback greeting for store: ${storeId}`)
    }

    // Step 3: Use existing voice if available, otherwise pick random
    if (existingAiConfig?.voice_type) {
      voiceId = existingAiConfig.voice_type
      console.log(`[VAPI Setup] Using existing voice from DB: ${voiceId}`)
    } else {
      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
      console.log(`[VAPI Setup] Picked random voice: ${voiceId}`)
    }

    // Step 4: Load business hours and special hours for opening hours section
    console.log(`[VAPI Setup] Loading business hours for store: ${storeId}`)
    const { businessHours, isEnabled: hoursEnabled } = await loadStoreBusinessHours(supabase, storeId)
    const specialHours = await loadStoreSpecialHours(supabase, storeId)
    const transferPhoneNumber = existingAiConfig?.transfer_phone_number || null

    // Step 5: Build complete system prompt with opening hours
    // When business hours are disabled, also hide special hours and transfer phone
    const systemPrompt = buildCompleteSystemPrompt(
      promptData.systemPrompt,
      storeName,
      storeId,
      hoursEnabled ? businessHours : null,
      hoursEnabled ? specialHours : null,  // Hide special hours when business hours disabled
      languageCode,
      hoursEnabled ? transferPhoneNumber : null  // Hide transfer phone when business hours disabled
    )
    console.log(`[VAPI Setup] Built system prompt (${systemPrompt.length} chars), hours enabled: ${hoursEnabled}`)

    // Step 6: Create VAPI assistant first (we need the ID for phone number registration)
    console.log(`[VAPI Setup] Creating assistant for store: ${storeName}`)
    const assistantConfig: VapiAssistantConfig = {
      storeName,
      storeId,
      voiceId,
      greetingMessage,
      systemPrompt,
      languageCode
    }

    const assistantResult = await createAssistant(assistantConfig)

    if (!assistantResult.success) {
      const error = `Failed to create assistant: ${assistantResult.error}`
      await updateStoreWithError(supabase, storeId, error)
      return { success: false, error }
    }

    // Step 7: Register phone number with VAPI (with assistantId to link them)
    console.log(`[VAPI Setup] Registering phone number: ${phoneNumber} with assistant: ${assistantResult.assistantId}`)
    const phoneResult = await registerPhoneNumber(phoneNumber, storeName, assistantResult.assistantId)

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

    // Step 8: 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 (one of phone/assistant failed)
 */
async function updateStoreWithPartialSuccess(
  supabase: SupabaseClient,
  storeId: string,
  vapiPhoneNumberId: string | null,
  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
 * @param updateSystemPrompt - Whether to also rebuild and update the system prompt (default: false)
 */
export async function updateVapiAssistant(
  supabase: SupabaseClient,
  storeId: string,
  voiceId: string,
  greetingMessage: string,
  updateSystemPrompt: boolean = false
): Promise<VapiUpdateResult> {
  console.log(`[VAPI Update] Updating assistant for store: ${storeId}${updateSystemPrompt ? ' (including system prompt)' : ''}`)

  // 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 and store_name
    const { data: store, error: fetchError } = await supabase
      .from('stores')
      .select('store_name, 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
    const storeName = store.store_name || 'Unknown Store'
    const languageCode = store.alt_data?.ai_config?.language_code || DEFAULT_LANGUAGE_CODE

    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' }
    }

    let systemPrompt: string | undefined

    // Rebuild system prompt if requested
    if (updateSystemPrompt) {
      console.log(`[VAPI Update] Rebuilding system prompt for language: ${languageCode}`)

      const promptData = await loadSystemPrompt(supabase, languageCode)
      if (!promptData?.systemPrompt) {
        console.error(`[VAPI Update] Failed to load system prompt for language: ${languageCode}`)
        return { success: false, error: 'Failed to load system prompt' }
      }

      // Load business hours and special hours
      const { businessHours, isEnabled: hoursEnabled } = await loadStoreBusinessHours(supabase, storeId)
      const specialHours = await loadStoreSpecialHours(supabase, storeId)
      const transferPhoneNumber = store.alt_data?.ai_config?.transfer_phone_number || null

      // Build complete system prompt with opening hours
      // When business hours are disabled, also hide special hours and transfer phone
      systemPrompt = buildCompleteSystemPrompt(
        promptData.systemPrompt,
        storeName,
        storeId,
        hoursEnabled ? businessHours : null,
        hoursEnabled ? specialHours : null,  // Hide special hours when business hours disabled
        languageCode,
        hoursEnabled ? transferPhoneNumber : null  // Hide transfer phone when business hours disabled
      )
      console.log(`[VAPI Update] Built system prompt (${systemPrompt.length} chars), hours enabled: ${hoursEnabled}`)
    }

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

    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 }
  }
}

/**
 * Update VAPI assistant's system prompt only
 * Used when business hours or special hours change
 *
 * @param supabase - Supabase client
 * @param storeId - The store UUID
 */
export async function updateVapiSystemPrompt(
  supabase: SupabaseClient,
  storeId: string
): Promise<VapiUpdateResult> {
  console.log(`[VAPI Update] Updating system prompt only 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 all needed data
    const { data: store, error: fetchError } = await supabase
      .from('stores')
      .select('store_name, 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
    const storeName = store.store_name || 'Unknown Store'
    const languageCode = store.alt_data?.ai_config?.language_code || DEFAULT_LANGUAGE_CODE
    const voiceId = store.alt_data?.ai_config?.voice_type
    const greetingMessage = store.alt_data?.ai_config?.greeting_message

    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' }
    }

    if (!voiceId || !greetingMessage) {
      console.log('[VAPI Update] Missing voice or greeting config, skipping update')
      return { success: false, error: 'Missing AI configuration for this store' }
    }

    // Load system prompt
    const promptData = await loadSystemPrompt(supabase, languageCode)
    if (!promptData?.systemPrompt) {
      console.error(`[VAPI Update] Failed to load system prompt for language: ${languageCode}`)
      return { success: false, error: 'Failed to load system prompt' }
    }

    // Load business hours and special hours
    const { businessHours, isEnabled: hoursEnabled } = await loadStoreBusinessHours(supabase, storeId)
    const specialHours = await loadStoreSpecialHours(supabase, storeId)
    const transferPhoneNumber = store.alt_data?.ai_config?.transfer_phone_number || null

    // Build complete system prompt with opening hours
    // When business hours are disabled, also hide special hours and transfer phone
    const systemPrompt = buildCompleteSystemPrompt(
      promptData.systemPrompt,
      storeName,
      storeId,
      hoursEnabled ? businessHours : null,
      hoursEnabled ? specialHours : null,  // Hide special hours when business hours disabled
      languageCode,
      hoursEnabled ? transferPhoneNumber : null  // Hide transfer phone when business hours disabled
    )
    console.log(`[VAPI Update] Built system prompt (${systemPrompt.length} chars), hours enabled: ${hoursEnabled}, special hours: ${hoursEnabled ? specialHours.length : 0}`)

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

    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 system prompt for 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 }
  }
}
