import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
import {
  requireInternalApiKey,
  createInternalApiKeyErrorResponse,
} from '../_shared/internal-api-key-auth.ts'

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
  'Access-Control-Allow-Methods': 'POST, OPTIONS',
}

const STORAGE_BUCKET = 'call-recordings'

/**
 * Download recording from VAPI and upload to Supabase Storage
 */
async function downloadAndStoreRecording(
  supabase: ReturnType<typeof createClient>,
  recordingUrl: string,
  storeId: string,
  callId: string
): Promise<string | null> {
  try {
    console.log('Downloading recording from:', recordingUrl)

    // Download the recording
    const response = await fetch(recordingUrl)
    if (!response.ok) {
      console.error('Failed to download recording:', response.status, response.statusText)
      return null
    }

    const audioBlob = await response.blob()

    // Extract filename from URL or generate one
    const urlParts = recordingUrl.split('/')
    const originalFilename = urlParts[urlParts.length - 1] || `${callId}.wav`
    const storagePath = `${storeId}/recordings/${originalFilename}`

    console.log('Uploading recording to storage:', storagePath)

    // Upload to Supabase Storage
    const { data: uploadData, error: uploadError } = await supabase.storage
      .from(STORAGE_BUCKET)
      .upload(storagePath, audioBlob, {
        contentType: 'audio/wav',
        upsert: true
      })

    if (uploadError) {
      console.error('Failed to upload recording:', uploadError)
      return null
    }

    // Get public URL
    const { data: publicUrlData } = supabase.storage
      .from(STORAGE_BUCKET)
      .getPublicUrl(storagePath)

    console.log('Recording stored successfully:', publicUrlData.publicUrl)
    return publicUrlData.publicUrl
  } catch (error) {
    console.error('Error processing recording:', error)
    return null
  }
}

