import * as React from 'react';
import { useState, useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';
import { Copy, Check, Trash2, Plus } from 'lucide-react';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
  DialogDescription,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Switch } from '@/components/ui/switch';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogPortal,
  AlertDialogOverlay,
} from '@/components/ui/alert-dialog';
import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
import { backendClient } from '@/app/infra/http';
import { PanelToolbar } from '../settings-dialog/panel-layout';

interface ApiKey {
  id: number;
  uuid: string;
  name: string;
  description: string;
  scopes: string[];
  status: 'active' | 'revoked';
  secret_available: false;
  created_at: string;
}

type CreatedApiKey = Omit<ApiKey, 'secret_available'> & {
  key: string;
  secret_available: true;
};

interface Webhook {
  id: number;
  name: string;
  url: string;
  description: string;
  enabled: boolean;
  created_at: string;
}

interface ApiIntegrationPanelProps {
  // True when this panel is the active section and the dialog is open.
  active: boolean;
}

export default function ApiIntegrationPanel({
  active,
}: ApiIntegrationPanelProps) {
  const { t } = useTranslation();
  const [activeTab, setActiveTab] = useState('apikeys');
  const [apiKeys, setApiKeys] = useState<ApiKey[]>([]);
  const [webhooks, setWebhooks] = useState<Webhook[]>([]);
  const [loading, setLoading] = useState(false);
  const [showCreateDialog, setShowCreateDialog] = useState(false);
  const [newKeyName, setNewKeyName] = useState('');
  const [newKeyDescription, setNewKeyDescription] = useState('');
  const [createdKey, setCreatedKey] = useState<CreatedApiKey | null>(null);
  const [deleteKeyId, setDeleteKeyId] = useState<number | null>(null);

  // Webhook state
  const [showCreateWebhookDialog, setShowCreateWebhookDialog] = useState(false);
  const [newWebhookName, setNewWebhookName] = useState('');
  const [newWebhookUrl, setNewWebhookUrl] = useState('');
  const [newWebhookDescription, setNewWebhookDescription] = useState('');
  const [newWebhookEnabled, setNewWebhookEnabled] = useState(true);
  const [deleteWebhookId, setDeleteWebhookId] = useState<number | null>(null);
  const copiedTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(
    undefined,
  );
  const [copiedKey, setCopiedKey] = useState<string | null>(null);

  // MCP server endpoint, derived from the current origin. The backend serves
  // the MCP server at /mcp on the same host/port as the HTTP API + web UI.
  const mcpEndpoint =
    typeof window !== 'undefined' ? `${window.location.origin}/mcp` : '/mcp';

  // 清理 body 样式，防止嵌套对话框关闭后页面无法交互
  useEffect(() => {
    if (!deleteKeyId && !deleteWebhookId) {
      const cleanup = () => {
        document.body.style.removeProperty('pointer-events');
      };

      cleanup();
      const timer = setTimeout(cleanup, 100);
      return () => clearTimeout(timer);
    }
  }, [deleteKeyId, deleteWebhookId]);

  useEffect(() => {
    if (active) {
      loadApiKeys();
      loadWebhooks();
    }
  }, [active]);

  const loadApiKeys = async () => {
    setLoading(true);
    try {
      const response = (await backendClient.get('/api/v1/apikeys')) as {
        keys: ApiKey[];
      };
      setApiKeys(response.keys || []);
    } catch (error) {
      toast.error(`Failed to load API keys: ${error}`);
    } finally {
      setLoading(false);
    }
  };

  const handleCreateApiKey = async () => {
    if (!newKeyName.trim()) {
      toast.error(t('common.apiKeyNameRequired'));
      return;
    }

    try {
      const response = (await backendClient.post('/api/v1/apikeys', {
        name: newKeyName,
        description: newKeyDescription,
      })) as { key: CreatedApiKey };

      setCreatedKey(response.key);
      toast.success(t('common.apiKeyCreated'));
      setNewKeyName('');
      setNewKeyDescription('');
      setShowCreateDialog(false);
      loadApiKeys();
    } catch (error) {
      toast.error(`Failed to create API key: ${error}`);
    }
  };

  const handleDeleteApiKey = async (keyId: number) => {
    try {
      await backendClient.delete(`/api/v1/apikeys/${keyId}`);
      toast.success(t('common.apiKeyDeleted'));
      loadApiKeys();
      setDeleteKeyId(null);
    } catch (error) {
      toast.error(`Failed to delete API key: ${error}`);
    }
  };

  const copyToClipboard = (text: string) => {
    const el = document.createElement('span');
    el.textContent = text;
    el.style.cssText =
      'position:fixed;opacity:0;pointer-events:none;white-space:pre;';
    document.body.appendChild(el);
    const range = document.createRange();
    range.selectNodeContents(el);
    const sel = window.getSelection();
    sel?.removeAllRanges();
    sel?.addRange(range);
    document.execCommand('copy');
    sel?.removeAllRanges();
    document.body.removeChild(el);
  };

  const handleCopyKey = (key: string) => {
    try {
      copyToClipboard(key);
    } catch {}
    clearTimeout(copiedTimerRef.current);
    setCopiedKey(key);
    copiedTimerRef.current = setTimeout(() => setCopiedKey(null), 2000);
  };

  // Webhook methods
  const loadWebhooks = async () => {
    setLoading(true);
    try {
      const response = (await backendClient.get('/api/v1/webhooks')) as {
        webhooks: Webhook[];
      };
      setWebhooks(response.webhooks || []);
    } catch (error) {
      toast.error(`Failed to load webhooks: ${error}`);
    } finally {
      setLoading(false);
    }
  };

  const handleCreateWebhook = async () => {
    if (!newWebhookName.trim()) {
      toast.error(t('common.webhookNameRequired'));
      return;
    }
    if (!newWebhookUrl.trim()) {
      toast.error(t('common.webhookUrlRequired'));
      return;
    }

    try {
      await backendClient.post('/api/v1/webhooks', {
        name: newWebhookName,
        url: newWebhookUrl,
        description: newWebhookDescription,
        enabled: newWebhookEnabled,
      });

      toast.success(t('common.webhookCreated'));
      setNewWebhookName('');
      setNewWebhookUrl('');
      setNewWebhookDescription('');
      setNewWebhookEnabled(true);
      setShowCreateWebhookDialog(false);
      loadWebhooks();
    } catch (error) {
      toast.error(`Failed to create webhook: ${error}`);
    }
  };

  const handleDeleteWebhook = async (webhookId: number) => {
    try {
      await backendClient.delete(`/api/v1/webhooks/${webhookId}`);
      toast.success(t('common.webhookDeleted'));
      loadWebhooks();
      setDeleteWebhookId(null);
    } catch (error) {
      toast.error(`Failed to delete webhook: ${error}`);
    }
  };

  const handleToggleWebhook = async (webhook: Webhook) => {
    try {
      await backendClient.put(`/api/v1/webhooks/${webhook.id}`, {
        enabled: !webhook.enabled,
      });
      loadWebhooks();
    } catch (error) {
      toast.error(`Failed to update webhook: ${error}`);
    }
  };

  return (
    <>
      <Tabs
        value={activeTab}
        onValueChange={setActiveTab}
        className="flex h-full min-h-0 w-full flex-col overflow-hidden"
      >
        <PanelToolbar>
          <TabsList>
            <TabsTrigger value="apikeys">{t('common.apiKeys')}</TabsTrigger>
            <TabsTrigger value="webhooks">{t('common.webhooks')}</TabsTrigger>
            <TabsTrigger value="mcp">{t('common.mcpTab')}</TabsTrigger>
          </TabsList>
          {activeTab === 'apikeys' ? (
            <Button
              onClick={() => setShowCreateDialog(true)}
              size="sm"
              className="gap-2"
            >
              <Plus className="h-4 w-4" />
              {t('common.createApiKey')}
            </Button>
          ) : activeTab === 'webhooks' ? (
            <Button
              onClick={() => setShowCreateWebhookDialog(true)}
              size="sm"
              className="gap-2"
            >
              <Plus className="h-4 w-4" />
              {t('common.createWebhook')}
            </Button>
          ) : null}
        </PanelToolbar>

        {/* API Keys Tab */}
        <TabsContent
          value="apikeys"
          className="min-h-0 flex-1 space-y-4 overflow-auto px-6 py-5"
        >
          <p className="text-sm text-muted-foreground">
            {t('common.apiKeyHint')}
          </p>

          {loading ? (
            <div className="text-center py-8 text-muted-foreground">
              {t('common.loading')}
            </div>
          ) : apiKeys.length === 0 ? (
            <div className="text-center py-8 text-muted-foreground">
              {t('common.noApiKeys')}
            </div>
          ) : (
            <div className="flex-1 overflow-auto rounded-md border">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead className="min-w-[120px]">
                      {t('common.name')}
                    </TableHead>
                    <TableHead className="min-w-[200px]">
                      {t('common.apiKeyValue')}
                    </TableHead>
                    <TableHead className="w-[100px]">
                      {t('common.actions')}
                    </TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {apiKeys.map((item) => (
                    <TableRow key={item.id}>
                      <TableCell>
                        <div>
                          <div className="font-medium">{item.name}</div>
                          {item.description && (
                            <div className="text-sm text-muted-foreground">
                              {item.description}
                            </div>
                          )}
                        </div>
                      </TableCell>
                      <TableCell>
                        <span className="text-sm text-muted-foreground">
                          {t('common.apiKeyStoredSecurely')}
                        </span>
                      </TableCell>
                      <TableCell>
                        <div className="flex gap-2">
                          <Button
                            variant="ghost"
                            size="sm"
                            onClick={() => setDeleteKeyId(item.id)}
                            title={t('common.delete')}
                          >
                            <Trash2 className="h-4 w-4" />
                          </Button>
                        </div>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          )}
        </TabsContent>

        {/* Webhooks Tab */}
        <TabsContent
          value="webhooks"
          className="min-h-0 flex-1 space-y-4 overflow-auto px-6 py-5"
        >
          <p className="text-sm text-muted-foreground">
            {t('common.webhookHint')}
          </p>

          {loading ? (
            <div className="text-center py-8 text-muted-foreground">
              {t('common.loading')}
            </div>
          ) : webhooks.length === 0 ? (
            <div className="text-center py-8 text-muted-foreground">
              {t('common.noWebhooks')}
            </div>
          ) : (
            <div className="max-w-full flex-1 overflow-auto rounded-md border">
              <Table className="table-fixed w-full">
                <TableHeader>
                  <TableRow>
                    <TableHead className="w-[150px]">
                      {t('common.name')}
                    </TableHead>
                    <TableHead className="w-[380px]">
                      {t('common.webhookUrl')}
                    </TableHead>
                    <TableHead className="w-[80px]">
                      {t('common.webhookEnabled')}
                    </TableHead>
                    <TableHead className="w-[80px]">
                      {t('common.actions')}
                    </TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {webhooks.map((webhook) => (
                    <TableRow key={webhook.id}>
                      <TableCell className="truncate">
                        <div className="truncate">
                          <div
                            className="font-medium truncate"
                            title={webhook.name}
                          >
                            {webhook.name}
                          </div>
                          {webhook.description && (
                            <div
                              className="text-sm text-muted-foreground truncate"
                              title={webhook.description}
                            >
                              {webhook.description}
                            </div>
                          )}
                        </div>
                      </TableCell>
                      <TableCell>
                        <div className="overflow-x-auto max-w-[380px]">
                          <code className="text-sm bg-muted px-2 py-1 rounded whitespace-nowrap inline-block">
                            {webhook.url}
                          </code>
                        </div>
                      </TableCell>
                      <TableCell>
                        <Switch
                          checked={webhook.enabled}
                          onCheckedChange={() => handleToggleWebhook(webhook)}
                        />
                      </TableCell>
                      <TableCell>
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => setDeleteWebhookId(webhook.id)}
                          title={t('common.delete')}
                        >
                          <Trash2 className="h-4 w-4" />
                        </Button>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          )}
        </TabsContent>

        {/* MCP Tab */}
        <TabsContent
          value="mcp"
          className="min-h-0 flex-1 space-y-4 overflow-auto px-6 py-5"
        >
          <p className="text-sm text-muted-foreground">{t('common.mcpHint')}</p>

          <div className="space-y-2">
            <label className="text-sm font-medium">
              {t('common.mcpEndpoint')}
            </label>
            <div className="flex items-center gap-2">
              <code className="flex-1 truncate rounded bg-muted px-3 py-2 text-sm">
                {mcpEndpoint}
              </code>
              <Button
                variant="ghost"
                size="sm"
                type="button"
                onClick={() => handleCopyKey(mcpEndpoint)}
                title={t('common.copy')}
              >
                {copiedKey === mcpEndpoint ? (
                  <Check className="h-4 w-4 text-green-600" />
                ) : (
                  <Copy className="h-4 w-4" />
                )}
              </Button>
            </div>
          </div>

          <div className="space-y-2">
            <label className="text-sm font-medium">
              {t('common.mcpAuthTitle')}
            </label>
            <p className="text-sm text-muted-foreground">
              {t('common.mcpAuthDesc')}
            </p>
            <pre className="overflow-auto rounded bg-muted px-3 py-2 text-xs">
              {`X-API-Key: <your-api-key>
# or
Authorization: Bearer <your-api-key>`}
            </pre>
            <p className="text-sm text-muted-foreground">
              {t('common.mcpGlobalKeyNote')}
            </p>
          </div>

          <div className="space-y-2">
            <label className="text-sm font-medium">
              {t('common.mcpClientConfigTitle')}
            </label>
            <pre className="overflow-auto rounded bg-muted px-3 py-2 text-xs">
              {`{
  "mcpServers": {
    "langbot": {
      "url": "${mcpEndpoint}",
      "headers": { "X-API-Key": "<your-api-key>" }
    }
  }
}`}
            </pre>
          </div>
        </TabsContent>
      </Tabs>

      {/* Create API Key Dialog */}
      <Dialog open={showCreateDialog} onOpenChange={setShowCreateDialog}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>{t('common.createApiKey')}</DialogTitle>
          </DialogHeader>
          <div className="space-y-4">
            <div>
              <label className="text-sm font-medium">{t('common.name')}</label>
              <Input
                value={newKeyName}
                onChange={(e) => setNewKeyName(e.target.value)}
                placeholder={t('common.name')}
                className="mt-1"
              />
            </div>
            <div>
              <label className="text-sm font-medium">
                {t('common.description')}
              </label>
              <Input
                value={newKeyDescription}
                onChange={(e) => setNewKeyDescription(e.target.value)}
                placeholder={t('common.description')}
                className="mt-1"
              />
            </div>
          </div>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => setShowCreateDialog(false)}
            >
              {t('common.cancel')}
            </Button>
            <Button onClick={handleCreateApiKey}>{t('common.create')}</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Show Created Key Dialog */}
      <Dialog open={!!createdKey} onOpenChange={() => setCreatedKey(null)}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>{t('common.apiKeyCreated')}</DialogTitle>
            <DialogDescription>
              {t('common.apiKeyCreatedMessage')}
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div>
              <label className="text-sm font-medium">
                {t('common.apiKeyValue')}
              </label>
              <div className="flex gap-2 mt-1">
                <Input value={createdKey?.key || ''} readOnly />
                <Button
                  onClick={() => createdKey && handleCopyKey(createdKey.key)}
                  variant="outline"
                  size="icon"
                >
                  {copiedKey === createdKey?.key ? (
                    <Check className="h-4 w-4 text-green-600" />
                  ) : (
                    <Copy className="h-4 w-4" />
                  )}
                </Button>
              </div>
            </div>
          </div>
          <DialogFooter>
            <Button onClick={() => setCreatedKey(null)}>
              {t('common.close')}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Create Webhook Dialog */}
      <Dialog
        open={showCreateWebhookDialog}
        onOpenChange={setShowCreateWebhookDialog}
      >
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>{t('common.createWebhook')}</DialogTitle>
          </DialogHeader>
          <div className="space-y-4">
            <div>
              <label className="text-sm font-medium">{t('common.name')}</label>
              <Input
                value={newWebhookName}
                onChange={(e) => setNewWebhookName(e.target.value)}
                placeholder={t('common.webhookName')}
                className="mt-1"
              />
            </div>
            <div>
              <label className="text-sm font-medium">
                {t('common.webhookUrl')}
              </label>
              <Input
                value={newWebhookUrl}
                onChange={(e) => setNewWebhookUrl(e.target.value)}
                placeholder="https://example.com/webhook"
                className="mt-1"
              />
            </div>
            <div>
              <label className="text-sm font-medium">
                {t('common.description')}
              </label>
              <Input
                value={newWebhookDescription}
                onChange={(e) => setNewWebhookDescription(e.target.value)}
                placeholder={t('common.description')}
                className="mt-1"
              />
            </div>
            <div className="flex items-center gap-2">
              <Switch
                checked={newWebhookEnabled}
                onCheckedChange={setNewWebhookEnabled}
              />
              <label className="text-sm font-medium">
                {t('common.webhookEnabled')}
              </label>
            </div>
          </div>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => setShowCreateWebhookDialog(false)}
            >
              {t('common.cancel')}
            </Button>
            <Button onClick={handleCreateWebhook}>{t('common.create')}</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Delete Confirmation Dialog */}
      <AlertDialog open={!!deleteKeyId}>
        <AlertDialogPortal>
          <AlertDialogOverlay
            className="z-[60]"
            onClick={() => setDeleteKeyId(null)}
          />
          <AlertDialogPrimitive.Content
            className="fixed left-[50%] top-[50%] z-[60] grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 sm:rounded-lg"
            onEscapeKeyDown={() => setDeleteKeyId(null)}
          >
            <AlertDialogHeader>
              <AlertDialogTitle>{t('common.confirmDelete')}</AlertDialogTitle>
              <AlertDialogDescription>
                {t('common.apiKeyDeleteConfirm')}
              </AlertDialogDescription>
            </AlertDialogHeader>
            <AlertDialogFooter>
              <AlertDialogCancel onClick={() => setDeleteKeyId(null)}>
                {t('common.cancel')}
              </AlertDialogCancel>
              <AlertDialogAction
                onClick={() => deleteKeyId && handleDeleteApiKey(deleteKeyId)}
              >
                {t('common.delete')}
              </AlertDialogAction>
            </AlertDialogFooter>
          </AlertDialogPrimitive.Content>
        </AlertDialogPortal>
      </AlertDialog>

      {/* Delete Webhook Confirmation Dialog */}
      <AlertDialog open={!!deleteWebhookId}>
        <AlertDialogPortal>
          <AlertDialogOverlay
            className="z-[60]"
            onClick={() => setDeleteWebhookId(null)}
          />
          <AlertDialogPrimitive.Content
            className="fixed left-[50%] top-[50%] z-[60] grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 sm:rounded-lg"
            onEscapeKeyDown={() => setDeleteWebhookId(null)}
          >
            <AlertDialogHeader>
              <AlertDialogTitle>{t('common.confirmDelete')}</AlertDialogTitle>
              <AlertDialogDescription>
                {t('common.webhookDeleteConfirm')}
              </AlertDialogDescription>
            </AlertDialogHeader>
            <AlertDialogFooter>
              <AlertDialogCancel onClick={() => setDeleteWebhookId(null)}>
                {t('common.cancel')}
              </AlertDialogCancel>
              <AlertDialogAction
                onClick={() =>
                  deleteWebhookId && handleDeleteWebhook(deleteWebhookId)
                }
              >
                {t('common.delete')}
              </AlertDialogAction>
            </AlertDialogFooter>
          </AlertDialogPrimitive.Content>
        </AlertDialogPortal>
      </AlertDialog>
    </>
  );
}
