import { useState, useEffect, useCallback } from 'react'
import { t, sprintf } from '@/lib/i18n'
import { KeyRound, Plus, Trash2, Copy, Check, Loader2, AlertTriangle, X } from 'lucide-react'
import { Card, CardHeader, CardTitle, CardContent } from '@/components/common/Card'
import { ToggleSwitch } from '@/components/common/ToggleSwitch'
import {
  externalKBApi,
  type ExternalKBKey,
  type CreateExternalKBKeyInput,
} from '@/api/external-kb'

const AVAILABLE_SCOPES = ['post', 'page', 'product'] as const

/**
 * External KB Access — settings section ("גישה חיצונית ל-KB").
 *
 * Manages API keys that let external systems (e.g. BoostCalendar's WhatsApp
 * bot) read this site's Knowledge Base via /kb/status, /kb/export and
 * /kb/retrieve. The raw key is displayed exactly once on creation.
 */
export function ExternalKBKeys() {
  const [keys, setKeys] = useState<ExternalKBKey[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [showCreateModal, setShowCreateModal] = useState(false)
  const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null)
  const [pendingDeleteId, setPendingDeleteId] = useState<string | null>(null)
  const [busyId, setBusyId] = useState<string | null>(null)

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

  const loadKeys = useCallback(async () => {
    try {
      const res = await externalKBApi.listKeys()
      setKeys(res.data?.keys || [])
    } catch {
      showMessage('error', t('Failed to load external KB keys'))
    } finally {
      setIsLoading(false)
    }
  }, [])

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

  const handleToggleEnabled = async (key: ExternalKBKey, enabled: boolean) => {
    setBusyId(key.id)
    try {
      await externalKBApi.updateKey(key.id, { enabled })
      setKeys(prev => prev.map(k => (k.id === key.id ? { ...k, enabled } : k)))
      showMessage('success', enabled ? t('Key enabled') : t('Key disabled'))
    } catch {
      showMessage('error', t('Failed to update key'))
    } finally {
      setBusyId(null)
    }
  }

  const handleDelete = async (id: string) => {
    setBusyId(id)
    try {
      await externalKBApi.deleteKey(id)
      setKeys(prev => prev.filter(k => k.id !== id))
      showMessage('success', t('Key deleted'))
    } catch {
      showMessage('error', t('Failed to delete key'))
    } finally {
      setBusyId(null)
      setPendingDeleteId(null)
    }
  }

  const formatDate = (iso: string | null) => {
    if (!iso) return t('Never')
    try {
      return new Date(iso).toLocaleString()
    } catch {
      return iso
    }
  }

  return (
    <Card className="lg:col-span-2">
      <CardHeader>
        <CardTitle className="flex items-center justify-between gap-3">
          <span className="flex items-center gap-2">
            <KeyRound className="w-5 h-5 text-[#3BC2D0]" />
            {t('External KB Access')}
          </span>
          <button
            onClick={() => setShowCreateModal(true)}
            className="flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-lg bg-primary-600 hover:bg-primary-700 text-white transition-colors"
          >
            <Plus className="w-4 h-4" />
            {t('Create Key')}
          </button>
        </CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        <p className="text-sm text-gray-600">
          {t('Allow external systems (such as a WhatsApp bot) to read the site knowledge base securely via scoped API keys. Keys can export content for periodic sync or retrieve answers live.')}
        </p>

        {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>
        )}

        {isLoading ? (
          <div className="py-6 text-center text-gray-500 flex items-center justify-center gap-2">
            <Loader2 className="w-4 h-4 animate-spin" />
            {t('Loading...')}
          </div>
        ) : keys.length === 0 ? (
          <div className="py-6 text-center text-sm text-gray-500 border border-dashed border-gray-200 rounded-lg">
            {t('No external keys yet. Create a key to connect an external system.')}
          </div>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="text-start text-xs text-gray-500 border-b border-gray-100">
                  <th className="py-2 px-2 text-start font-medium">{t('Label')}</th>
                  <th className="py-2 px-2 text-start font-medium">{t('Scopes')}</th>
                  <th className="py-2 px-2 text-start font-medium">{t('Permissions')}</th>
                  <th className="py-2 px-2 text-start font-medium">{t('Rate limit')}</th>
                  <th className="py-2 px-2 text-start font-medium">{t('Last used')}</th>
                  <th className="py-2 px-2 text-start font-medium">{t('Active')}</th>
                  <th className="py-2 px-2 text-start font-medium"></th>
                </tr>
              </thead>
              <tbody>
                {keys.map(key => (
                  <tr key={key.id} className="border-b border-gray-50 last:border-0">
                    <td className="py-2.5 px-2">
                      <div className="font-medium text-gray-800">{key.label}</div>
                      <div className="text-xs text-gray-400 font-mono" dir="ltr">{key.id}</div>
                    </td>
                    <td className="py-2.5 px-2 text-gray-600">
                      {key.scopes.length > 0 ? key.scopes.join(', ') : t('All types')}
                    </td>
                    <td className="py-2.5 px-2">
                      <div className="flex flex-wrap gap-1">
                        {key.export_enabled && (
                          <span className="px-1.5 py-0.5 rounded text-xs bg-blue-50 text-blue-700">
                            {t('Export')}
                          </span>
                        )}
                        {key.retrieve_enabled && (
                          <span className="px-1.5 py-0.5 rounded text-xs bg-purple-50 text-purple-700">
                            {t('Retrieve')}
                          </span>
                        )}
                      </div>
                    </td>
                    <td className="py-2.5 px-2 text-gray-600" dir="ltr">
                      {sprintf(t('%d/min'), key.rate_limit_per_min)}
                    </td>
                    <td className="py-2.5 px-2 text-gray-500 text-xs">{formatDate(key.last_used_at)}</td>
                    <td className="py-2.5 px-2">
                      <ToggleSwitch
                        checked={key.enabled}
                        onChange={v => handleToggleEnabled(key, v)}
                        disabled={busyId === key.id}
                        ariaLabel={t('Active')}
                      />
                    </td>
                    <td className="py-2.5 px-2">
                      {pendingDeleteId === key.id ? (
                        <div className="flex items-center gap-1.5">
                          <button
                            onClick={() => handleDelete(key.id)}
                            disabled={busyId === key.id}
                            className="px-2 py-1 text-xs rounded bg-red-600 hover:bg-red-700 text-white transition-colors disabled:opacity-50"
                          >
                            {busyId === key.id ? <Loader2 className="w-3 h-3 animate-spin" /> : t('Confirm delete')}
                          </button>
                          <button
                            onClick={() => setPendingDeleteId(null)}
                            className="px-2 py-1 text-xs rounded border border-gray-200 text-gray-600 hover:bg-gray-50 transition-colors"
                          >
                            {t('Cancel')}
                          </button>
                        </div>
                      ) : (
                        <button
                          onClick={() => setPendingDeleteId(key.id)}
                          className="p-1.5 rounded-lg text-gray-400 hover:text-red-600 hover:bg-red-50 transition-colors"
                          title={t('Delete key')}
                        >
                          <Trash2 className="w-4 h-4" />
                        </button>
                      )}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </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 key allows access only to published content within its scopes. The full key is shown once at creation — store it securely on the consuming system. Disabling a key blocks access immediately.')}
          </p>
        </div>
      </CardContent>

      {showCreateModal && (
        <CreateKeyModal
          onClose={() => setShowCreateModal(false)}
          onCreated={key => {
            setKeys(prev => [...prev, key])
          }}
        />
      )}
    </Card>
  )
}

/**
 * Create-key modal: collects the key specification, then shows the raw key
 * exactly once with a copy button.
 */
function CreateKeyModal(props: { onClose: () => void; onCreated: (key: ExternalKBKey) => void }) {
  const [label, setLabel] = useState('')
  const [scopes, setScopes] = useState<string[]>(['post', 'page', 'product'])
  const [maxTopK, setMaxTopK] = useState(8)
  const [rateLimit, setRateLimit] = useState(30)
  const [exportEnabled, setExportEnabled] = useState(true)
  const [retrieveEnabled, setRetrieveEnabled] = useState(true)
  const [ipAllowlist, setIpAllowlist] = useState('')
  const [consumers, setConsumers] = useState('boostcalendar')
  const [isCreating, setIsCreating] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [rawKey, setRawKey] = useState<string | null>(null)
  const [copied, setCopied] = useState(false)

  const toggleScope = (scope: string) => {
    setScopes(prev => (prev.includes(scope) ? prev.filter(s => s !== scope) : [...prev, scope]))
  }

  const parseList = (value: string): string[] =>
    value
      .split(',')
      .map(s => s.trim())
      .filter(Boolean)

  const handleCreate = async () => {
    if (!label.trim()) {
      setError(t('Key label is required'))
      return
    }
    setError(null)
    setIsCreating(true)
    try {
      const input: CreateExternalKBKeyInput = {
        label: label.trim(),
        scopes,
        max_top_k: maxTopK,
        rate_limit_per_min: rateLimit,
        export_enabled: exportEnabled,
        retrieve_enabled: retrieveEnabled,
        ip_allowlist: parseList(ipAllowlist),
        allowed_consumers: parseList(consumers),
      }
      const res = await externalKBApi.createKey(input)
      if (res.data?.raw_key && res.data?.key) {
        setRawKey(res.data.raw_key)
        props.onCreated(res.data.key)
      } else {
        setError(t('Failed to create key'))
      }
    } catch {
      setError(t('Failed to create key'))
    } finally {
      setIsCreating(false)
    }
  }

  const handleCopy = async () => {
    if (!rawKey) return
    try {
      await navigator.clipboard.writeText(rawKey)
      setCopied(true)
      setTimeout(() => setCopied(false), 2500)
    } catch {
      // Clipboard API unavailable — leave the key selectable for manual copy.
    }
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
      {/* Backdrop */}
      <div
        className="absolute inset-0 bg-black/40"
        onClick={() => {
          if (!isCreating) props.onClose()
        }}
      />

      <div className="relative bg-white rounded-xl shadow-xl w-full max-w-lg max-h-[90vh] overflow-y-auto">
        <div className="flex items-center justify-between px-5 py-4 border-b border-gray-100">
          <h3 className="text-base font-semibold text-gray-800 flex items-center gap-2">
            <KeyRound className="w-5 h-5 text-[#3BC2D0]" />
            {rawKey ? t('Key created successfully!') : t('Create External KB Key')}
          </h3>
          <button
            onClick={props.onClose}
            disabled={isCreating}
            className="p-1.5 rounded-lg text-gray-400 hover:text-gray-600 hover:bg-gray-100 transition-colors"
          >
            <X className="w-4 h-4" />
          </button>
        </div>

        {rawKey ? (
          /* ── One-time raw key display ─────────────────────────────── */
          <div className="p-5 space-y-4">
            <div className="p-3 bg-amber-50 border border-amber-200 rounded-lg text-sm text-amber-800 flex items-start gap-2">
              <AlertTriangle className="w-4 h-4 mt-0.5 shrink-0" />
              <span>
                {t('This is the only time the key will be displayed. Copy it now and store it securely — it cannot be recovered later.')}
              </span>
            </div>

            <div className="flex items-center gap-2">
              <code
                dir="ltr"
                className="flex-1 p-3 bg-gray-50 border border-gray-200 rounded-lg text-sm font-mono break-all select-all"
              >
                {rawKey}
              </code>
              <button
                onClick={handleCopy}
                className={`flex items-center gap-1.5 px-3 py-2 text-sm rounded-lg transition-colors ${
                  copied
                    ? 'bg-green-100 text-green-700'
                    : 'bg-primary-600 hover:bg-primary-700 text-white'
                }`}
              >
                {copied ? <Check className="w-4 h-4" /> : <Copy className="w-4 h-4" />}
                {copied ? t('Copied!') : t('Copy')}
              </button>
            </div>

            <div className="flex justify-end">
              <button
                onClick={props.onClose}
                className="px-4 py-2 text-sm rounded-lg border border-gray-200 text-gray-700 hover:bg-gray-50 transition-colors"
              >
                {t('Done')}
              </button>
            </div>
          </div>
        ) : (
          /* ── Key specification form ───────────────────────────────── */
          <div className="p-5 space-y-4">
            {error && (
              <div className="p-3 bg-red-50 border border-red-200 rounded-lg text-sm text-red-800">
                ✗ {error}
              </div>
            )}

            <div>
              <label className="block text-sm font-medium text-gray-700 mb-1">{t('Label')}</label>
              <input
                type="text"
                value={label}
                onChange={e => setLabel(e.target.value)}
                placeholder={t('e.g. BoostCalendar - Client X')}
                className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500"
              />
            </div>

            <div>
              <label className="block text-sm font-medium text-gray-700 mb-1">{t('Allowed content types (scopes)')}</label>
              <div className="flex gap-3">
                {AVAILABLE_SCOPES.map(scope => (
                  <label key={scope} className="flex items-center gap-1.5 cursor-pointer text-sm text-gray-600">
                    <input
                      type="checkbox"
                      checked={scopes.includes(scope)}
                      onChange={() => toggleScope(scope)}
                      className="accent-primary-600"
                    />
                    {scope}
                  </label>
                ))}
              </div>
            </div>

            <div className="grid grid-cols-2 gap-3">
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-1">{t('Max results per retrieve (top_k)')}</label>
                <input
                  type="number"
                  min={1}
                  max={20}
                  value={maxTopK}
                  onChange={e => setMaxTopK(Number(e.target.value))}
                  className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500"
                />
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-1">{t('Rate limit (requests/minute)')}</label>
                <input
                  type="number"
                  min={1}
                  max={600}
                  value={rateLimit}
                  onChange={e => setRateLimit(Number(e.target.value))}
                  className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500"
                />
              </div>
            </div>

            <div className="grid grid-cols-2 gap-3">
              <div className="flex items-center justify-between border border-gray-200 rounded-lg px-3 py-2">
                <span className="text-sm text-gray-700">{t('Allow export')}</span>
                <ToggleSwitch checked={exportEnabled} onChange={setExportEnabled} ariaLabel={t('Allow export')} />
              </div>
              <div className="flex items-center justify-between border border-gray-200 rounded-lg px-3 py-2">
                <span className="text-sm text-gray-700">{t('Allow retrieve')}</span>
                <ToggleSwitch checked={retrieveEnabled} onChange={setRetrieveEnabled} ariaLabel={t('Allow retrieve')} />
              </div>
            </div>

            <div>
              <label className="block text-sm font-medium text-gray-700 mb-1">{t('IP allowlist (optional, comma separated)')}</label>
              <input
                type="text"
                dir="ltr"
                value={ipAllowlist}
                onChange={e => setIpAllowlist(e.target.value)}
                placeholder="76.76.21.21, 76.76.21.0/24"
                className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500 font-mono text-sm"
              />
              <p className="text-xs text-gray-400 mt-1">{t('Leave empty to allow any origin (the key itself is the secret)')}</p>
            </div>

            <div>
              <label className="block text-sm font-medium text-gray-700 mb-1">{t('Allowed consumers (informational)')}</label>
              <input
                type="text"
                dir="ltr"
                value={consumers}
                onChange={e => setConsumers(e.target.value)}
                placeholder="boostcalendar"
                className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500 font-mono text-sm"
              />
            </div>

            <div className="flex justify-end gap-2 pt-2">
              <button
                onClick={props.onClose}
                disabled={isCreating}
                className="px-4 py-2 text-sm rounded-lg border border-gray-200 text-gray-700 hover:bg-gray-50 transition-colors disabled:opacity-50"
              >
                {t('Cancel')}
              </button>
              <button
                onClick={handleCreate}
                disabled={isCreating}
                className="flex items-center gap-2 px-4 py-2 text-sm rounded-lg bg-primary-600 hover:bg-primary-700 text-white transition-colors disabled:opacity-50"
              >
                {isCreating ? <Loader2 className="w-4 h-4 animate-spin" /> : <Plus className="w-4 h-4" />}
                {isCreating ? t('Creating...') : t('Create Key')}
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  )
}
