/**
 * Widget Renderer
 * 
 * Main component that renders the appropriate widget based on type.
 * Handles widget lifecycle and communication with chat.
 */

import { useCallback, useEffect, useRef } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import { LeadFormWidget } from './LeadFormWidget'
import { ProductCardWidget } from './ProductCardWidget'
import { ContactCardWidget } from './ContactCardWidget'
import { CalendarWidget } from './CalendarWidget'
import { SurveyWidget } from './SurveyWidget'
import { CartWidget } from './CartWidget'
import { OrderStatusWidget } from './OrderStatusWidget'
import { ProductCarouselWidget } from './ProductCarouselWidget'
// DynamicFormWidget is deprecated - LeadFormWidget now handles all form types
// import { DynamicFormWidget } from './DynamicFormWidget'
import { WhatsAppWidget } from './WhatsAppWidget'
import { WidgetPicker } from './WidgetPicker'
import { CouponWidget } from './CouponWidget'
import { YouTubeWidget } from './YouTubeWidget'
import { GalleryWidget } from './GalleryWidget'
import { BundleBuilderWidget } from './BundleBuilderWidget'
import type { BundleData } from './BundleDisplay'
import { chatApi } from '@/api/chat'
import { useChatStore } from '@/store/chatStore'
import { flushCommerceEvents, getCartTelemetryFields, trackCommerceEvent } from '@/services/commerceTelemetry'
import { GlobalValues } from '@/utils/resolveAppearance'
import { t } from '@/lib/i18n'
import { cartDebugLog, getWooCartCount } from '@/utils/cart'
import type { ProductActionResult, ProductAddToCartRequest } from '@shared/components/widgets/ProductCard'

export type WidgetType = 
  | 'lead_form'
  | 'lead_capture'
  | 'contact_form'
  | 'contact_card'
  | 'dynamic_form'
  | 'form'
  | 'product_card'
  | 'product_carousel'
  | 'calendar'
  | 'calendar_call'
  | 'calendar_meeting'
  | 'whatsapp'
  | 'survey'
  | 'cart'
  | 'order_status'
  | 'widget_picker'
  | 'coupon'
  | 'youtube'
  | 'gallery'
  | 'bundle_builder'

export interface WidgetData {
  type: WidgetType
  config: Record<string, unknown>
  id?: string | number
}

interface WidgetPickerOption {
  type: string
  id: number
  label: string
  icon?: string
}

interface WidgetRendererProps {
  widget: WidgetData
  onComplete?: (result: unknown) => void
  onWidgetSelect?: (option: WidgetPickerOption) => void
  isRTL?: boolean
}

