import { useState, useEffect, useRef } from 'react'
import { useNavigate } from 'react-router-dom'
import { t, sprintf } from '@/lib/i18n'
import { Save, Bot, FileSearch, Loader2, MessageSquare, Smartphone, AlertTriangle, Bell, CheckCircle2, AlertCircle, Sparkles, ExternalLink, Shield, Download, Upload, FolderArchive, Globe, Wifi, WifiOff, RefreshCw } from 'lucide-react'
import { useSettings, useUpdateSettings } from '@/hooks/useSettings'
import { useLanguage } from '@/contexts/LanguageContext'
import { useWizardCompletionStatus } from '@/hooks/useWizardCompletionStatus'
import { PageHeader } from '@/components/layout/PageHeader'
import { Card, CardHeader, CardTitle, CardContent } from '@/components/common/Card'
import { Button } from '@/components/common/Button'
import { PageLoading } from '@/components/common/Spinner'
import { ToggleSwitch } from '@/components/common/ToggleSwitch'
import { UnsavedChangesModal } from '@/components/common/UnsavedChangesModal'
import { ExternalKBKeys } from '@/components/settings/ExternalKBKeys'
import { useUnsavedChanges } from '@/hooks/useUnsavedChanges'
import { apiClient } from '@/api/client'
import type { BoostBotSettings } from '@/types/settings'

