import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
import { wrapHandler, logError } from '../_shared/error-handler.ts'
import { fetchProducts, fetchOrders, fetchCustomers } from '../_shared/shoprenter-client.ts'
import { detectCountryCode } from '../_shared/phone-formatter.ts'

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

/**
 * Scheduled Background Sync for ShopRenter Stores
 *
 * This Edge Function is designed to be called by pg_cron or external schedulers.
 * It requires an internal secret key for authentication instead of user tokens.
 *
 * Security: Uses INTERNAL_SYNC_SECRET environment variable for authentication
 */

serve(wrapHandler('shoprenter-scheduled-sync', async (req) => {
  if (req.method === 'OPTIONS') {
    return new Response('ok', { headers: corsHeaders })
  }

  try {
    // Verify internal secret key for scheduled sync
    const internalSecret = req.headers.get('x-internal-secret')
    const expectedSecret = Deno.env.get('INTERNAL_SYNC_SECRET')

    if (!expectedSecret) {
      console.error('[ShopRenter Scheduled Sync] INTERNAL_SYNC_SECRET not configured')
      return new Response(
        JSON.stringify({ error: 'Service not configured' }),
        { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    if (!internalSecret || internalSecret !== expectedSecret) {
      console.warn('[ShopRenter Scheduled Sync] Invalid or missing internal secret')
      return new Response(
        JSON.stringify({ error: 'Unauthorized' }),
        { status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    const supabaseUrl = Deno.env.get('SUPABASE_URL')!
    const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
    const supabaseAdmin = createClient(supabaseUrl, supabaseServiceKey)

    // Get all ShopRenter stores with sync config
    const { data: stores, error: storesError } = await supabaseAdmin
      .from('stores')
      .select(`
        id,
        user_id,
        store_name,
        store_url,
        alt_data,
        qdrant_sync_enabled,
        store_sync_config (
          enabled,
          sync_frequency,
          last_sync_at,
          next_sync_at,
          products_access_policy,
          customers_access_policy,
          orders_access_policy
        )
      `)
      .eq('platform_name', 'shoprenter')
      .eq('is_active', true)

    if (storesError) {
      console.error('[ShopRenter Scheduled Sync] Error fetching stores:', storesError)
      return new Response(
        JSON.stringify({ error: 'Failed to fetch stores', details: storesError.message }),
        { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    // Filter stores that have sync enabled and are due for sync
    const now = new Date()
    console.log(`[ShopRenter Scheduled Sync] Current time: ${now.toISOString()}, Found ${stores?.length || 0} ShopRenter stores`)

    const storesToSync = stores?.filter(store => {
      // Handle both array and single object cases for store_sync_config
      const configArray = store.store_sync_config
      const config = Array.isArray(configArray) ? configArray[0] : configArray

      console.log(`[ShopRenter Scheduled Sync] Store ${store.id} (${store.store_name}):`, {
        hasConfig: !!config,
        configType: configArray ? (Array.isArray(configArray) ? 'array' : 'object') : 'null',
        enabled: config?.enabled,
        next_sync_at: config?.next_sync_at
      })

      if (!config || !config.enabled) {
        console.log(`[ShopRenter Scheduled Sync] Store ${store.id} skipped: no config or not enabled`)
        return false
      }

      // Check if sync is due
      if (config.next_sync_at) {
        const nextSync = new Date(config.next_sync_at)
        const isDue = nextSync <= now
        console.log(`[ShopRenter Scheduled Sync] Store ${store.id} sync check:`, {
          nextSync: nextSync.toISOString(),
          now: now.toISOString(),
          isDue
        })
        return isDue
      }

      // If no next_sync_at, sync is due
      console.log(`[ShopRenter Scheduled Sync] Store ${store.id} has no next_sync_at, marking as due`)
      return true
    }) || []

    if (storesToSync.length === 0) {
      console.log('[ShopRenter Scheduled Sync] No ShopRenter stores due for sync')
      return new Response(
        JSON.stringify({
          success: true,
          message: 'No stores due for sync',
          stores_processed: 0
        }),
        { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    console.log(`[ShopRenter Scheduled Sync] Found ${storesToSync.length} stores due for sync`)

    const syncResults = []

    // Sync each store
    for (const store of storesToSync) {
      const storeId = store.id
      // Handle both array and single object cases for store_sync_config
      const configArray = store.store_sync_config
      const config = Array.isArray(configArray) ? configArray[0] : configArray
      console.log(`[ShopRenter Scheduled Sync] Starting sync for store ${storeId} (${store.store_name})`)

      // Detect country code from store URL for phone formatting
      const countryCode = detectCountryCode(store.store_url)
      console.log(`[ShopRenter Scheduled Sync] Detected country code: ${countryCode} for store: ${store.store_name}`)

      const syncStats = {
        store_id: storeId,
        store_name: store.store_name,
        products: { synced: 0, errors: 0 },
        orders: { synced: 0, errors: 0 },
        customers: { synced: 0, errors: 0 },
        started_at: new Date().toISOString(),
        completed_at: null as string | null,
        status: 'success' as 'success' | 'partial' | 'failed',
        error_message: null as string | null
      }

      try {
        // Check access policies (GDPR compliance - Issue #95)
        const productsPolicy = config?.products_access_policy || 'sync'
        const ordersPolicy = config?.orders_access_policy || 'sync'
        const customersPolicy = config?.customers_access_policy || 'sync'

        console.log(`[ShopRenter Scheduled Sync] Store ${storeId} access policies:`, {
          products: productsPolicy,
          orders: ordersPolicy,
          customers: customersPolicy
        })

        // Sync Products (only if policy allows sync)
        if (productsPolicy === 'sync') {
          try {
            console.log(`[ShopRenter Scheduled Sync] Syncing products for store ${storeId}`)
            let page = 0  // ShopRenter API uses zero-based pagination
            let hasMore = true
            const limit = 50

            while (hasMore) {
              const productsData = await fetchProducts(storeId, page, limit)

              if (productsData.items && productsData.items.length > 0) {
                const productsToCache = productsData.items.map((product: any) => ({
                  store_id: storeId,
                  product_id: product.id,
                  inner_id: product.innerId,
                  name: product.name,
                  sku: product.sku,
                  categories: product.productCategory || [],
                  excluded: false, // Will be set if in exclusion list
                  last_synced_at: new Date().toISOString()
                }))

                const { error: upsertError } = await supabaseAdmin
                  .from('shoprenter_products_cache')
                  .upsert(productsToCache, {
                    onConflict: 'store_id,product_id'
                  })

                if (upsertError) {
                  console.error(`[ShopRenter Scheduled Sync] Error caching products for store ${storeId}:`, upsertError)
                  syncStats.products.errors += productsToCache.length
                } else {
                  syncStats.products.synced += productsToCache.length
                }

                // Check if there are more pages
                if (productsData.pagination && productsData.pagination.total) {
                  const totalPages = Math.ceil(productsData.pagination.total / limit)
                  hasMore = page < totalPages - 1  // Zero-based, so last page is totalPages - 1
                } else {
                  hasMore = productsData.items.length === limit
                }

                page++
              } else {
                hasMore = false
              }
            }

            console.log(`[ShopRenter Scheduled Sync] Store ${storeId}: Products synced: ${syncStats.products.synced}, errors: ${syncStats.products.errors}`)
          } catch (error) {
            console.error(`[ShopRenter Scheduled Sync] Product sync error for store ${storeId}:`, error)
            syncStats.products.errors++
            syncStats.status = 'partial'
          }
        } else {
          console.log(`[ShopRenter Scheduled Sync] Products sync skipped for store ${storeId}: access policy is '${productsPolicy}' (requires 'sync')`)
        }

        // Sync Orders and Customers to Qdrant (if enabled and policy allows)
        // Note: Orders/customers are NOT cached to database for GDPR compliance
        // They are only synced to Qdrant for AI access when policy allows
        const qdrantEnabled = store.qdrant_sync_enabled !== false
        const shouldSyncOrders = ordersPolicy === 'sync'
        const shouldSyncCustomers = customersPolicy === 'sync'

        // Call shoprenter-sync to handle full sync (products + orders + customers)
        // This ensures orders and customers are synced to Qdrant (only if policies allow)
        if (qdrantEnabled && (shouldSyncOrders || shouldSyncCustomers)) {
          try {
            console.log(`[ShopRenter Scheduled Sync] Calling shoprenter-sync for full sync on store ${storeId}`)
            const syncResponse = await fetch(`${supabaseUrl}/functions/v1/shoprenter-sync/${storeId}`, {
              method: 'POST',
              headers: {
                'Authorization': `Bearer ${supabaseServiceKey}`,
                'Content-Type': 'application/json'
              }
            })

            if (syncResponse.ok) {
              const syncResult = await syncResponse.json()
              if (syncResult.success && syncResult.stats) {
                // Update with results from full sync
                syncStats.orders = syncResult.stats.orders || { synced: 0, errors: 0 }
                syncStats.customers = syncResult.stats.customers || { synced: 0, errors: 0 }
                console.log(`[ShopRenter Scheduled Sync] Full sync completed: orders=${syncStats.orders.synced}, customers=${syncStats.customers.synced}`)
              } else {
                console.error(`[ShopRenter Scheduled Sync] Full sync failed:`, syncResult.error || syncResult.message)
                syncStats.status = 'partial'
              }
            } else {
              console.error(`[ShopRenter Scheduled Sync] Full sync HTTP error: ${syncResponse.status}`)
              syncStats.status = 'partial'
            }
          } catch (error) {
            console.error(`[ShopRenter Scheduled Sync] Full sync error for store ${storeId}:`, error)
            syncStats.orders.errors++
            syncStats.customers.errors++
            syncStats.status = 'partial'
          }
        } else {
          console.log(`[ShopRenter Scheduled Sync] Orders/customers sync skipped:`, {
            qdrantEnabled,
            shouldSyncOrders,
            shouldSyncCustomers,
            ordersPolicy,
            customersPolicy
          })
        }

        // Update BOTH stores table and store_sync_config to maintain consistency
        const syncCompletedAt = new Date().toISOString()

        // Update store last_sync timestamp and alt_data
        const updatedAltData = {
          ...(store.alt_data || {}),
          last_sync_at: syncCompletedAt,
          last_sync_stats: {
            products: syncStats.products,
            orders: syncStats.orders,
            customers: syncStats.customers
          },
          last_sync_type: 'scheduled'
        }

        // Update stores table (runtime status only, preserve alt_data)
        await supabaseAdmin
          .from('stores')
          .update({
            alt_data: updatedAltData,
            sync_status: syncStats.status === 'success' ? 'completed' : 'error',
            sync_error: syncStats.error_message
          })
          .eq('id', storeId)

        // Update store_sync_config (single source of truth for sync timing)
        if (config) {
          await supabaseAdmin
            .from('store_sync_config')
            .update({
              last_sync_at: syncCompletedAt,
              // next_sync_at will be auto-calculated by trigger
            })
            .eq('store_id', storeId)
        } else {
          // Create sync config if it doesn't exist
          await supabaseAdmin
            .from('store_sync_config')
            .insert({
              store_id: storeId,
              enabled: true,
              sync_frequency: 'hourly',
              last_sync_at: syncCompletedAt
            })
        }

        syncStats.completed_at = new Date().toISOString()
        console.log(`[ShopRenter Scheduled Sync] Store ${storeId} sync completed with status: ${syncStats.status}`)

      } catch (error) {
        console.error(`[ShopRenter Scheduled Sync] Fatal error syncing store ${storeId}:`, error)
        syncStats.status = 'failed'
        syncStats.error_message = error.message
        syncStats.completed_at = new Date().toISOString()
      }

      syncResults.push(syncStats)
    }

    // Log sync summary to database
    try {
      await supabaseAdmin
        .from('sync_logs')
        .insert({
          sync_type: 'scheduled',
          platform: 'shoprenter',
          stores_processed: storesToSync.length,
          results: syncResults,
          started_at: syncResults[0]?.started_at || new Date().toISOString(),
          completed_at: new Date().toISOString()
        })
    } catch (error) {
      console.error('[ShopRenter Scheduled Sync] Failed to log sync results:', error)
      // Don't fail the request if logging fails
    }

    const successCount = syncResults.filter(r => r.status === 'success').length
    const partialCount = syncResults.filter(r => r.status === 'partial').length
    const failedCount = syncResults.filter(r => r.status === 'failed').length

    console.log(`[ShopRenter Scheduled Sync] Batch complete: ${successCount} success, ${partialCount} partial, ${failedCount} failed`)

    return new Response(
      JSON.stringify({
        success: true,
        message: 'Scheduled sync completed',
        summary: {
          stores_processed: storesToSync.length,
          success: successCount,
          partial: partialCount,
          failed: failedCount
        },
        results: syncResults,
        timestamp: new Date().toISOString()
      }),
      { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
    )

  } catch (error) {
    console.error('[ShopRenter Scheduled Sync] Unexpected error:', error)
    return new Response(
      JSON.stringify({ error: 'Internal server error', details: error.message }),
      { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
    )
  }
}))
