/**
 * VAPI API Client
 *
 * Provides integration with VAPI (Voice AI) for:
 * - Registering phone numbers (BYO - Bring Your Own)
 * - Creating and updating AI assistants
 *
 * @see https://docs.vapi.ai/
 */

const VAPI_BASE_URL = 'https://api.vapi.ai'

// KOMPAAS credential ID - hardcoded as per requirements
const KOMPAAS_CREDENTIAL_ID = '7d8aceb7-61ae-42e0-a1ed-e81ba00735ce'

// Response types
export interface VapiPhoneNumberResponse {
  success: boolean
  phoneNumberId?: string
  error?: string
}

export interface VapiAssistantResponse {
  success: boolean
  assistantId?: string
  error?: string
}

export interface VapiAssistantConfig {
  storeName: string
  storeId: string
  voiceId: string
  greetingMessage: string
  systemPrompt: string  // Complete system prompt with opening hours
  languageCode?: string // Language code for transcription (hu, en, de)
  phoneNumberId?: string
}

/**
 * Get VAPI API key from environment
 */
function getVapiApiKey(): string | null {
  return Deno.env.get('VAPI_API_KEY') || null
}

/**
 * Get VAPI webhook auth token from environment
 */
function getVapiWebhookAuthToken(): string {
  return Deno.env.get('VAPI_WEBHOOK_AUTH_TOKEN') || 'int_shopcall_cOftLHMgH-o6JG5z6qfPI9xqswUq2ClBysMiCqKAoK3KkU7O'
}

/**
 * Make authenticated request to VAPI API
 */
async function vapiRequest(
  method: string,
  endpoint: string,
  body?: Record<string, unknown>
): Promise<{ success: boolean; data?: unknown; error?: string }> {
  const apiKey = getVapiApiKey()

  if (!apiKey) {
    return { success: false, error: 'VAPI_API_KEY not configured' }
  }

  try {
    const response = await fetch(`${VAPI_BASE_URL}${endpoint}`, {
      method,
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: body ? JSON.stringify(body) : undefined
    })

    const responseText = await response.text()
    let data: unknown

    try {
      data = JSON.parse(responseText)
    } catch {
      data = responseText
    }

    if (!response.ok) {
      console.error(`[VAPI] API error: ${response.status}`, data)
      return {
        success: false,
        error: `VAPI API error (${response.status}): ${typeof data === 'object' ? JSON.stringify(data) : data}`
      }
    }

    return { success: true, data }
  } catch (error) {
    console.error('[VAPI] Request failed:', error)
    return {
      success: false,
      error: error instanceof Error ? error.message : 'Request failed'
    }
  }
}

/**
 * Register a phone number with VAPI (BYO - Bring Your Own)
 *
 * @param phoneNumber - Phone number in E.164 format (e.g., "+36309284614")
 * @param storeName - Store name for identification
 * @param assistantId - Optional VAPI assistant ID to assign to this phone number
 */
export async function registerPhoneNumber(
  phoneNumber: string,
  storeName: string,
  assistantId?: string
): Promise<VapiPhoneNumberResponse> {
  console.log(`[VAPI] Registering phone number: ${phoneNumber} for store: ${storeName}${assistantId ? ` with assistant: ${assistantId}` : ''}`)

  const requestBody: Record<string, unknown> = {
    provider: 'byo-phone-number',
    name: `shopcall.ai - ${storeName}`,
    number: phoneNumber,
    numberE164CheckEnabled: false,
    credentialId: KOMPAAS_CREDENTIAL_ID
  }

  // Add assistantId if provided
  if (assistantId) {
    requestBody.assistantId = assistantId
  }

  const result = await vapiRequest('POST', '/phone-number', requestBody)

  if (!result.success) {
    return { success: false, error: result.error }
  }

  const data = result.data as { id?: string }

  if (!data?.id) {
    return { success: false, error: 'No phone number ID returned from VAPI' }
  }

  console.log(`[VAPI] Phone number registered successfully: ${data.id}`)
  return { success: true, phoneNumberId: data.id }
}

// Language to transcription locale mapping
const TRANSCRIBER_LOCALES: Record<string, string> = {
  hu: 'hu-HU',
  en: 'en-US',
  de: 'de-DE'
}

// Language to end call message mapping
const END_CALL_MESSAGES: Record<string, string> = {
  hu: 'Viszonthallásra!',
  en: 'Goodbye!',
  de: 'Auf Wiederhören!'
}

// Language to voicemail message mapping
const VOICEMAIL_MESSAGES: Record<string, string> = {
  hu: 'Kérem, hívjon vissza, amikor elérhető.',
  en: 'Please call back when you\'re available.',
  de: 'Bitte rufen Sie zurück, wenn Sie verfügbar sind.'
}

/**
 * Build the full assistant configuration for VAPI
 */