export function Settings() {
  const navigate = useNavigate()

  const { data, isLoading } = useSettings()
  const updateSettings = useUpdateSettings()
  const { enabledLanguages, labels, isMultilingual } = useLanguage()
  
  // Local state for form
  const [formData, setFormData] = useState<Partial<BoostBotSettings>>({})
  const [isDataLoaded, setIsDataLoaded] = useState(false)
  const [saveMessage, setSaveMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null)
  const skipNextDataSync = useRef(false)

  // NOTE (Week 27.7): BrandCard editor moved to "Knowledge Base" page.
  
  // Initialize form when data loads
  useEffect(() => {
    if (data?.data) {
      if (skipNextDataSync.current) {
        skipNextDataSync.current = false
        return
      }
      // IMPORTANT: Never keep masked secrets in form state.
      const initial = { ...data.data } as Partial<BoostBotSettings> & Record<string, unknown>
      delete (initial as any).backend_site_api_key
      delete (initial as any).api_key
      delete (initial as any).openai_api_key
      setFormData(initial)
      setIsDataLoaded(true)
    }
  }, [data])
  
  // Handle input change
  const handleChange = (field: keyof BoostBotSettings, value: unknown) => {
    setFormData(prev => ({ ...prev, [field]: value }))
  }
  
  // Save settings
  const handleSave = async () => {
    setSaveMessage(null)
    try {
      skipNextDataSync.current = true
      await updateSettings.mutateAsync(formData)
      setOriginalData()
      setSaveMessage({ type: 'success', text: t('Settings saved successfully!') })
      setTimeout(() => setSaveMessage(null), 3000)
    } catch (error) {
      skipNextDataSync.current = false
      setSaveMessage({ type: 'error', text: t('Error saving settings') })
    }
  }

  // Unsaved changes detection
  const {
    hasUnsavedChanges,
    setOriginalData,
    showModal: showUnsavedModal,
    saveError,
    modalActions,
  } = useUnsavedChanges({
    currentData: formData,
    onSave: async () => { await handleSave() },
    onDiscard: (original) => {
      setFormData(original)
    },
    isLoaded: isDataLoaded,
  })
  
  if (isLoading) {
    return <PageLoading />
  }
  
  const settings = data?.data
  const isFrozen = false
  // Trace logs feature archived — see boostbot/_archive/trace-logs/
  
  return (
    <div className="space-y-6 animate-fade-in">
      {/* Unsaved Changes Modal */}
      <UnsavedChangesModal
        isOpen={showUnsavedModal}
        onCancel={modalActions.onCancel}
        onDiscard={modalActions.onDiscard}
        onSave={modalActions.onSave}
        onSaveAlways={modalActions.onSaveAlways}
        isSaving={updateSettings.isPending}
        errorMessage={saveError}
      />

      <PageHeader
        title={t('Settings')}
        subtitle={t('Chatbot configuration')}
      >
        <div className="flex items-center gap-3">
          {saveMessage && (
            <span className={`text-sm ${saveMessage.type === 'success' ? 'text-green-600' : 'text-red-600'}`}>
              {saveMessage.type === 'success' ? '✓' : '✗'} {saveMessage.text}
            </span>
          )}
          <button
            onClick={handleSave}
            disabled={!hasUnsavedChanges || updateSettings.isPending || isFrozen}
            className={`flex items-center gap-2 px-4 py-2 rounded-lg transition-all disabled:opacity-50 disabled:cursor-not-allowed ${
              hasUnsavedChanges
                ? 'bg-amber-500 hover:bg-amber-600 animate-pulse'
                : 'bg-primary-600 hover:bg-primary-700'
            } text-white`}
          >
            {updateSettings.isPending ? (
              <Loader2 className="w-4 h-4 animate-spin" />
            ) : (
              <Save className="w-4 h-4" />
            )}
            {updateSettings.isPending ? t('Saving...') : hasUnsavedChanges ? t('Save Changes') : t('Save')}
          </button>
        </div>
      </PageHeader>

      {/* Unsaved changes indicator */}
      {hasUnsavedChanges && (
        <div className="fixed bottom-4 left-4 bg-amber-100 text-amber-800 px-4 py-2 rounded-lg shadow-lg flex items-center gap-2 text-sm z-40">
          <AlertTriangle className="w-4 h-4" />
          {t('You have unsaved changes')}
        </div>
      )}

      {/* Connection Status */}
      <ConnectionStatusCard />

      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
        {/* General Settings */}
        <Card data-wizard-id="general-settings">
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Bot className="w-5 h-5" />
              {t('General Settings')}
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="flex items-center justify-between">
              <div>
                <label className="text-sm font-medium text-gray-700">
                  {t('Enable Chatbot')}
                </label>
                <p className="text-xs text-gray-500">{t('Bot will appear on the site')}</p>
              </div>
              <ToggleSwitch
                checked={Boolean(formData.is_active ?? true)}
                onChange={(v) => handleChange('is_active', v)}
                disabled={isFrozen}
                ariaLabel={t('Enable Chatbot')}
              />
            </div>
            
            <div className="flex items-center justify-between">
              <div>
                <label className="text-sm font-medium text-gray-700">
                  {t('Proactive messages on page transitions')}
                </label>
                <p className="text-xs text-gray-500">{t('When a visitor navigates to a page with a different bot, the bot will offer help in the new context')}</p>
              </div>
              <ToggleSwitch
                checked={Boolean((formData as any).page_transition_triggers_enabled ?? settings?.page_transition_triggers_enabled ?? true)}
                onChange={(v) => handleChange('page_transition_triggers_enabled' as any, v)}
                disabled={isFrozen}
                ariaLabel={t('Proactive messages on page transitions')}
              />
            </div>
          </CardContent>
        </Card>

        {/* Message Limits */}
        <Card data-wizard-id="message-limits">
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <MessageSquare className="w-5 h-5" />
              {t('Message Limits (characters)')}
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="flex items-center justify-between">
              <div>
                <label className="text-sm font-medium text-gray-700">{t('Visitor input character limit')}</label>
                <p className="text-xs text-gray-500">{t('Limits how many characters a visitor can type per message')}</p>
              </div>
              <ToggleSwitch
                checked={Boolean((formData as any).visitor_input_char_limit_enabled ?? settings?.visitor_input_char_limit_enabled ?? true)}
                onChange={(v) => handleChange('visitor_input_char_limit_enabled' as any, v)}
                disabled={isFrozen}
                ariaLabel={t('Visitor input character limit')}
              />
            </div>

            <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-1">{t('Input character limit (default 500)')}</label>
                <input
                  type="number"
                  min={1}
                  max={5000}
                  value={Number((formData as any).visitor_input_char_limit ?? settings?.visitor_input_char_limit ?? 500)}
                  onChange={(e) => handleChange('visitor_input_char_limit' as any, Number(e.target.value))}
                  disabled={isFrozen}
                  className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500 disabled:bg-gray-100"
                />
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-1">{t('Bot reply word limit (global, default 150)')}</label>
                <input
                  type="number"
                  min={1}
                  max={5000}
                  value={Number((formData as any).bot_output_char_limit_global ?? settings?.bot_output_char_limit_global ?? 150)}
                  onChange={(e) => handleChange('bot_output_char_limit_global' as any, Number(e.target.value))}
                  disabled={isFrozen}
                  className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500 disabled:bg-gray-100"
                />
              </div>
            </div>

            <div className="p-3 bg-blue-50 rounded-lg text-sm text-blue-700">
              <p className="font-medium mb-1">💡 {t('Note')}</p>
              <p>{t('You can set a lower word limit per bot (not higher than the global limit). The value is in words.')}</p>
              <p className="mt-1">{t('Widgets (forms, galleries, product cards, etc.) are not counted toward the word limit. The bot will always show relevant widgets even if the text response is short.')}</p>
            </div>
          </CardContent>
        </Card>

        {/* Setup Wizard Section */}
        <SetupWizardSection
          settings={settings}
          formData={formData}
          isFrozen={isFrozen}
          onNavigate={(path) => navigate(path)}
          onChangeFloatingWizard={(v) => {
            handleChange('floating_wizard_enabled', v)
            if (v && settings?.onboarding_completed) {
              handleChange('onboarding_completed', false)
            }
            const payload: Partial<BoostBotSettings> = { floating_wizard_enabled: v }
            if (v && settings?.onboarding_completed) {
              (payload as any).onboarding_completed = false
            }
            skipNextDataSync.current = true
            updateSettings.mutateAsync(payload)
          }}
        />

        {/* Mobile Layout Settings */}
        <Card data-wizard-id="mobile-settings">
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Smartphone className="w-5 h-5" />
              {t('Mobile Settings')}
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="flex items-center justify-between">
              <div>
                <label className="text-sm font-medium text-gray-700">
                  {t('Show on Mobile')}
                </label>
                <p className="text-xs text-gray-500">{t('Bot will appear on mobile devices')}</p>
              </div>
              <ToggleSwitch
                checked={Boolean(formData.show_on_mobile ?? true)}
                onChange={(v) => handleChange('show_on_mobile', v)}
                disabled={isFrozen}
                ariaLabel={t('Show on Mobile')}
              />
            </div>

            <div className="border-t border-gray-100 pt-4">
              <h4 className="text-sm font-medium text-gray-700 mb-3">{t('Mobile chat window position and size')}</h4>
              <p className="text-xs text-gray-500 mb-4">
                {t('Settings use vw/vh units (percentage of screen width/height) to ensure consistent display across all devices')}
              </p>
              
              {(() => {
                // Get current values with defaults
                const widthVw = Number((formData as any).mobile_layout_width_vw ?? settings?.mobile_layout_width_vw ?? 94);
                const heightVh = Number((formData as any).mobile_layout_height_vh ?? settings?.mobile_layout_height_vh ?? 75);
                const marginTopVh = Number((formData as any).mobile_layout_margin_top_vh ?? settings?.mobile_layout_margin_top_vh ?? 20);
                const marginBottomVh = Number((formData as any).mobile_layout_margin_bottom_vh ?? settings?.mobile_layout_margin_bottom_vh ?? 5);
                
                // Calculate remaining space and auto side margin
                const remainingVh = 100 - heightVh;
                const sideMarginVw = (100 - widthVw) / 2;
                
                // Handlers for linked margin controls
                const handleHeightChange = (newHeight: number) => {
                  const newRemaining = 100 - newHeight;
                  // Distribute remaining: 80% top, 20% bottom (default ratio)
                  const newTop = Math.round(newRemaining * 0.8);
                  const newBottom = newRemaining - newTop;
                  setFormData(prev => ({
                    ...prev,
                    mobile_layout_height_vh: newHeight,
                    mobile_layout_margin_top_vh: Math.max(2, newTop),
                    mobile_layout_margin_bottom_vh: Math.max(2, newBottom),
                  }));
                };
                
                const handleTopChange = (newTop: number) => {
                  const newBottom = Math.max(2, remainingVh - newTop);
                  setFormData(prev => ({
                    ...prev,
                    mobile_layout_margin_top_vh: newTop,
                    mobile_layout_margin_bottom_vh: newBottom,
                  }));
                };
                
                const handleBottomChange = (newBottom: number) => {
                  const newTop = Math.max(2, remainingVh - newBottom);
                  setFormData(prev => ({
                    ...prev,
                    mobile_layout_margin_top_vh: newTop,
                    mobile_layout_margin_bottom_vh: newBottom,
                  }));
                };
                
                return (
                  <div className="space-y-4">
                    {/* Width */}
                    <div>
                      <div className="flex items-center justify-between mb-1">
                        <label className="text-sm font-medium text-gray-700">{t('Window width (vw)')}</label>
                        <span className="text-sm text-gray-500 font-mono">
                          {widthVw}vw
                          <span className="text-xs text-gray-400 ms-2">{sprintf(t('(margins: %svw each side)'), sideMarginVw.toFixed(1))}</span>
                        </span>
                      </div>
                      <input
                        type="range"
                        min={70}
                        max={100}
                        step={1}
                        value={widthVw}
                        onChange={(e) => handleChange('mobile_layout_width_vw' as any, Number(e.target.value))}
                        disabled={isFrozen}
                        className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary-500"
                      />
                      <p className="text-xs text-gray-400 mt-1">{t('Recommended: 90-96vw (side margins calculated automatically)')}</p>
                    </div>

                    {/* Height */}
                    <div>
                      <div className="flex items-center justify-between mb-1">
                        <label className="text-sm font-medium text-gray-700">{t('Window height (vh)')}</label>
                        <span className="text-sm text-gray-500 font-mono">
                          {heightVh}vh
                          <span className="text-xs text-gray-400 ms-2">{sprintf(t('(remaining: %svh to distribute)'), remainingVh)}</span>
                        </span>
                      </div>
                      <input
                        type="range"
                        min={50}
                        max={90}
                        step={1}
                        value={heightVh}
                        onChange={(e) => handleHeightChange(Number(e.target.value))}
                        disabled={isFrozen}
                        className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary-500"
                      />
                      <p className="text-xs text-gray-400 mt-1">{t('Recommended: 70-80vh (leaves room for site header)')}</p>
                    </div>

                    {/* Linked Top/Bottom Margins */}
                    <div className="p-3 bg-gray-50 rounded-lg space-y-3">
                      <div className="flex items-center justify-between">
                        <span className="text-xs font-medium text-gray-600">{sprintf(t('Vertical margin distribution (%svh)'), remainingVh)}</span>
                      </div>
                      
                      {/* Top Margin */}
                      <div>
                        <div className="flex items-center justify-between mb-1">
                          <label className="text-sm font-medium text-gray-700">{t('Top margin')}</label>
                          <span className="text-sm text-gray-500 font-mono">{marginTopVh}vh</span>
                        </div>
                        <input
                          type="range"
                          min={2}
                          max={Math.max(2, remainingVh - 2)}
                          step={1}
                          value={marginTopVh}
                          onChange={(e) => handleTopChange(Number(e.target.value))}
                          disabled={isFrozen}
                          className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary-500"
                        />
                        <p className="text-xs text-gray-400 mt-1">{t('Recommended: 15-20vh (leaves room for site header)')}</p>
                      </div>

                      {/* Bottom Margin */}
                      <div>
                        <div className="flex items-center justify-between mb-1">
                          <label className="text-sm font-medium text-gray-700">{t('Bottom margin')}</label>
                          <span className="text-sm text-gray-500 font-mono">{marginBottomVh}vh</span>
                        </div>
                        <input
                          type="range"
                          min={2}
                          max={Math.max(2, remainingVh - 2)}
                          step={1}
                          value={marginBottomVh}
                          onChange={(e) => handleBottomChange(Number(e.target.value))}
                          disabled={isFrozen}
                          className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary-500"
                        />
                        <p className="text-xs text-gray-400 mt-1">{t('Recommended: 3-8vh')}</p>
                      </div>
                    </div>
                  </div>
                );
              })()}
            </div>

            <div className="p-3 bg-blue-50 rounded-lg text-sm text-blue-700">
              <p className="font-medium mb-1">💡 {t('Explanation')}</p>
              <p>{t('On mobile, the chat window is automatically centered and ignores the bubble position to ensure the chat is always displayed within the screen and not clipped.')}</p>
            </div>
          </CardContent>
        </Card>

        {/* Low Credits Alert */}
        <Card data-wizard-id="low-credits-alert">
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Bell className="w-5 h-5" />
              {t('Low BoostCoin Alert')}
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <p className="text-sm text-gray-600">
              {t('Get notified when your purchased (cumulative) BoostCoin balance drops below a defined threshold.')}
            </p>

            <div>
              <label className="block text-sm font-medium text-gray-700 mb-1">{t('Alert threshold (default: 100 BoostCoin)')}</label>
              <input
                type="number"
                min={0}
                max={100000}
                value={Number((formData as any).low_credits_threshold ?? settings?.low_credits_threshold ?? 100)}
                onChange={(e) => handleChange('low_credits_threshold' as any, Number(e.target.value))}
                disabled={isFrozen}
                className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500 disabled:bg-gray-100"
              />
              <p className="text-xs text-gray-400 mt-1">{t('Set to 0 to disable the alert entirely')}</p>
            </div>

            <div className="flex items-center justify-between">
              <div>
                <label className="text-sm font-medium text-gray-700">{t('Also send email alert')}</label>
                <p className="text-xs text-gray-500">{t('An email will be sent to the site admin once per threshold crossing')}</p>
              </div>
              <ToggleSwitch
                checked={Boolean((formData as any).low_credits_email_enabled ?? settings?.low_credits_email_enabled ?? true)}
                onChange={(v) => handleChange('low_credits_email_enabled' as any, v)}
                disabled={isFrozen}
                ariaLabel={t('Send email alert')}
              />
            </div>

            <div className="p-3 bg-blue-50 rounded-lg text-sm text-blue-700">
              <p className="font-medium mb-1">💡 {t('How does it work?')}</p>
              <p>{t('The system checks your BoostCoin balance every 6 hours. When the balance drops below the threshold, an alert will appear in the admin panel and an email will be sent (if enabled). The alert will not repeat until you purchase new BoostCoin.')}</p>
            </div>
          </CardContent>
        </Card>

        {/* Content Indexing */}
        <IndexingSettings />

        {/* Per-Visitor Message Rate Limiting */}
        <Card data-wizard-id="visitor-message-limits">
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Shield className="w-5 h-5" />
              {t('Visitor Message Rate Limiting')}
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <p className="text-sm text-gray-600">
              {t('Limit the number of messages a visitor can send to the chatbot per hour and day, to prevent abuse and excessive BoostCoin consumption.')}
            </p>

            {/* Enable / Disable */}
            <div className="flex items-center justify-between">
              <div>
                <label className="text-sm font-medium text-gray-700">{t('Enable message rate limiting')}</label>
                <p className="text-xs text-gray-500">{t('Limit the number of messages per visitor by hour and day')}</p>
              </div>
              <ToggleSwitch
                checked={Boolean((formData as any).visitor_message_limit_enabled ?? settings?.visitor_message_limit_enabled ?? true)}
                onChange={(v) => handleChange('visitor_message_limit_enabled' as any, v)}
                disabled={isFrozen}
                ariaLabel={t('Enable visitor message rate limiting')}
              />
            </div>

            {/* Hourly / Daily limits */}
            <div className="grid grid-cols-2 gap-4">
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-1">{t('Max messages per hour')}</label>
                <input
                  type="number"
                  min={5}
                  max={500}
                  value={Number((formData as any).visitor_messages_per_hour ?? settings?.visitor_messages_per_hour ?? 50)}
                  onChange={(e) => handleChange('visitor_messages_per_hour' as any, Number(e.target.value))}
                  disabled={isFrozen || !Boolean((formData as any).visitor_message_limit_enabled ?? settings?.visitor_message_limit_enabled ?? true)}
                  className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500 disabled:bg-gray-100"
                />
                <p className="text-xs text-gray-400 mt-1">{t('Default: 50 (enough for 3-4 intensive conversations per hour)')}</p>
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-1">{t('Max messages per day')}</label>
                <input
                  type="number"
                  min={10}
                  max={5000}
                  value={Number((formData as any).visitor_messages_per_day ?? settings?.visitor_messages_per_day ?? 200)}
                  onChange={(e) => handleChange('visitor_messages_per_day' as any, Number(e.target.value))}
                  disabled={isFrozen || !Boolean((formData as any).visitor_message_limit_enabled ?? settings?.visitor_message_limit_enabled ?? true)}
                  className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500 disabled:bg-gray-100"
                />
                <p className="text-xs text-gray-400 mt-1">{t('Default: 200')}</p>
              </div>
            </div>

            {/* Cooldown toggle */}
            <div className="flex items-center justify-between border-t border-gray-100 pt-4">
              <div>
                <label className="text-sm font-medium text-gray-700">{t('Auto Cooldown')}</label>
                <p className="text-xs text-gray-500">{t('Automatically slow down rapid message sending (5+ messages in 30 seconds)')}</p>
              </div>
              <ToggleSwitch
                checked={Boolean((formData as any).visitor_cooldown_enabled ?? settings?.visitor_cooldown_enabled ?? true)}
                onChange={(v) => handleChange('visitor_cooldown_enabled' as any, v)}
                disabled={isFrozen}
                ariaLabel={t('Auto Cooldown')}
              />
            </div>

            {/* Spam alert toggles */}
            <div className="border-t border-gray-100 pt-4 space-y-3">
              <h4 className="text-sm font-medium text-gray-700">{t('Spam Alerts')}</h4>
              <div className="flex items-center justify-between">
                <div>
                  <label className="text-sm font-medium text-gray-700">{t('Spam alert in admin panel')}</label>
                  <p className="text-xs text-gray-500">{t('Show alert when a visitor hits the limit suspiciously (3+ times in 24 hours)')}</p>
                </div>
                <ToggleSwitch
                  checked={Boolean((formData as any).spam_alert_enabled ?? settings?.spam_alert_enabled ?? true)}
                  onChange={(v) => handleChange('spam_alert_enabled' as any, v)}
                  disabled={isFrozen}
                  ariaLabel={t('Spam alert')}
                />
              </div>
              <div className="flex items-center justify-between">
                <div>
                  <label className="text-sm font-medium text-gray-700">{t('Send spam alert via email')}</label>
                  <p className="text-xs text-gray-500">{t('Email the site admin when a spam pattern is detected (once per 24 hours per visitor)')}</p>
                </div>
                <ToggleSwitch
                  checked={Boolean((formData as any).spam_alert_email_enabled ?? settings?.spam_alert_email_enabled ?? true)}
                  onChange={(v) => handleChange('spam_alert_email_enabled' as any, v)}
                  disabled={isFrozen || !Boolean((formData as any).spam_alert_enabled ?? settings?.spam_alert_enabled ?? true)}
                  ariaLabel={t('Send spam alert via email')}
                />
              </div>
            </div>

            <div className="p-3 bg-blue-50 rounded-lg text-sm text-blue-700">
              <p className="font-medium mb-1">💡 {t('How does it work?')}</p>
              <p>{t('Each visitor is identified by IP address. When a visitor exceeds the limit, they receive a friendly message from the bot and are temporarily blocked. If a visitor hits the hourly limit 3+ times per day, the system identifies it as potential spam and sends you an alert.')}</p>
            </div>
          </CardContent>
        </Card>

        {/* Primary Language */}
        {isMultilingual && (
          <Card>
            <CardHeader>
              <CardTitle className="flex items-center gap-2">
                <Globe className="w-5 h-5 text-[#3BC2D0]" />
                {t('Primary Language')}
              </CardTitle>
            </CardHeader>
            <CardContent className="space-y-4">
              <p className="text-sm text-gray-600">
                {t('The default language used when no specific language is detected (e.g. for new records, fallback content).')}
              </p>
              <select
                value={(formData as any).primary_language ?? settings?.primary_language ?? ''}
                onChange={(e) => handleChange('primary_language' as any, e.target.value)}
                disabled={isFrozen}
                className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-[#3BC2D0] focus:border-[#3BC2D0] disabled:bg-gray-100"
              >
                <option value="">{t('Auto-detect from site locale')}</option>
                {enabledLanguages.map((lang) => (
                  <option key={lang} value={lang}>{labels[lang] || lang.toUpperCase()}</option>
                ))}
              </select>
            </CardContent>
          </Card>
        )}

        {/* External KB Access ("גישה חיצונית ל-KB") */}
        <ExternalKBKeys />

        {/* Import / Export */}
        <ImportExportSettings />
      </div>
    </div>
  )
}

/**
 * Connection Status Card
 *
 * Shows whether the backend is reachable from this WordPress site.
 * Fetches the status from the /settings/connection-status endpoint.
 */
function ConnectionStatusCard() {
  const [status, setStatus] = useState<'checking' | 'connected' | 'no_config' | 'unreachable' | 'error'>('checking')
  const [details, setDetails] = useState<{ site_id?: string; backend_url?: string; message?: string }>({})
  const [isRefreshing, setIsRefreshing] = useState(false)

  const fetchStatus = async () => {
    try {
      const res = await apiClient.get<{ data: { status: string; site_id: string; backend_url: string; message: string } }>('settings/connection-status')
      if (res.data) {
        setStatus(res.data.status as typeof status)
        setDetails(res.data)
      }
    } catch {
      setStatus('error')
    }
  }

  useEffect(() => { fetchStatus() }, [])

  const handleRefresh = async () => {
    setIsRefreshing(true)
    setStatus('checking')
    await fetchStatus()
    setIsRefreshing(false)
  }

  return (
    <Card>
      <CardContent className="py-4">
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            {status === 'checking' && (
              <>
                <div className="w-9 h-9 rounded-full bg-gray-100 flex items-center justify-center">
                  <Loader2 className="w-5 h-5 text-gray-400 animate-spin" />
                </div>
                <div>
                  <p className="text-sm font-medium text-gray-600">{t('Checking connection...')}</p>
                </div>
              </>
            )}
            {status === 'connected' && (
              <>
                <div className="w-9 h-9 rounded-full bg-green-100 flex items-center justify-center">
                  <Wifi className="w-5 h-5 text-green-600" />
                </div>
                <div>
                  <p className="text-sm font-medium text-green-700">{t('Connected to BoostBot Cloud')}</p>
                  <p className="text-xs text-gray-500">
                    {t('Site ID')}: {details.site_id?.substring(0, 8)}...
                  </p>
                </div>
              </>
            )}
            {status === 'no_config' && (
              <>
                <div className="w-9 h-9 rounded-full bg-yellow-100 flex items-center justify-center">
                  <AlertTriangle className="w-5 h-5 text-yellow-600" />
                </div>
                <div>
                  <p className="text-sm font-medium text-yellow-700">{t('Not connected')}</p>
                  <p className="text-xs text-gray-500">
                    {t('The BoostBot backend is not configured. The chat widget will not appear on your site until a connection is established.')}
                  </p>
                </div>
              </>
            )}
            {(status === 'unreachable' || status === 'error') && (
              <>
                <div className="w-9 h-9 rounded-full bg-red-100 flex items-center justify-center">
                  <WifiOff className="w-5 h-5 text-red-600" />
                </div>
                <div>
                  <p className="text-sm font-medium text-red-700">{t('Backend unreachable')}</p>
                  <p className="text-xs text-gray-500">
                    {details.message || t('Could not connect to the backend. The chat widget is hidden until the connection is restored.')}
                  </p>
                </div>
              </>
            )}
          </div>
          <button
            onClick={handleRefresh}
            disabled={isRefreshing}
            className="p-2 rounded-lg hover:bg-gray-100 transition-colors disabled:opacity-50"
            title={t('Refresh')}
          >
            <RefreshCw className={`w-4 h-4 text-gray-500 ${isRefreshing ? 'animate-spin' : ''}`} />
          </button>
        </div>
      </CardContent>
    </Card>
  )
}

/**
 * Setup Wizard Section
 * 
 * Displays critical step checklist and a toggle for the floating wizard.
 * Rendered as a card within the general settings grid.
 */
function SetupWizardSection(props: {
  settings: BoostBotSettings | undefined
  formData: Partial<BoostBotSettings>
  isFrozen: boolean
  onNavigate: (path: string) => void
  onChangeFloatingWizard: (enabled: boolean) => void
}) {
  const { settings, formData } = props

  const { criticalSteps, completedCount, totalCritical, isLoading: completionLoading } = useWizardCompletionStatus()

  const floatingWizardEnabled = Boolean(formData.floating_wizard_enabled ?? settings?.floating_wizard_enabled ?? true)
  const isOnboardingDone = Boolean(settings?.onboarding_completed)

  return (
    <Card className="lg:col-span-2" data-wizard-id="wizard-section">
      <CardHeader>
        <CardTitle className="flex items-center justify-between gap-3">
          <span className="flex items-center gap-2">
            <Sparkles className="w-5 h-5 text-[#3BC2D0]" />
            {t('Installation Wizard')}
          </span>
          {completionLoading ? (
            <span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-600">
              <Loader2 className="w-3 h-3 animate-spin me-1" />
              {t('Checking...')}
            </span>
          ) : (
            <span
              className={`inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${
                completedCount === totalCritical
                  ? 'bg-green-100 text-green-800'
                  : 'bg-yellow-100 text-yellow-800'
              }`}
            >
              {sprintf(t('%d/%d critical steps completed'), completedCount, totalCritical)}
            </span>
          )}
        </CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        {/* Critical steps checklist */}
        {completedCount === totalCritical ? (
          <div className="p-4 bg-green-50 border border-green-200 rounded-lg text-sm text-green-800">
            <p className="font-medium mb-2">{t('All critical steps completed!')}</p>
            <ul className="space-y-1.5">
              {criticalSteps.map((step) => (
                <li key={step.id} className="flex items-start gap-2">
                  <CheckCircle2 className="w-5 h-5 text-green-500 mt-0.5 shrink-0" />
                  <div className="flex-1 min-w-0">
                    <span className="font-medium text-green-800">{step.name}</span>
                    <span className="text-sm mx-1 text-green-700">— {step.description}</span>
                  </div>
                </li>
              ))}
            </ul>
          </div>
        ) : (
          <div className="p-4 bg-yellow-50 border border-yellow-200 rounded-lg text-sm text-yellow-800">
            <p className="font-medium mb-2">{t('Critical steps:')}</p>
            <ul className="space-y-1.5">
              {criticalSteps.map((step) => (
                <li key={step.id} className="flex items-start gap-2">
                  {step.completed ? (
                    <CheckCircle2 className="w-5 h-5 text-green-500 mt-0.5 shrink-0" />
                  ) : (
                    <AlertCircle className="w-5 h-5 text-yellow-500 mt-0.5 shrink-0" />
                  )}
                  <div className="flex-1 min-w-0">
                    <span className={`font-medium ${step.completed ? 'text-green-800' : 'text-yellow-800'}`}>
                      {step.name}
                    </span>
                    <span className={`text-sm mx-1 ${step.completed ? 'text-green-700' : 'text-yellow-700'}`}>
                      — {step.description}
                    </span>
                    {!step.completed && step.link && (
                      <button
                        type="button"
                        onClick={() => props.onNavigate(step.link!)}
                        className="text-sm text-primary-600 hover:text-primary-700 underline underline-offset-2 ms-1"
                      >
                        {t('Configure')} ←
                      </button>
                    )}
                  </div>
                </li>
              ))}
            </ul>
          </div>
        )}

        {/* Floating wizard toggle */}
        <div className="flex items-center justify-between pt-2 border-t border-gray-100">
          <div>
            <label className="text-sm font-medium text-gray-700">{t('Show floating installation wizard')}</label>
            <p className="text-xs text-gray-500">
              {isOnboardingDone && !floatingWizardEnabled
                ? t('Installation completed — enable to restart')
                : t('A floating navigation panel that guides you through all installation steps')
              }
            </p>
          </div>
          <ToggleSwitch
            checked={floatingWizardEnabled}
            onChange={props.onChangeFloatingWizard}
            disabled={props.isFrozen}
            ariaLabel={t('Show floating installation wizard')}
          />
        </div>
      </CardContent>
    </Card>
  )
}

/**
 * Indexing Settings Component
 * Allows re-indexing site content with enhanced specs and prices
 */
function IndexingSettings() {
  const navigate = useNavigate()
  const [stats, setStats] = useState<{
    total_indexed: number
    with_specs: number
    with_prices: number
    last_indexed: string | null
  } | null>(null)
  const [isLoading, setIsLoading] = useState(true)
  
  // Load index stats
  useEffect(() => {
    const loadStats = async () => {
      try {
        const response = await apiClient.get<{ data: typeof stats }>('index/status')
        if (response.data) {
          setStats(response.data)
        }
      } catch (error) {
        console.error('Failed to load index stats:', error)
        // Set defaults if endpoint fails
        setStats({
          total_indexed: 0,
          with_specs: 0,
          with_prices: 0,
          last_indexed: null
        })
      } finally {
        setIsLoading(false)
      }
    }
    loadStats()
  }, [])
  
  if (isLoading) {
    return (
      <Card>
        <CardContent className="py-8 text-center text-gray-500">
          {t('Loading...')}
        </CardContent>
      </Card>
    )
  }
  
  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <FileSearch className="w-5 h-5" />
          {t('Content Indexing')}
        </CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        <p className="text-sm text-gray-600">
          {t('Re-index all site content including technical specifications and prices')}
        </p>
        
        {/* Stats Grid */}
        <div className="grid grid-cols-3 gap-4">
          <div className="text-center p-4 bg-gray-50 rounded-lg">
            <div className="text-2xl font-bold text-primary-600">{stats?.total_indexed || 0}</div>
            <div className="text-sm text-gray-500">{t('Pages Indexed')}</div>
          </div>
          <div className="text-center p-4 bg-gray-50 rounded-lg">
            <div className="text-2xl font-bold text-green-600">{stats?.with_specs || 0}</div>
            <div className="text-sm text-gray-500">{t('With Technical Specs')}</div>
          </div>
          <div className="text-center p-4 bg-gray-50 rounded-lg">
            <div className="text-2xl font-bold text-accent-600">{stats?.with_prices || 0}</div>
            <div className="text-sm text-gray-500">{t('With Prices')}</div>
          </div>
        </div>
        
        {/* Last Indexed */}
        {stats?.last_indexed && (
          <p className="text-sm text-gray-500">
            {sprintf(t('Last indexed: %s'), new Date(stats.last_indexed).toLocaleString())}
          </p>
        )}
        
        {/* Navigate to Knowledge Base */}
        <Button
          onClick={() => navigate('/knowledge-base')}
        >
          <ExternalLink className="w-4 h-4 me-2" />
          {t('Go to Knowledge Base')}
        </Button>
        
        {/* Info */}
        <div className="p-3 bg-blue-50 rounded-lg text-sm text-blue-800">
          <p className="font-medium mb-1">{t('What does enhanced indexing include?')}</p>
          <ul className="list-disc list-inside space-y-1 text-blue-700">
            <li>{t('Full content from Elementor pages')}</li>
            <li>{t('Technical specifications from tables and products')}</li>
            <li>{t('Prices and inventory information from WooCommerce')}</li>
            <li>{t('Smart summaries for accurate answers')}</li>
          </ul>
        </div>
      </CardContent>
    </Card>
  )
}