export function WidgetRenderer({ 
  widget, 
  onComplete,
  onWidgetSelect,
  isRTL = true 
}: WidgetRendererProps) {
  const { type, config } = widget
  const { config: chatConfig, conversationId, visitorId, currentBotId } = useChatStore()
  const refreshCart = useChatStore((state) => state.refreshCart)
  const setCartState = useChatStore((state) => state.setCartState)
  const cart = useChatStore((state) => (type === 'cart' ? state.cart : null))
  const updateCartItemAndSync = useChatStore((state) => state.updateCartItemAndSync)
  const removeCartItemAndSync = useChatStore((state) => state.removeCartItemAndSync)
  const couponCart = useChatStore((state) => (type === 'coupon' ? state.cart : null))
  const applyCouponAndSync = useChatStore((state) => state.applyCouponAndSync)
  const removeCouponAndSync = useChatStore((state) => state.removeCouponAndSync)
  const lastBundleCouponCode = useChatStore((state) => state.lastBundleCouponCode)
  const setLastBundleCouponCode = useChatStore((state) => state.setLastBundleCouponCode)
  
  // Get global values and element settings for widgets
  const globalValues = (chatConfig.appearance_preset?.global_values || {}) as GlobalValues
  const calendarWidgetSettings = chatConfig.appearance_preset?.widget_settings?.calendar as Parameters<typeof CalendarWidget>[0]['widgetSettings']
  const productCardWidgetSettings = chatConfig.appearance_preset?.widget_settings?.productCard as Parameters<typeof ProductCardWidget>[0]['widgetSettings']
  const contactCardWidgetSettings = chatConfig.appearance_preset?.widget_settings?.contactCard as Parameters<typeof ContactCardWidget>[0]['widgetSettings']
  const whatsappWidgetSettings = chatConfig.appearance_preset?.widget_settings?.whatsapp as Parameters<typeof WhatsAppWidget>[0]['widgetSettings']
  const youtubeWidgetSettings = chatConfig.appearance_preset?.widget_settings?.youtube as Parameters<typeof YouTubeWidget>[0]['widgetSettings']
  const galleryWidgetSettings = chatConfig.appearance_preset?.widget_settings?.gallery as Parameters<typeof GalleryWidget>[0]['widgetSettings']
  const leadFormWidgetSettings = chatConfig.appearance_preset?.widget_settings?.leadForm as Parameters<typeof LeadFormWidget>[0]['widgetSettings']
  const couponWidgetSettings = chatConfig.appearance_preset?.widget_settings?.coupon as Parameters<typeof CouponWidget>[0]['widgetSettings']
  const bundleBuilderWidgetSettings = chatConfig.appearance_preset?.widget_settings?.bundleBuilder as Parameters<typeof BundleBuilderWidget>[0]['widgetSettings']
  
  const botLanguage = chatConfig.language || 'he'
  const widgetId = widget.id != null ? Number(widget.id) : null
  const impressionKeysRef = useRef<Set<string>>(new Set())

  // Add RTL config to all widgets
  const widgetConfig = {
    ...config,
    is_rtl: isRTL,
  }

  const emitCommerceEvent = useCallback(
    (
      event: Parameters<typeof trackCommerceEvent>[0],
      eventCart?: Parameters<typeof getCartTelemetryFields>[0],
    ) => {
      trackCommerceEvent({
        conversation_id: conversationId,
        visitor_id: visitorId,
        bot_id: currentBotId,
        language: botLanguage,
        widget_type: type,
        widget_id: widgetId,
        ...getCartTelemetryFields(eventCart ?? cart ?? couponCart ?? null),
        ...event,
      })
    },
    [botLanguage, cart, conversationId, couponCart, currentBotId, type, visitorId, widgetId],
  )

  useEffect(() => {
    if (type === 'product_card') {
      const product = (config as Record<string, any>)?.product
      if (!product?.id) {
        return
      }

      const key = `product:${product.id}`
      if (impressionKeysRef.current.has(key)) {
        return
      }

      impressionKeysRef.current.add(key)
      emitCommerceEvent({
        event_type: 'product_card_viewed',
        product_id: Number(product.id),
        product_name: product.name ? String(product.name) : null,
        currency_code: typeof product.currency_code === 'string' ? product.currency_code : undefined,
      })
      return
    }

    if (type === 'coupon') {
      const coupons = Array.isArray((config as Record<string, unknown>).coupons)
        ? ((config as Record<string, unknown>).coupons as Array<Record<string, unknown>>)
        : []

      coupons.forEach((coupon) => {
        const code = typeof coupon.code === 'string' ? coupon.code : ''
        if (!code) {
          return
        }

        const key = `coupon:${code}`
        if (impressionKeysRef.current.has(key)) {
          return
        }

        impressionKeysRef.current.add(key)
        emitCommerceEvent(
          {
            event_type: 'coupon_viewed',
            coupon_code: code,
            metadata: {
              applicable: coupon.applicable === true,
              free_shipping: coupon.free_shipping === true,
            },
          },
          couponCart,
        )
      })
      return
    }

    if (type === 'cart') {
      const key = 'cart_opened_widget'
      if (impressionKeysRef.current.has(key)) {
        return
      }

      impressionKeysRef.current.add(key)
      emitCommerceEvent(
        {
          event_type: 'cart_opened',
          metadata: {
            source: 'widget',
          },
        },
        cart,
      )
    }
  }, [cart, config, couponCart, emitCommerceEvent, type])

  const handleBundleBuild = useCallback(async (criteria: {
    budget?: number
    category?: string
    preferences?: string[]
  }) => {
    const currentCart = useChatStore.getState().cart
    const cartProductIds = currentCart?.items
      ?.map(item => item.id)
      ?.filter((id): id is number => typeof id === 'number' && id > 0)
      ?? []

    const apiBase = window.boostbot_config?.rest_url || window.boostbot_config?.api_url || '/wp-json/boostbot/v1'
    const url = `${apiBase.replace(/\/$/, '')}/widgets/bundle-builder/build`
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        ...(window.boostbot_config?.nonce ? { 'X-WP-Nonce': window.boostbot_config.nonce } : {}),
      },
      body: JSON.stringify({
        budget: criteria.budget,
        category: criteria.category,
        preferences: criteria.preferences,
        widget_id: widget.id ? Number(widget.id) : undefined,
        customer_message: criteria.preferences?.join(' ') || '',
        language: botLanguage || window.boostbot_config?.locale?.substring(0, 2) || 'he',
        cart_item_ids: cartProductIds,
      }),
    })
    const result = await response.json()
    if (!response.ok || !result.success) {
      throw new Error(result.message || result.data?.message || t('Failed to build bundle'))
    }
    return result.data
  }, [botLanguage, widget.id])

  const handleBundleSwapItem = useCallback(async ({
    bundleId,
    swapOutId,
    bundle,
    criteria,
  }: {
    bundleId: number
    swapOutId: number
    bundle: BundleData
    criteria: {
      budget?: number
      category?: string
      preferences?: string[]
    }
  }) => {
    const apiBase = window.boostbot_config?.rest_url || window.boostbot_config?.api_url || '/wp-json/boostbot/v1'
    const url = `${apiBase.replace(/\/$/, '')}/widgets/bundle-builder/swap-item`
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        ...(window.boostbot_config?.nonce ? { 'X-WP-Nonce': window.boostbot_config.nonce } : {}),
      },
      body: JSON.stringify({
        bundle_id: bundleId,
        swap_out_id: swapOutId,
        bundle_items: bundle.products,
        budget: criteria.budget,
        category: criteria.category,
        preferences: criteria.preferences,
        widget_id: widget.id ? Number(widget.id) : undefined,
        language: botLanguage || window.boostbot_config?.locale?.substring(0, 2) || 'he',
      }),
    })
    const result = await response.json()
    if (!response.ok || !result.success) {
      throw new Error(result.message || result.data?.message || t('Could not swap bundle item'))
    }
    const swappedInProduct = Array.isArray(result.data?.products)
      ? result.data.products.find((product: { id?: number }) => !bundle.products.some(existing => existing.id === product.id))
      : null
    emitCommerceEvent({
      event_type: 'bundle_item_swapped',
      bundle_id: bundleId,
      bundle_size: Array.isArray(result.data?.products) ? result.data.products.length : bundle.products.length,
      bundle_value: Number(result.data?.total_price ?? bundle.total_price ?? 0),
      product_id: swapOutId,
      metadata: {
        swapped_in_product_id: swappedInProduct?.id ?? null,
        category: criteria.category || null,
      },
    })
    return result.data
  }, [botLanguage, emitCommerceEvent, widget.id])

  const handleBundleAddToCart = useCallback(async (bundleId: number, bundle: BundleData, couponCode?: string) => {
    const requestLanguage = botLanguage || window.boostbot_config?.locale?.substring(0, 2) || 'he'
    try {
      const result = await chatApi.addBundleToCart({
        bundle_id: bundleId,
        bundle_items: bundle.products,
        discount_percent: bundle.savings_percent,
        coupon_code: couponCode || '',
        language: requestLanguage,
      })

      if (result.couponApplied && result.couponCode) {
        setLastBundleCouponCode(String(result.couponCode))
      }
      const responseCart = result.cart
      console.info('[BoostBot][Cart] bundle responseCart before setCartState:', {
        exists: !!responseCart,
        keys: responseCart ? Object.keys(responseCart) : 'NULL',
        itemCount: responseCart?.count ?? responseCart?.items?.length ?? 'MISSING',
      })
      cartDebugLog('bundle add_to_cart response', {
        count: getWooCartCount(responseCart),
        items: responseCart?.items.length ?? 0,
        cart_count: result.cartCount ?? null,
        coupon_applied: result.couponApplied === true,
      })
      if (responseCart) {
        setCartState(responseCart)
      } else {
        const currentStoreState = useChatStore.getState()
        const woo = currentStoreState.config?.woocommerce ?? window.boostbot_config?.woocommerce
        if (woo?.active === true && woo?.show_cart_button === true) {
          await refreshCart()
        }
      }
      emitCommerceEvent({
        event_type: 'bundle_added_to_cart',
        bundle_id: bundleId,
        bundle_size: bundle.products.length,
        bundle_value: Number(bundle.total_price ?? 0),
        coupon_code: (result.couponCode || couponCode || '') ? String(result.couponCode || couponCode) : null,
        metadata: {
          coupon_applied: result.couponApplied === true,
        },
      })
      onComplete?.({ action: 'add_bundle_to_cart', bundleId, couponCode })
      if (result.couponApplied && result.couponCode) {
        return { success: true, message: t('Coupon "{code}" applied automatically!').replace('{code}', String(result.couponCode)) }
      }
      return { success: true, message: result.message || t('Bundle added to cart!') }
    } catch (err) {
      emitCommerceEvent({
        event_type: 'bundle_add_to_cart_failed',
        bundle_id: bundleId,
        bundle_size: bundle.products.length,
        bundle_value: Number(bundle.total_price ?? 0),
        coupon_code: couponCode || null,
        metadata: {
          message: err instanceof Error ? err.message : null,
        },
      })
      return { success: false, message: err instanceof Error ? err.message : t('Failed to add to cart') }
    }
  }, [botLanguage, emitCommerceEvent, onComplete, refreshCart, setCartState, setLastBundleCouponCode])

  const handleFormSubmit = async (data: Record<string, string>) => {
    await onComplete?.(data)
  }

  const handleProductAction = async (
    payload: {
      product_id: number
      action: string
      quantity?: number
      variation_id?: number
      variation?: Record<string, string>
    },
  ): Promise<ProductActionResult> => {
    const result = await onComplete?.(payload)
    const normalized = result as ProductActionResult | undefined
    return normalized || {
      success: false,
      error: t('Failed to add to cart'),
    }
  }

  const handleCalendarSelect = async (date: string, time: string, formData?: Record<string, string>) => {
    // Include widget_id so Message.tsx can resolve it even when selectedWidget is null
    const widgetId = widget.id ? Number(widget.id) : undefined
    await onComplete?.({ date, time, widget_id: widgetId, ...formData })
  }

  const handleSurveySubmit = async (data: { rating: number; feedback?: string }) => {
    onComplete?.(data)
  }

  const renderWidget = () => {
    switch (type) {
      case 'lead_form':
      case 'lead_capture':
      case 'contact_form':
        return (
          <LeadFormWidget
            config={widgetConfig as Parameters<typeof LeadFormWidget>[0]['config']}
            widgetSettings={leadFormWidgetSettings}
            globalValues={globalValues}
            language={botLanguage}
            onSubmit={handleFormSubmit}
          />
        )

      case 'dynamic_form':
      case 'form':
        // Route through unified LeadFormWidget for parity with Preview
        // LeadFormWidget now handles both legacy schema and dynamic form configs
        return (
          <LeadFormWidget
            config={widgetConfig as Parameters<typeof LeadFormWidget>[0]['config']}
            widgetSettings={leadFormWidgetSettings}
            globalValues={globalValues}
            language={botLanguage}
            onSubmit={handleFormSubmit}
          />
        )

      case 'whatsapp':
        return (
          <WhatsAppWidget
            config={widgetConfig as Parameters<typeof WhatsAppWidget>[0]['config']}
            widgetSettings={whatsappWidgetSettings}
            globalValues={globalValues}
            language={botLanguage}
            context={{
              page_url: window.location.href,
              conversation_id: widget.id?.toString()
            }}
          />
        )

      case 'calendar':
      case 'calendar_call':
      case 'calendar_meeting':
        return (
          <CalendarWidget
            config={{
              ...widgetConfig,
              title: (config as Record<string, unknown>).title as string || t('Book an Appointment'),
              widget_id: widget.id ? Number(widget.id) : undefined,
            } as Parameters<typeof CalendarWidget>[0]['config']}
            widgetSettings={calendarWidgetSettings}
            globalValues={globalValues}
            language={botLanguage}
            onSelect={handleCalendarSelect}
          />
        )

      case 'product_card':
        return (
          <ProductCardWidget
            config={widgetConfig as Parameters<typeof ProductCardWidget>[0]['config']}
            widgetSettings={productCardWidgetSettings}
            globalValues={globalValues}
            language={botLanguage}
            currencySymbol={(window as any).boostbot_config?.woocommerce?.currency_symbol || '₪'}
            onAddToCart={(request: ProductAddToCartRequest) => handleProductAction({
              product_id: request.productId,
              action: 'add_to_cart',
              quantity: request.quantity,
              variation_id: request.variationId,
              variation: request.variation,
            })}
            onViewProduct={(id) => {
              void handleProductAction({ product_id: id, action: 'view' })
            }}
          />
        )

      case 'contact_card':
        return (
          <ContactCardWidget
            config={widgetConfig as Parameters<typeof ContactCardWidget>[0]['config']}
            widgetSettings={contactCardWidgetSettings}
            globalValues={globalValues}
            language={botLanguage}
            onCall={(phone) => onComplete?.({ action: 'call', phone })}
            onMessage={(contact) => onComplete?.({ action: 'message', contact })}
          />
        )

      case 'survey':
        return (
          <SurveyWidget
            config={widgetConfig as Parameters<typeof SurveyWidget>[0]['config']}
            widgetSettings={chatConfig.appearance_preset?.widget_settings?.survey as any}
            globalValues={globalValues}
            language={botLanguage}
            onSubmit={handleSurveySubmit}
          />
        )

      case 'cart':
        return (
          <CartWidget
            config={((cart && !cart.is_empty ? { ...cart, is_rtl: isRTL } : widgetConfig)) as Parameters<typeof CartWidget>[0]['config']}
            language={botLanguage}
            onCheckout={() => {
              const hasWooSessionCookie = typeof document !== 'undefined'
                && (
                  document.cookie.includes('woocommerce_cart_hash=')
                  || document.cookie.includes('wp_woocommerce_session_')
                )

              console.log('[BoostBot] Checkout redirect:', {
                url: cart?.checkout_url || '#',
                chatCartItems: cart?.items?.length ?? 0,
                cart_count: cart?.count ?? 0,
                cookies: hasWooSessionCookie,
                source: 'widget',
              })
              emitCommerceEvent(
                {
                  event_type: 'checkout_clicked',
                  metadata: {
                    source: 'widget',
                  },
                },
                cart,
              )
              void flushCommerceEvents({ transport: 'beacon' })
              onComplete?.({ action: 'checkout' })
            }}
            onViewCart={() => onComplete?.({ action: 'view_cart' })}
            onUpdateItem={async (itemKey, quantity) => {
              const previousItem = cart?.items.find((item) => item.key === itemKey)
              const result = await updateCartItemAndSync(itemKey, quantity)
              if (result.success) {
                emitCommerceEvent(
                  {
                    event_type: 'cart_item_quantity_updated',
                    product_id: previousItem?.id ?? null,
                    product_name: previousItem?.name ?? null,
                    variation_id: previousItem?.variation_id ?? null,
                    quantity,
                    cart_item_key: itemKey,
                  },
                  result.cart,
                )
              }
            }}
            onRemoveItem={async (itemKey) => {
              const previousItem = cart?.items.find((item) => item.key === itemKey)
              const result = await removeCartItemAndSync(itemKey)
              if (result.success) {
                emitCommerceEvent(
                  {
                    event_type: 'cart_item_removed',
                    product_id: previousItem?.id ?? null,
                    product_name: previousItem?.name ?? null,
                    variation_id: previousItem?.variation_id ?? null,
                    quantity: previousItem?.quantity ?? null,
                    cart_item_key: itemKey,
                  },
                  result.cart,
                )
              }
            }}
          />
        )

      case 'widget_picker':
        return (
          <WidgetPicker
            options={((config as Record<string, unknown>).options as WidgetPickerOption[]) || []}
            onSelect={(option) => onWidgetSelect?.(option)}
            isRTL={isRTL}
          />
        )

      case 'order_status':
        return (
          <OrderStatusWidget
            config={widgetConfig as Parameters<typeof OrderStatusWidget>[0]['config']}
            language={botLanguage}
            onTrack={() => onComplete?.({ action: 'track' })}
            onViewOrder={() => onComplete?.({ action: 'view_order' })}
          />
        )

      case 'product_carousel':
        return (
          <ProductCarouselWidget
            config={widgetConfig as Parameters<typeof ProductCarouselWidget>[0]['config']}
            onAddToCart={(id) => handleProductAction({ product_id: id, action: 'add_to_cart' })}
            onViewProduct={(id) => handleProductAction({ product_id: id, action: 'view' })}
          />
        )

      case 'coupon':
        return (
          <CouponWidget
            config={widgetConfig as Parameters<typeof CouponWidget>[0]['config']}
            widgetSettings={couponWidgetSettings}
            globalValues={globalValues}
            language={botLanguage}
            isRTL={isRTL}
            cart={couponCart}
            lastBundleCouponCode={lastBundleCouponCode}
            currencySymbol={(window as any).boostbot_config?.woocommerce?.currency_symbol || '₪'}
            onCopyCode={(code) => {
              emitCommerceEvent(
                {
                  event_type: 'coupon_copied',
                  coupon_code: code,
                },
                couponCart,
              )
              onComplete?.({ action: 'coupon_copy', coupon_code: code })
            }}
            onApplyCoupon={async (code) => {
              const result = await applyCouponAndSync(code)
              emitCommerceEvent(
                {
                  event_type: result.success ? 'coupon_applied' : 'coupon_apply_failed',
                  coupon_code: code,
                  metadata: result.success
                    ? undefined
                    : {
                        error: result.error || null,
                      },
                },
                result.cart,
              )
              return result
            }}
            onRemoveCoupon={async (code) => {
              const result = await removeCouponAndSync(code)
              if (result.success) {
                emitCommerceEvent(
                  {
                    event_type: 'coupon_removed',
                    coupon_code: code,
                  },
                  result.cart,
                )
              }
              return result
            }}
          />
        )

      case 'youtube':
        return (
          <YouTubeWidget
            config={widgetConfig as Parameters<typeof YouTubeWidget>[0]['config']}
            widgetSettings={youtubeWidgetSettings}
            globalValues={globalValues}
            language={botLanguage}
          />
        )

      case 'gallery':
        return (
          <GalleryWidget
            config={widgetConfig as Parameters<typeof GalleryWidget>[0]['config']}
            widgetSettings={galleryWidgetSettings}
            globalValues={globalValues}
            language={botLanguage}
          />
        )

      case 'bundle_builder':
        return (
          <BundleBuilderWidget
            config={widgetConfig as Parameters<typeof BundleBuilderWidget>[0]['config']}
            widgetId={widgetId ?? undefined}
            widgetSettings={bundleBuilderWidgetSettings}
            globalValues={globalValues}
            onBuildBundle={handleBundleBuild}
            onSwapItem={handleBundleSwapItem}
            onAddToCart={handleBundleAddToCart}
            primaryColor={globalValues.colors?.primary || '#3BC2D0'}
            isRtl={isRTL}
            language={botLanguage}
          />
        )

      default:
        console.warn('Unknown widget type:', type)
        return null
    }
  }

  return (
    <AnimatePresence mode="wait">
      <motion.div
        key={widget.id || type}
        className="widget-container my-2"
        initial={{ opacity: 0, y: 10 }}
        animate={{ opacity: 1, y: 0 }}
        exit={{ opacity: 0, y: -10 }}
        transition={{ duration: 0.2 }}
      >
        {renderWidget()}
      </motion.div>
    </AnimatePresence>
  )
}

export default WidgetRenderer