function buildAssistantConfig(config: VapiAssistantConfig): Record<string, unknown> {
  const supabaseUrl = Deno.env.get('SUPABASE_URL') || 'https://api.shopcall.ai'
  const webhookAuthToken = getVapiWebhookAuthToken()
  const langCode = config.languageCode || 'hu'

  return {
    name: `SC_${config.storeId}`, // max 40 chars -> stores.id = 37char (UUID)
    voice: {
      provider: '11labs',
      model: 'eleven_turbo_v2_5',
      voiceId: config.voiceId,
      stability: 0.5,
      similarityBoost: 0.75
    },
    model: {
      model: 'gpt-4.1',
      toolIds: [
        '82c2159c-05b0-44a0-af92-0c83ff3dd1ae',
        'bda2f41b-ec69-441d-8d16-a349783370d4'
      ],
      messages: [
        {
          role: 'system',
          content: config.systemPrompt
        }
      ],
      provider: 'openai',
      temperature: 0.4
    },
    forwardingPhoneNumber: '+36305547382',
    firstMessage: config.greetingMessage,
    voicemailMessage: VOICEMAIL_MESSAGES[langCode] || VOICEMAIL_MESSAGES['en'],
    endCallFunctionEnabled: true,
    endCallMessage: END_CALL_MESSAGES[langCode] || END_CALL_MESSAGES['en'],
    transcriber: {
      language: TRANSCRIBER_LOCALES[langCode] || 'hu-HU',
      provider: 'azure'
    },
    serverMessages: [
      'end-of-call-report',
      'transcript[transcriptType="final"]',
      'session.created'
    ],
    backgroundSound: 'off',
    firstMessageMode: 'assistant-speaks-first',
    analysisPlan: {
      minMessagesThreshold: 2
    },
    backgroundDenoisingEnabled: true,
    server: {
      url: `${supabaseUrl}/functions/v1/vapi-webhook?store_id=${config.storeId}`,
      timeoutSeconds: 20,
      headers: {
        Authorization: `Bearer ${webhookAuthToken}`
      }
    },
    compliancePlan: {
      hipaaEnabled: false,
      pciEnabled: false
    }
  }
}

/**
 * Create a new VAPI assistant for a store
 */
export async function createAssistant(
  config: VapiAssistantConfig
): Promise<VapiAssistantResponse> {
  console.log(`[VAPI] Creating assistant for store: ${config.storeName} (${config.storeId})`)

  const assistantConfig = buildAssistantConfig(config)
  const result = await vapiRequest('POST', '/assistant', assistantConfig)

  if (!result.success) {
    return { success: false, error: result.error }
  }

  const data = result.data as { id?: string }

  if (!data?.id) {
    return { success: false, error: 'No assistant ID returned from VAPI' }
  }

  console.log(`[VAPI] Assistant created successfully: ${data.id}`)
  return { success: true, assistantId: data.id }
}

/**
 * Update an existing VAPI assistant
 *
 * @param assistantId - The VAPI assistant ID to update
 * @param voiceId - New voice ID
 * @param greetingMessage - New greeting message
 * @param systemPrompt - Optional new system prompt (if not provided, system prompt is not updated)
 */
export async function updateAssistant(
  assistantId: string,
  voiceId: string,
  greetingMessage: string,
  systemPrompt?: string
): Promise<VapiAssistantResponse> {
  console.log(`[VAPI] Updating assistant: ${assistantId}${systemPrompt ? ' (including system prompt)' : ''}`)

  const updatePayload: Record<string, unknown> = {
    voice: {
      provider: '11labs',
      model: 'eleven_turbo_v2_5',
      voiceId: voiceId,
      stability: 0.5,
      similarityBoost: 0.75
    },
    firstMessage: greetingMessage
  }

  // Only update system prompt if provided
  if (systemPrompt) {
    updatePayload.model = {
      model: 'gpt-4.1',
      toolIds: [
        '82c2159c-05b0-44a0-af92-0c83ff3dd1ae',
        'bda2f41b-ec69-441d-8d16-a349783370d4'
      ],
      messages: [
        {
          role: 'system',
          content: systemPrompt
        }
      ],
      provider: 'openai',
      temperature: 0.4
    }
  }

  const result = await vapiRequest('PATCH', `/assistant/${assistantId}`, updatePayload)

  if (!result.success) {
    return { success: false, error: result.error }
  }

  console.log(`[VAPI] Assistant updated successfully: ${assistantId}`)
  return { success: true, assistantId }
}

/**
 * Assign an assistant to a phone number
 *
 * After creating an assistant, this function links it to the registered phone number
 * so that incoming calls to that number are handled by the assistant.
 *
 * @param phoneNumberId - The VAPI phone number ID
 * @param assistantId - The VAPI assistant ID to assign
 */
export async function assignAssistantToPhoneNumber(
  phoneNumberId: string,
  assistantId: string
): Promise<{ success: boolean; error?: string }> {
  console.log(`[VAPI] Assigning assistant ${assistantId} to phone number ${phoneNumberId}`)

  const result = await vapiRequest('PATCH', `/phone-number/${phoneNumberId}`, {
    assistantId: assistantId
  })

  if (!result.success) {
    return { success: false, error: result.error }
  }

  console.log(`[VAPI] Assistant assigned to phone number successfully`)
  return { success: true }
}

/**
 * Check if VAPI integration is available (API key configured)
 */
export function isVapiConfigured(): boolean {
  return !!getVapiApiKey()
}
