import { useState, useMemo, useEffect } from 'react';
import { useQuery } from '@tanstack/react-query';
import { apiFetch } from '../../lib/api';
import { useI18n } from '../../lib/i18n';
import { useLayoutContext } from '../Layout';
import PasswordRevealPrompt from '../../components/PasswordRevealPrompt';
import { MCP_CLIENTS, buildClientConfig, sanitizeServerName, type McpClientId } from '../../lib/mcp-clients';

type Project = { id: string; name: string };

type ApiKeyStatus = { hasKey: boolean; prefix: string | null };

type McpInfo = {
  projectName: string;
  openApiVersion: string;
  totalEndpoints: number;
  totalModules: number;
  toolCount: number;
};

type TestStatus =
  | { kind: 'idle' }
  | { kind: 'loading' }
  | { kind: 'ok'; info: McpInfo }
  | { kind: 'error'; message: string };

export default function McpIntegration({ project }: { project: Project }) {
  const { t } = useI18n();
  const { onOpenSettings } = useLayoutContext();

  const mcpUrl = `${window.location.origin}/mcp/${project.id}`;
  const serverName = useMemo(() => sanitizeServerName(project.name), [project.name]);

  const [activeClient, setActiveClient] = useState<McpClientId>('claude-desktop');
  const [revealedKey, setRevealedKey] = useState<string | null>(null);
  const [passwordPromptOpen, setPasswordPromptOpen] = useState(false);
  const [copied, setCopied] = useState<string | null>(null);
  const [testStatus, setTestStatus] = useState<TestStatus>({ kind: 'idle' });

  const { data: keyStatus } = useQuery({
    queryKey: ['api-key-status'],
    queryFn: () => apiFetch<ApiKeyStatus>('/auth/api-key/status'),
  });

  useEffect(() => { setTestStatus({ kind: 'idle' }); }, [mcpUrl]);

  const client = MCP_CLIENTS.find((c) => c.id === activeClient) ?? MCP_CLIENTS[0];
  const configSnippet = buildClientConfig(client, serverName, mcpUrl, revealedKey);

  const copyText = (text: string, key: string) => {
    navigator.clipboard.writeText(text);
    setCopied(key);
    setTimeout(() => setCopied(null), 2000);
  };

  const requestRevealAndCopy = () => {
    if (!keyStatus?.hasKey) return;
    if (revealedKey) {
      copyText(buildClientConfig(client, serverName, mcpUrl, revealedKey), 'config');
      return;
    }
    setPasswordPromptOpen(true);
  };

  const handleReveal = (apiKey: string) => {
    setRevealedKey(apiKey);
    // Copy synchronously off the user gesture chain — re-using `apiKey` instead
    // of `revealedKey` because state hasn't propagated yet.
    copyText(buildClientConfig(client, serverName, mcpUrl, apiKey), 'config');
    setPasswordPromptOpen(false);
  };

  const testConnection = async () => {
    setTestStatus({ kind: 'loading' });
    try {
      const res = await fetch(`${mcpUrl}/info`);
      if (!res.ok) {
        setTestStatus({ kind: 'error', message: `HTTP ${res.status}` });
        return;
      }
      const info = (await res.json()) as McpInfo;
      setTestStatus({ kind: 'ok', info });
    } catch (err) {
      setTestStatus({ kind: 'error', message: err instanceof Error ? err.message : 'Network error' });
    }
  };

  return (
    <div className="max-w-2xl space-y-8">
      {/* MCP URL */}
      <section>
        <p className="section-title">{t('dashboard.mcp.urlTitle')}</p>
        <p className="section-desc mb-3">{t('dashboard.mcp.urlDesc')}</p>
        <div className="flex items-center gap-2">
          <code className="flex-1 px-3.5 py-2.5 rounded-lg bg-bg-tertiary border border-border-muted text-[13px] font-mono text-text-primary truncate">{mcpUrl}</code>
          <button onClick={() => copyText(mcpUrl, 'url')} className="btn-outline shrink-0">
            {copied === 'url' ? t('common.copied') : t('common.copy')}
          </button>
          <button onClick={testConnection} disabled={testStatus.kind === 'loading'} className="btn-outline shrink-0">
            {testStatus.kind === 'loading' ? t('dashboard.mcp.testing') : t('dashboard.mcp.testConnection')}
          </button>
        </div>
        {testStatus.kind === 'ok' && (
          <div className="mt-2.5 p-3 rounded-lg bg-success-muted text-[12px] text-text-secondary flex items-start gap-2">
            <svg className="w-4 h-4 text-success shrink-0 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}><path d="M5 13l4 4L19 7" /></svg>
            <div>
              <div className="font-medium text-success">{t('dashboard.mcp.testOk')}</div>
              <div className="text-text-muted mt-0.5">
                {testStatus.info.projectName} · OpenAPI {testStatus.info.openApiVersion} · {testStatus.info.totalModules} {t('common.modules')} · {testStatus.info.totalEndpoints} {t('common.endpoints')} · {testStatus.info.toolCount} tools
              </div>
            </div>
          </div>
        )}
        {testStatus.kind === 'error' && (
          <div className="mt-2.5 p-3 rounded-lg bg-danger-muted text-[12px] text-danger flex items-center gap-2">
            <svg className="w-4 h-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}><path d="M6 18L18 6M6 6l12 12" /></svg>
            <span>{t('dashboard.mcp.testFail')}: {testStatus.message}</span>
          </div>
        )}
      </section>

      {/* Client selector + Config */}
      <section>
        <p className="section-title">{t('dashboard.mcp.configTitle')}</p>
        <p className="section-desc mb-3">{t('dashboard.mcp.configDesc')}</p>

        {/* Client tabs */}
        <div className="flex flex-wrap gap-1 p-1 rounded-lg bg-bg-tertiary border border-border-muted mb-3">
          {MCP_CLIENTS.map((c) => (
            <button
              key={c.id}
              onClick={() => setActiveClient(c.id)}
              className={`px-3 py-1.5 rounded-md text-[12px] font-medium transition-all ${
                activeClient === c.id
                  ? 'bg-bg-elevated text-text-primary shadow-sm'
                  : 'text-text-muted hover:text-text-secondary'
              }`}
            >
              {c.label}
            </button>
          ))}
        </div>

        {/* Setup hint */}
        <div className="mb-3 p-3 rounded-lg bg-bg-tertiary border border-border-muted text-[12px] text-text-secondary space-y-1">
          <div>
            <span className="text-text-muted">{t('dashboard.mcp.configLocation')}：</span>
            <code className="font-mono text-text-primary">{client.configPath}</code>
          </div>
          {client.configPathAlt && (
            <div>
              <span className="text-text-muted">{t('dashboard.mcp.configLocationAlt')}：</span>
              <code className="font-mono text-text-primary">{client.configPathAlt}</code>
            </div>
          )}
          <div className="text-text-muted pt-1">{client.restartHint}</div>
        </div>

        {/* Config snippet */}
        <div className="relative">
          <pre className="code-block text-xs">{configSnippet}</pre>
          <div className="absolute top-2.5 right-2.5 flex gap-1.5">
            {keyStatus?.hasKey && !revealedKey && (
              <button
                onClick={requestRevealAndCopy}
                className="copy-btn"
                title={t('dashboard.mcp.copyWithKey')}
              >
                {t('dashboard.mcp.copyWithKey')}
              </button>
            )}
            <button onClick={() => copyText(configSnippet, 'config')} className="copy-btn">
              {copied === 'config' ? `${t('common.copied')}!` : t('common.copy')}
            </button>
          </div>
        </div>

        <div className="mt-3">
          <PasswordRevealPrompt
            open={passwordPromptOpen}
            promptText={t('dashboard.mcp.revealPrompt')}
            onCancel={() => setPasswordPromptOpen(false)}
            onReveal={handleReveal}
            onSetPasswordClick={() => { setPasswordPromptOpen(false); onOpenSettings(); }}
          />
        </div>

        {/* API Key status */}
        {keyStatus && !keyStatus.hasKey && (
          <div className="mt-3 flex items-center gap-3 p-3.5 rounded-lg bg-warning-muted border border-warning/20">
            <svg className="w-4 h-4 text-warning shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}><path d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z" /></svg>
            <p className="text-[13px] text-text-secondary flex-1">{t('dashboard.mcp.noKeyWarning')}</p>
            <button onClick={onOpenSettings} className="btn-primary shrink-0 text-[13px] py-1.5 px-3">
              {t('dashboard.mcp.openSettings')}
            </button>
          </div>
        )}
      </section>

      {/* Available tools */}
      <section>
        <p className="section-title">{t('dashboard.mcp.toolsTitle')}</p>
        <p className="section-desc mb-3">{t('dashboard.mcp.toolsDesc')}</p>
        <div className="space-y-1.5 stagger-children">
          {[
            { name: 'get_project_overview', desc: t('dashboard.mcp.tool1Desc'), num: '1' },
            { name: 'list_modules', desc: t('dashboard.mcp.tool2Desc'), num: '2' },
            { name: 'list_endpoints', desc: t('dashboard.mcp.tool3Desc'), num: '3' },
            { name: 'get_endpoint_detail', desc: t('dashboard.mcp.tool4Desc'), num: '4' },
            { name: 'search_endpoints', desc: t('dashboard.mcp.tool5Desc'), num: '5' },
          ].map((tool) => (
            <div key={tool.name} className="card px-4 py-3 flex items-start gap-3">
              <span className="w-5 h-5 rounded-full bg-accent-muted text-accent text-[10px] font-bold flex items-center justify-center shrink-0 mt-0.5">{tool.num}</span>
              <div className="min-w-0">
                <code className="text-[13px] font-mono font-medium text-accent">{tool.name}</code>
                <p className="text-xs text-text-muted mt-0.5 leading-relaxed">{tool.desc}</p>
              </div>
            </div>
          ))}
        </div>
      </section>
    </div>
  );
}
