'use client';

import { useState, useEffect } from 'react';
import { Key, Plus, Trash2, Eye, EyeOff, Copy, CheckCircle, Clock, ChevronDown, ChevronUp, X, Code, Lock, Globe, Loader2, AlertCircle } from 'lucide-react';
import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip } from 'recharts';
import { SafeChart } from '@client/components/ui/SafeChart';
import { listApiKeys, createApiKey, revokeApiKey, ApiKey } from '@client/api/api-keys';
import { getApiUsageChart } from '@client/api/billing';
import { usePageHeader } from '@client/contexts/PageHeaderContext';
import { useLanguage } from '@client/contexts/LanguageContext';
import SmokeTester from './SmokeTester';

type TFn = (key: string, fallback?: string, vars?: Record<string, string | number>) => string;

const apiEndpoints = (t: TFn) => [
  { method: 'GET', path: '/v1/orders', description: t('restApi.endpoints.listOrders', 'List all orders with filters and pagination') },
  { method: 'GET', path: '/v1/orders/:id', description: t('restApi.endpoints.getOrder', 'Get a single order by ID') },
  { method: 'POST', path: '/v1/orders', description: t('restApi.endpoints.createOrder', 'Create a new order') },
  { method: 'PATCH', path: '/v1/orders/:id', description: t('restApi.endpoints.updateOrder', 'Update order status or details') },
  { method: 'GET', path: '/v1/bookings', description: t('restApi.endpoints.listBookings', 'List all table bookings') },
  { method: 'POST', path: '/v1/bookings', description: t('restApi.endpoints.createBooking', 'Create a new table booking') },
  { method: 'DELETE', path: '/v1/bookings/:id', description: t('restApi.endpoints.cancelBooking', 'Cancel a booking') },
  { method: 'GET', path: '/v1/customers', description: t('restApi.endpoints.listCustomers', 'List all customers') },
  { method: 'GET', path: '/v1/customers/:id', description: t('restApi.endpoints.getCustomer', 'Get customer profile and order history') },
  { method: 'GET', path: '/v1/menu/items', description: t('restApi.endpoints.listMenuItems', 'List all menu items') },
  { method: 'POST', path: '/v1/menu/items', description: t('restApi.endpoints.createMenuItem', 'Create a new menu item') },
  { method: 'GET', path: '/v1/analytics/summary', description: t('restApi.endpoints.analyticsSummary', 'Get revenue and order analytics summary') },
  { method: 'GET', path: '/v1/ai/conversations', description: t('restApi.endpoints.listConversations', 'List AI conversations') },
  { method: 'POST', path: '/v1/ai/conversations/:id/takeover', description: t('restApi.endpoints.takeoverConversation', 'Take over an AI conversation') },
];

const methodColors: Record<string, { color: string; bg: string }> = {
  GET: { color: 'hsl(142, 72%, 29%)', bg: 'hsl(142, 72%, 96%)' },
  POST: { color: 'hsl(210, 100%, 40%)', bg: 'hsl(210, 100%, 96%)' },
  PATCH: { color: 'hsl(38, 92%, 40%)', bg: 'hsl(38, 100%, 96%)' },
  DELETE: { color: 'hsl(0, 84%, 44%)', bg: 'hsl(0, 84%, 97%)' },
  PUT: { color: 'hsl(280, 60%, 45%)', bg: 'hsl(280, 60%, 96%)' },
};

const allPermissions = ['orders:read', 'orders:write', 'bookings:read', 'bookings:write', 'customers:read', 'customers:write', 'menu:read', 'menu:write', 'analytics:read', 'ai:read', 'ai:write'];