serve(async (req) => {
  // Handle CORS preflight
  if (req.method === 'OPTIONS') {
    return new Response('ok', { headers: corsHeaders })
  }

  try {
    // Only accept POST requests
    if (req.method !== 'POST') {
      return new Response(
        JSON.stringify({ error: 'Method not allowed' }),
        { status: 405, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    // Create Supabase admin client for authentication
    const supabaseUrl = Deno.env.get('SUPABASE_URL')!
    const supabaseKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
    const supabase = createClient(supabaseUrl, supabaseKey)

    // Validate internal API key
    const authResult = await requireInternalApiKey(req, supabase)
    if (!authResult.valid) {
      const errorResponse = createInternalApiKeyErrorResponse(authResult)
      // Add CORS headers to error response
      return new Response(errorResponse.body, {
        status: errorResponse.status,
        headers: { ...corsHeaders, 'Content-Type': 'application/json' }
      })
    }

    // Extract and validate store_id from query parameters
    const url = new URL(req.url)
    const storeId = url.searchParams.get('store_id')
    const caller = url.searchParams.get('caller') // Optional caller number

    if (!storeId) {
      return new Response(
        JSON.stringify({ error: 'Missing required query parameter: store_id' }),
        { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    // Validate UUID format
    const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
    if (!uuidRegex.test(storeId)) {
      return new Response(
        JSON.stringify({ error: 'Invalid store_id format. Must be a valid UUID.' }),
        { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    // Verify store exists and is active
    const { data: store, error: storeError } = await supabase
      .from('stores')
      .select('id, store_name, is_active')
      .eq('id', storeId)
      .single()

    if (storeError || !store) {
      return new Response(
        JSON.stringify({ error: 'Store not found', store_id: storeId }),
        { status: 404, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    if (!store.is_active) {
      return new Response(
        JSON.stringify({ error: 'Store is inactive', store_id: storeId }),
        { status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    console.log(`Processing VAPI webhook for store: ${store.store_name} (${storeId})`)

    // Parse the webhook payload
    const payload = await req.json()
    console.log('Received VAPI webhook:', JSON.stringify(payload, null, 2))

    // Validate payload structure - only process end-of-call-report
    if (!payload.message || payload.message.type !== 'end-of-call-report') {
      console.log('Ignoring non-end-of-call-report webhook:', payload.message?.type)
      return new Response(
        JSON.stringify({ status: 'ignored', reason: 'Not an end-of-call-report' }),
        { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    const message = payload.message
    const callId = crypto.randomUUID()

    // Download and store recording if available
    let recordingUrl: string | null = null
    if (message.stereoRecordingUrl) {
      recordingUrl = await downloadAndStoreRecording(
        supabase,
        message.stereoRecordingUrl,
        storeId,
        callId
      )
    }

    // Prepare call log data with extracted fields
    const callLogData = {
      id: callId,
      store_id: storeId,
      payload: payload,
      // Extracted fields
      started_at: message.startedAt || null,
      ended_at: message.endedAt || null,
      transcript: message.transcript || null,
      recording_url: recordingUrl,
      duration: message.durationSeconds || null,
      costs: message.costs || null,
      cost_total: message.call?.cost || message.cost || null,
      caller: message.customer?.number || caller || null,
    }

    console.log('Inserting call log for store:', storeId)

    // Insert call log into database
    const { data, error } = await supabase
      .from('call_logs')
      .insert([callLogData])
      .select()
      .single()

    if (error) {
      console.error('Error inserting call log:', error)
      return new Response(
        JSON.stringify({ error: 'Failed to store call log', details: error.message }),
        { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    console.log('Call log stored successfully:', data.id)

    // Update subscription usage if call had duration
    if (message.durationSeconds && message.durationSeconds > 0) {
      const minutesConsumed = message.durationSeconds / 60
      console.log(`Updating subscription usage: ${minutesConsumed.toFixed(2)} minutes for store ${storeId}`)

      // Get current subscription
      const { data: subscription, error: subError } = await supabase
        .from('store_subscriptions')
        .select('id, minutes_used, minutes_included, status')
        .eq('store_id', storeId)
        .single()

      if (subError || !subscription) {
        console.error('No subscription found for store:', storeId, subError)
      } else if (subscription.status === 'cancelled' || subscription.status === 'expired') {
        console.log('Subscription is not active, skipping usage update:', subscription.status)
      } else {
        // Update minutes_used in store_subscriptions
        const { error: updateError } = await supabase
          .from('store_subscriptions')
          .update({
            minutes_used: (subscription.minutes_used || 0) + minutesConsumed
          })
          .eq('id', subscription.id)

        if (updateError) {
          console.error('Error updating subscription usage:', updateError)
        } else {
          console.log(`Subscription usage updated: ${(subscription.minutes_used || 0) + minutesConsumed} total minutes used`)

          // Log usage in subscription_usage_log
          const { error: logError } = await supabase
            .from('subscription_usage_log')
            .insert({
              subscription_id: subscription.id,
              store_id: storeId,
              call_log_id: data.id,
              minutes_consumed: minutesConsumed,
              source_type: 'included' // For now, all usage comes from included minutes
            })

          if (logError) {
            console.error('Error logging subscription usage:', logError)
          } else {
            console.log('Subscription usage logged successfully')
          }
        }
      }
    }

    // Trigger analytics processing (non-blocking)
    const analyticsApiKey = Deno.env.get('ANALYTICS_INTERNAL_API_KEY')
    if (analyticsApiKey && message.transcript) {
      console.log('Triggering call log analytics (non-blocking)...')
      // Fire and forget - don't await
      fetch(`${supabaseUrl}/functions/v1/call-log-analytics`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${analyticsApiKey}`
        },
        body: JSON.stringify({ call_log_id: data.id })
      }).then(res => {
        if (res.ok) {
          console.log('Analytics trigger successful for call log:', data.id)
        } else {
          console.error('Analytics trigger failed:', res.status)
        }
      }).catch(err => {
        console.error('Analytics trigger error:', err)
      })
    } else if (!analyticsApiKey) {
      console.log('ANALYTICS_INTERNAL_API_KEY not set, skipping analytics')
    } else if (!message.transcript) {
      console.log('No transcript available, skipping analytics')
    }

    // Return success response
    return new Response(
      JSON.stringify({
        status: 'success',
        call_log_id: data.id,
        recording_stored: !!recordingUrl,
        analytics_triggered: !!(analyticsApiKey && message.transcript),
        message: 'Call log stored successfully'
      }),
      { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
    )

  } catch (error) {
    console.error('Error processing VAPI webhook:', error)
    return new Response(
      JSON.stringify({
        error: 'Internal server error',
        details: error instanceof Error ? error.message : 'Unknown error'
      }),
      { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
    )
  }
})