/**
 * Import / Export Settings Component
 *
 * Allows exporting and importing plugin configuration and data as JSON.
 */
function ImportExportSettings() {
  const [exportingConfig, setExportingConfig] = useState(false)
  const [exportingData, setExportingData] = useState(false)
  const [importingConfig, setImportingConfig] = useState(false)
  const [importingData, setImportingData] = useState(false)
  const [importMode, setImportMode] = useState<'skip' | 'replace'>('skip')
  const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null)
  const configFileRef = useRef<HTMLInputElement>(null)
  const dataFileRef = useRef<HTMLInputElement>(null)

  const showMessage = (type: 'success' | 'error', text: string) => {
    setMessage({ type, text })
    setTimeout(() => setMessage(null), 5000)
  }

  const doExport = async (type: 'config' | 'data') => {
    const setLoading = type === 'config' ? setExportingConfig : setExportingData
    setLoading(true)
    try {
      const response = await apiClient.get<{ data: Record<string, unknown> }>(`backup/export/${type}`)
      if (!response.data) throw new Error('Empty response')

      const blob = new Blob([JSON.stringify(response.data, null, 2)], { type: 'application/json' })
      const filename = `boostbot-${type}-${new Date().toISOString().slice(0, 10)}.json`
      const url = URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      a.download = filename
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
      URL.revokeObjectURL(url)

      showMessage('success', type === 'config' ? t('Config exported successfully!') : t('Data exported successfully!'))
    } catch {
      showMessage('error', t('Error exporting'))
    } finally {
      setLoading(false)
    }
  }

  const doImport = async (type: 'config' | 'data', file: File) => {
    const setLoading = type === 'config' ? setImportingConfig : setImportingData
    setLoading(true)
    try {
      const text = await file.text()
      const json = JSON.parse(text)

      // Validate export_type
      const expectedType = type === 'config' ? 'boostbot_config' : 'boostbot_data'
      if (json.export_type !== expectedType) {
        showMessage('error', sprintf(t('Invalid file. Expected: %s, found: %s'), expectedType, json.export_type || t('unknown')))
        return
      }

      const response = await apiClient.post<{ data: { imported: Record<string, number>; errors: string[] } }>(`backup/import/${type}?import_mode=${importMode}`, json)

      if (response.data) {
        const imported = response.data.imported || {}
        const errors = response.data.errors || []
        const totalItems = Object.values(imported).reduce((sum: number, v: number) => sum + v, 0)

        if (errors.length > 0) {
          showMessage('error', sprintf(t('Imported %d items with %d errors'), totalItems, errors.length))
        } else {
          showMessage('success', sprintf(t('Successfully imported %d items!'), totalItems))
        }
      }
    } catch {
      showMessage('error', t('Import error - please verify the file is valid'))
    } finally {
      setLoading(false)
    }
  }

  const handleFileSelect = (type: 'config' | 'data', e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (file) {
      if (importMode === 'replace') {
        const confirmed = window.confirm(t('Replace mode will overwrite any existing configuration that matches the imported data. Are you sure?'))
        if (!confirmed) {
          e.target.value = ''
          return
        }
      }
      doImport(type, file)
      e.target.value = ''
    }
  }

  return (
    <Card className="lg:col-span-2">
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <FolderArchive className="w-5 h-5" />
          {t('Import & Export')}
        </CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        {message && (
          <div className={`p-3 rounded-lg text-sm ${message.type === 'success' ? 'bg-green-50 text-green-800 border border-green-200' : 'bg-red-50 text-red-800 border border-red-200'}`}>
            {message.type === 'success' ? '✓' : '✗'} {message.text}
          </div>
        )}

        <div className="flex items-center gap-3 text-sm">
          <span className="font-medium text-gray-700">{t('Import mode:')}</span>
          <label className="flex items-center gap-1.5 cursor-pointer">
            <input
              type="radio"
              name="import_mode"
              value="skip"
              checked={importMode === 'skip'}
              onChange={() => setImportMode('skip')}
              className="accent-blue-600"
            />
            <span className="text-gray-600">{t('Skip existing data')}</span>
          </label>
          <label className="flex items-center gap-1.5 cursor-pointer">
            <input
              type="radio"
              name="import_mode"
              value="replace"
              checked={importMode === 'replace'}
              onChange={() => setImportMode('replace')}
              className="accent-amber-600"
            />
            <span className="text-gray-600">{t('Replace existing data')}</span>
          </label>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          {/* Configuration Export/Import */}
          <div className="border border-gray-200 rounded-lg p-4 space-y-3">
            <div className="flex items-center gap-2 text-sm font-medium text-gray-700">
              <span className="w-8 h-8 rounded-lg bg-blue-50 flex items-center justify-center text-blue-600">⚙️</span>
              {t('Plugin Configuration')}
            </div>
            <p className="text-xs text-gray-500">
              {t('Settings, widgets, bots, personalities, design, and additional configurations.')}
            </p>
            <div className="flex gap-2">
              <button
                onClick={() => doExport('config')}
                disabled={exportingConfig}
                className="flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-lg border border-blue-200 bg-blue-50 text-blue-700 hover:bg-blue-100 transition-colors disabled:opacity-50"
              >
                {exportingConfig ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Download className="w-3.5 h-3.5" />}
                {t('Export')}
              </button>
              <button
                onClick={() => configFileRef.current?.click()}
                disabled={importingConfig}
                className="flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-lg border border-gray-200 bg-white text-gray-700 hover:bg-gray-50 transition-colors disabled:opacity-50"
              >
                {importingConfig ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Upload className="w-3.5 h-3.5" />}
                {t('Import')}
              </button>
              <input
                ref={configFileRef}
                type="file"
                accept=".json"
                className="hidden"
                onChange={(e) => handleFileSelect('config', e)}
              />
            </div>
          </div>

          {/* Data Export/Import */}
          <div className="border border-gray-200 rounded-lg p-4 space-y-3">
            <div className="flex items-center gap-2 text-sm font-medium text-gray-700">
              <span className="w-8 h-8 rounded-lg bg-orange-50 flex items-center justify-center text-orange-600">📊</span>
              {t('Accumulated Data')}
            </div>
            <p className="text-xs text-gray-500">
              {t('Leads, conversations, meetings, contacts, analytics, and usage statistics.')}
            </p>
            <div className="flex gap-2">
              <button
                onClick={() => doExport('data')}
                disabled={exportingData}
                className="flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-lg border border-orange-200 bg-orange-50 text-orange-700 hover:bg-orange-100 transition-colors disabled:opacity-50"
              >
                {exportingData ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Download className="w-3.5 h-3.5" />}
                {t('Export')}
              </button>
              <button
                onClick={() => dataFileRef.current?.click()}
                disabled={importingData}
                className="flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-lg border border-gray-200 bg-white text-gray-700 hover:bg-gray-50 transition-colors disabled:opacity-50"
              >
                {importingData ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Upload className="w-3.5 h-3.5" />}
                {t('Import')}
              </button>
              <input
                ref={dataFileRef}
                type="file"
                accept=".json"
                className="hidden"
                onChange={(e) => handleFileSelect('data', e)}
              />
            </div>
          </div>
        </div>

        <div className="p-3 bg-blue-50 rounded-lg text-sm text-blue-700">
          <p className="font-medium mb-1">💡 {t('Note')}</p>
          <p>{t('Export does not include API keys, passwords, or sensitive tokens. Import will not overwrite existing data — duplicate records are automatically skipped.')}</p>
        </div>
      </CardContent>
    </Card>
  )
}