export default function RestApiPage() {
  const { t } = useLanguage();
  usePageHeader(t('restApi.title', "REST API"), t('restApi.subtitle', "Manage API keys and integrate RestroAgent with your systems"));
  const [keys, setKeys] = useState<ApiKey[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const [newKeyValue, setNewKeyValue] = useState<string | null>(null);
  const [revealedKeys, setRevealedKeys] = useState<Set<string>>(new Set());
  const [showAddForm, setShowAddForm] = useState(false);
  const [showDocs, setShowDocs] = useState(true);
  const [newKey, setNewKey] = useState({ name: '', permissions: [] as string[] });
  const [copiedId, setCopiedId] = useState<string | null>(null);
  const [revokingId, setRevokingId] = useState<string | null>(null);
  const [usageData, setUsageData] = useState<{ day: string; calls: number }[]>([]);
  const [apiHost, setApiHost] = useState<string>('');
  useEffect(() => {
    if (typeof window !== 'undefined') setApiHost(window.location.host);
  }, []);
  const apiBaseUrlDisplay = apiHost ? `${apiHost}/api` : 'this-deployment/api';
  const apiBaseUrlFull = apiHost ? `${window.location.protocol}//${apiHost}/api/v1` : '/api/v1';

  useEffect(() => {
    setLoading(true);
    Promise.all([
      listApiKeys(),
      getApiUsageChart().catch(() => []),
    ])
      .then(([res, chart]) => {
        setKeys(res.keys);
        setUsageData(chart);
        setError(null);
      })
      .catch(e => setError(e.message))
      .finally(() => setLoading(false));
  }, []);

  const toggleReveal = (id: string) => {
    setRevealedKeys(prev => { const n = new Set(prev); n.has(id) ? n.delete(id) : n.add(id); return n; });
  };

  const copyKey = (id: string, key: string) => {
    navigator.clipboard.writeText(key).catch(() => {});
    setCopiedId(id);
    setTimeout(() => setCopiedId(null), 2000);
  };

  const handleRevoke = async (id: string) => {
    setRevokingId(id);
    try {
      const res = await revokeApiKey(id);
      setKeys(prev => prev.map(k => k.id === id ? { ...k, ...res.key } : k));
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Failed to revoke key');
    } finally {
      setRevokingId(null);
    }
  };

  const togglePermission = (perm: string) => {
    setNewKey(prev => ({
      ...prev,
      permissions: prev.permissions.includes(perm) ? prev.permissions.filter(p => p !== perm) : [...prev.permissions, perm],
    }));
  };

  const handleGenerate = async () => {
    if (!newKey.name.trim()) return;
    setSaving(true);
    try {
      const res = await createApiKey({ name: newKey.name, permissions: newKey.permissions });
      setKeys(prev => [res.key, ...prev]);
      setNewKeyValue(res.key.key ?? null);
      setShowAddForm(false);
      setNewKey({ name: '', permissions: [] });
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Failed to generate key');
    } finally {
      setSaving(false);
    }
  };

  const totalCalls = keys.filter(k => k.status === 'active').reduce((s, k) => s + (k.callsThisMonth ?? 0), 0);

  return (
    <>
      {/* Stats */}
      <div className="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-6">
        {[
          { label: t('restApi.stats.activeKeys', 'Active API Keys'), value: keys.filter(k => k.status === 'active').length, color: 'hsl(142, 72%, 29%)' },
          { label: t('restApi.stats.monthlyCalls', 'API Calls (Month)'), value: totalCalls.toLocaleString(), color: 'hsl(210, 100%, 40%)' },
          { label: t('restApi.stats.apiVersion', 'API Version'), value: 'v1.0', color: 'hsl(var(--primary))' },
          { label: t('restApi.stats.baseUrl', 'Base URL'), value: apiBaseUrlDisplay, color: 'hsl(231, 40%, 45%)' },
        ].map(stat => (
          <div key={stat.label} className="rounded-xl p-4" style={{ backgroundColor: 'hsl(var(--surface))', border: '1px solid hsl(var(--border))' }}>
            <p className="text-lg font-bold truncate" style={{ color: stat.color }}>{stat.value}</p>
            <p className="text-xs mt-0.5" style={{ color: 'hsl(var(--muted-foreground))' }}>{stat.label}</p>
          </div>
        ))}
      </div>

      {error && (
        <div className="mb-4 px-4 py-3 rounded-xl text-sm flex items-center gap-2" style={{ backgroundColor: 'hsl(var(--danger-bg))', color: 'hsl(var(--danger))', border: '1px solid hsl(var(--danger-border))' }}>
          <AlertCircle size={14} /> {error}
          <button className="ml-auto" onClick={() => setError(null)}><X size={14} /></button>
        </div>
      )}

      {/* New key banner */}
      {newKeyValue && (
        <div className="mb-5 p-4 rounded-xl" style={{ backgroundColor: 'hsl(var(--success-bg))', border: '1px solid hsl(var(--success-border))' }}>
          <p className="text-sm font-semibold mb-1" style={{ color: 'hsl(var(--success))' }}>{t('restApi.newKey.title', 'API key generated — copy it now')}</p>
          <p className="text-xs mb-2" style={{ color: 'hsl(var(--foreground-secondary))' }}>{t('restApi.newKey.subtitle', 'This is the only time you can see the full key.')}</p>
          <div className="flex items-center gap-2">
            <code className="text-xs font-mono flex-1 p-2 rounded" style={{ backgroundColor: 'hsl(var(--surface))', color: 'hsl(var(--foreground))' }}>
              {newKeyValue}
            </code>
            <button
              className="btn-secondary text-xs"
              onClick={() => { navigator.clipboard.writeText(newKeyValue).catch(() => {}); }}
            >
              <Copy size={13} /> {t('common.copy', 'Copy')}
            </button>
            <button onClick={() => setNewKeyValue(null)}><X size={16} style={{ color: 'hsl(var(--muted-foreground))' }} /></button>
          </div>
        </div>
      )}

      {/* Usage chart */}
      <div className="rounded-2xl p-5 mb-6" style={{ backgroundColor: 'hsl(var(--surface))', border: '1px solid hsl(var(--border))' }}>
        <h3 className="text-sm font-semibold mb-4" style={{ color: 'hsl(var(--foreground))' }}>{t('restApi.usage.title', 'API Usage — Last 7 Days')}</h3>
        <SafeChart height={140}>
          <AreaChart data={usageData}>
            <defs>
              <linearGradient id="apiGrad" x1="0" y1="0" x2="0" y2="1">
                <stop offset="5%" stopColor="hsl(22, 89%, 48%)" stopOpacity={0.2} />
                <stop offset="95%" stopColor="hsl(22, 89%, 48%)" stopOpacity={0} />
              </linearGradient>
            </defs>
            <CartesianGrid strokeDasharray="3 3" stroke="hsl(220, 13%, 91%)" />
            <XAxis dataKey="day" tick={{ fontSize: 11, fill: 'hsl(220, 9%, 46%)' }} axisLine={false} tickLine={false} />
            <YAxis tick={{ fontSize: 11, fill: 'hsl(220, 9%, 46%)' }} axisLine={false} tickLine={false} />
            <Tooltip contentStyle={{ fontSize: 12, borderRadius: 8, border: '1px solid hsl(220, 13%, 91%)' }} />
            <Area type="monotone" dataKey="calls" stroke="hsl(22, 89%, 48%)" strokeWidth={2} fill="url(#apiGrad)" />
          </AreaChart>
        </SafeChart>
      </div>

      {/* API Keys header */}
      <div className="flex items-center justify-between mb-4">
        <h3 className="text-sm font-semibold" style={{ color: 'hsl(var(--foreground))' }}>{t('restApi.keys.title', 'API Keys')}</h3>
        <button className="btn-primary text-sm" onClick={() => setShowAddForm(!showAddForm)}>
          <Plus size={15} /> {t('restApi.keys.generate', 'Generate New Key')}
        </button>
      </div>

      {/* Add form */}
      {showAddForm && (
        <div className="rounded-2xl p-5 mb-5" style={{ backgroundColor: 'hsl(var(--surface))', border: '2px solid hsl(var(--primary))' }}>
          <div className="flex items-center justify-between mb-4">
            <h4 className="font-semibold text-sm" style={{ color: 'hsl(var(--foreground))' }}>{t('restApi.addForm.title', 'Generate New API Key')}</h4>
            <button onClick={() => setShowAddForm(false)}><X size={16} style={{ color: 'hsl(var(--muted-foreground))' }} /></button>
          </div>
          <div className="space-y-4">
            <div>
              <label className="block text-xs font-semibold mb-1.5" style={{ color: 'hsl(var(--foreground-secondary))' }}>{t('restApi.addForm.nameLabel', 'Key Name *')}</label>
              <input
                type="text"
                placeholder={t('restApi.addForm.namePlaceholder', 'e.g. My POS Integration')}
                value={newKey.name}
                onChange={e => setNewKey(prev => ({ ...prev, name: e.target.value }))}
                className="input-field w-full"
              />
            </div>
            <div>
              <label className="block text-xs font-semibold mb-2" style={{ color: 'hsl(var(--foreground-secondary))' }}>{t('restApi.addForm.permissionsLabel', 'Permissions')}</label>
              <div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
                {allPermissions.map(perm => (
                  <label key={perm} className="flex items-center gap-2 cursor-pointer">
                    <input type="checkbox" checked={newKey.permissions.includes(perm)} onChange={() => togglePermission(perm)} className="rounded" />
                    <span className="text-xs font-mono" style={{ color: 'hsl(var(--foreground-secondary))' }}>{perm}</span>
                  </label>
                ))}
              </div>
            </div>
            <div className="flex gap-3">
              <button className="btn-primary" onClick={handleGenerate} disabled={saving || !newKey.name.trim()}>
                {saving ? <Loader2 size={15} className="animate-spin" /> : <Key size={15} />}
                {t('restApi.addForm.submit', 'Generate Key')}
              </button>
              <button className="btn-secondary" onClick={() => setShowAddForm(false)}>{t('common.cancel', 'Cancel')}</button>
            </div>
          </div>
        </div>
      )}

      {/* Keys list */}
      {loading ? (
        <div className="flex items-center justify-center py-16 gap-2" style={{ color: 'hsl(var(--muted-foreground))' }}>
          <Loader2 size={20} className="animate-spin" /> {t('restApi.loading', 'Loading API keys…')}
        </div>
      ) : (
        <div className="space-y-3 mb-8">
          {keys.length === 0 ? (
            <div className="text-center py-16 rounded-2xl" style={{ backgroundColor: 'hsl(var(--surface))', border: '1px solid hsl(var(--border))' }}>
              <Key size={32} className="mx-auto mb-3 opacity-30" style={{ color: 'hsl(var(--muted-foreground))' }} />
              <p className="font-medium text-sm" style={{ color: 'hsl(var(--foreground))' }}>{t('restApi.noKeys.title', 'No API keys yet')}</p>
              <p className="text-xs mt-1" style={{ color: 'hsl(var(--muted-foreground))' }}>{t('restApi.noKeys.subtitle', 'Generate a key to start integrating with RestroAgent')}</p>
            </div>
          ) : keys.map(apiKey => {
            const isRevealed = revealedKeys.has(apiKey.id);
            const isCopied = copiedId === apiKey.id;
            const isRevoked = apiKey.status === 'revoked';
            const permissions: string[] = Array.isArray(apiKey.permissions) ? apiKey.permissions : [];
            return (
              <div
                key={apiKey.id}
                className="rounded-2xl p-4"
                style={{ backgroundColor: 'hsl(var(--surface))', border: '1px solid hsl(var(--border))', opacity: isRevoked ? 0.6 : 1 }}
              >
                <div className="flex items-start gap-4">
                  <div
                    className="w-9 h-9 rounded-xl flex items-center justify-center shrink-0"
                    style={{
                      backgroundColor: isRevoked ? 'hsl(220, 9%, 96%)' : 'hsl(var(--primary-light))',
                      color: isRevoked ? 'hsl(220, 9%, 46%)' : 'hsl(var(--primary))',
                    }}
                  >
                    <Key size={16} />
                  </div>
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2 mb-1">
                      <p className="text-sm font-semibold" style={{ color: 'hsl(var(--foreground))' }}>{apiKey.name}</p>
                      {isRevoked && (
                        <span className="text-xs font-semibold px-2 py-0.5 rounded-full" style={{ backgroundColor: 'hsl(0, 84%, 97%)', color: 'hsl(0, 84%, 44%)' }}>{t('restApi.keys.revoked', 'Revoked')}</span>
                      )}
                    </div>
                    <div className="flex items-center gap-2 mb-2">
                      <code className="text-xs font-mono" style={{ color: 'hsl(var(--foreground-secondary))' }}>
                        {isRevealed && apiKey.key ? apiKey.key : apiKey.keyPreview}
                      </code>
                      {apiKey.key && (
                        <button onClick={() => toggleReveal(apiKey.id)} className="p-0.5">
                          {isRevealed ? <EyeOff size={12} style={{ color: 'hsl(var(--muted-foreground))' }} /> : <Eye size={12} style={{ color: 'hsl(var(--muted-foreground))' }} />}
                        </button>
                      )}
                      <button onClick={() => copyKey(apiKey.id, isRevealed && apiKey.key ? apiKey.key : apiKey.keyPreview)} className="p-0.5">
                        {isCopied ? <CheckCircle size={12} style={{ color: 'hsl(142, 72%, 29%)' }} /> : <Copy size={12} style={{ color: 'hsl(var(--muted-foreground))' }} />}
                      </button>
                    </div>
                    {permissions.length > 0 && (
                      <div className="flex flex-wrap gap-1 mb-2">
                        {permissions.map(p => (
                          <span key={p} className="text-xs font-mono px-1.5 py-0.5 rounded" style={{ backgroundColor: 'hsl(var(--muted))', color: 'hsl(var(--foreground-secondary))' }}>{p}</span>
                        ))}
                      </div>
                    )}
                    <div className="flex items-center gap-4 text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>
                      <span><Clock size={11} className="inline mr-1" />{t('restApi.keys.created', 'Created')} {new Date(apiKey.createdAt).toLocaleDateString()}</span>
                      {apiKey.lastUsedAt && <span>{t('restApi.keys.lastUsed', 'Last used:')} {new Date(apiKey.lastUsedAt).toLocaleDateString()}</span>}
                      <span>{(apiKey.callsThisMonth ?? 0).toLocaleString()} {t('restApi.keys.callsMonth', 'calls this month')}</span>
                    </div>
                  </div>
                  {!isRevoked && (
                    <button
                      className="flex items-center gap-1.5 text-xs font-semibold px-3 py-1.5 rounded-lg transition-colors shrink-0"
                      style={{ backgroundColor: 'hsl(0, 84%, 97%)', color: 'hsl(0, 84%, 44%)', border: '1px solid hsl(0, 84%, 85%)' }}
                      onClick={() => handleRevoke(apiKey.id)}
                      disabled={revokingId === apiKey.id}
                    >
                      {revokingId === apiKey.id ? <Loader2 size={12} className="animate-spin" /> : <Trash2 size={12} />}
                      {t('restApi.keys.revoke', 'Revoke')}
                    </button>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      )}

      {/* Smoke tester — lets a developer paste a key and exercise every v1
          endpoint without leaving the dashboard. */}
      <SmokeTester />

      {/* API Reference */}
      <div>
        <div className="flex items-center gap-2 mb-3">
          <button className="flex items-center gap-2 flex-1 text-left" onClick={() => setShowDocs(!showDocs)}>
            <Code size={16} style={{ color: 'hsl(var(--primary))' }} />
            <h3 className="text-sm font-semibold" style={{ color: 'hsl(var(--foreground))' }}>{t('restApi.reference.title', 'API Endpoint Reference')}</h3>
            <span className="text-xs ml-1" style={{ color: 'hsl(var(--muted-foreground))' }}>({apiEndpoints(t).length} {t('restApi.reference.endpoints', 'endpoints')})</span>
            <div className="ml-auto">
              {showDocs ? <ChevronUp size={15} style={{ color: 'hsl(var(--muted-foreground))' }} /> : <ChevronDown size={15} style={{ color: 'hsl(var(--muted-foreground))' }} />}
            </div>
          </button>
          <a
            href="/api/v1/openapi.json"
            target="_blank"
            rel="noreferrer"
            className="text-xs font-semibold px-3 py-1.5 rounded-lg shrink-0"
            style={{ backgroundColor: 'hsl(var(--surface))', color: 'hsl(var(--primary))', border: '1px solid hsl(var(--border))' }}
          >
            {t('restApi.reference.openapi', 'OpenAPI spec')}
          </a>
        </div>
        {showDocs && (
          <div className="rounded-2xl overflow-hidden" style={{ backgroundColor: 'hsl(var(--surface))', border: '1px solid hsl(var(--border))' }}>
            <div className="px-4 py-3 flex items-center gap-3" style={{ backgroundColor: 'hsl(231, 40%, 10%)', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>
              <Globe size={14} className="text-white/60" />
              <code className="text-xs text-white/80 font-mono">{t('restApi.reference.baseUrlPrefix', 'Base URL:')} {apiBaseUrlFull}</code>
              <div className="ml-auto flex items-center gap-1.5">
                <Lock size={12} className="text-white/40" />
                <span className="text-xs text-white/40">{t('restApi.reference.auth', 'Bearer token required')}</span>
              </div>
            </div>
            <div className="divide-y" style={{ borderColor: 'hsl(var(--border))' }}>
              {apiEndpoints(t).map((ep, idx) => {
                const mc = methodColors[ep.method] || methodColors.GET;
                return (
                  <div key={idx} className="flex items-center gap-4 px-4 py-3">
                    <span className="text-xs font-mono font-bold px-2 py-0.5 rounded shrink-0 w-14 text-center" style={{ backgroundColor: mc.bg, color: mc.color }}>
                      {ep.method}
                    </span>
                    <code className="text-xs font-mono flex-1" style={{ color: 'hsl(var(--foreground))' }}>{ep.path}</code>
                    <span className="text-xs hidden sm:block" style={{ color: 'hsl(var(--muted-foreground))' }}>{ep.description}</span>
                  </div>
                );
              })}
            </div>
          </div>
        )}
      </div>
    </>
  );
}
