import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useAuthState } from '../../App';

// ── Types ─────────────────────────────────────────────────────────────────────

interface ServerPublic {
  id: string;
  name: string;
  url: string;
  authKind: 'oauth' | 'api_key';
  ownerId: string | null;
  oauthClientId: string | null;
  oauthScopes: string | null;
  enabled: boolean;
  createdAt: string;
  updatedAt: string;
  authorizationEndpoint: string | null;
  toolCount?: number;
}

interface ServerListResponse {
  servers: ServerPublic[];
}

interface UserServerListResponse {
  servers: ServerPublic[];
}

// ── API helpers ───────────────────────────────────────────────────────────────

async function fetchAdminServers(): Promise<ServerPublic[]> {
  const res = await fetch('/api/mcp/servers', { credentials: 'include' });
  if (!res.ok) throw new Error(`${res.status}`);
  const data: ServerListResponse = await res.json();
  return data.servers ?? [];
}

async function fetchUserServers(): Promise<ServerPublic[]> {
  const res = await fetch('/api/mcp/user-servers', { credentials: 'include' });
  if (!res.ok) throw new Error(`${res.status}`);
  const data: UserServerListResponse = await res.json();
  return data.servers ?? [];
}

async function createGlobalServer(body: ServerFormBody): Promise<void> {
  const res = await fetch('/api/mcp/servers', {
    method: 'POST',
    credentials: 'include',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify(body),
  });
  if (!res.ok) {
    const text = await res.text().catch(() => '');
    throw new Error(`${res.status} ${text}`);
  }
}

async function createUserServer(body: ServerFormBody): Promise<void> {
  const res = await fetch('/api/mcp/user-servers', {
    method: 'POST',
    credentials: 'include',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify(body),
  });
  if (!res.ok) {
    const text = await res.text().catch(() => '');
    throw new Error(`${res.status} ${text}`);
  }
}

async function deleteServer(id: string, isGlobal: boolean): Promise<void> {
  const url = isGlobal
    ? `/api/mcp/servers/${encodeURIComponent(id)}`
    : `/api/mcp/user-servers/${encodeURIComponent(id)}`;
  const res = await fetch(url, { method: 'DELETE', credentials: 'include' });
  if (!res.ok) throw new Error(`${res.status}`);
}

async function refreshTools(id: string, isGlobal: boolean): Promise<void> {
  const url = isGlobal
    ? `/api/mcp/servers/${encodeURIComponent(id)}/tools/refresh`
    : `/api/mcp/user-servers/${encodeURIComponent(id)}/tools/refresh`;
  const res = await fetch(url, { method: 'POST', credentials: 'include' });
  if (!res.ok) throw new Error(`${res.status}`);
}

// ── Form types & helpers ──────────────────────────────────────────────────────

interface ServerFormBody {
  id: string;
  name: string;
  url: string;
  authKind: 'oauth' | 'api_key';
  oauthClientId?: string;
  oauthClientSecret?: string;
  oauthScopes?: string;
  staticToken?: string;
  enabled?: boolean;
}

const emptyForm = (): ServerFormBody => ({
  id: '',
  name: '',
  url: '',
  authKind: 'oauth',
  oauthClientId: '',
  oauthClientSecret: '',
  oauthScopes: '',
  staticToken: '',
});

function FormField({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <label className="block">
      <span className="block text-2xs text-slate-600 mb-1">{label}</span>
      {children}
    </label>
  );
}

// ── AddServerForm ─────────────────────────────────────────────────────────────

interface AddServerFormProps {
  sectionLabel: string;
  onSubmit: (body: ServerFormBody) => Promise<void>;
  isPending: boolean;
}

function AddServerForm({ sectionLabel, onSubmit, isPending }: AddServerFormProps) {
  const [form, setForm] = useState<ServerFormBody>(emptyForm());
  const [formError, setFormError] = useState<string | null>(null);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setFormError(null);
    try {
      await onSubmit(form);
      setForm(emptyForm());
    } catch (err) {
      setFormError(err instanceof Error ? err.message : String(err));
    }
  };

  return (
    <form className="space-y-3 max-w-xl" onSubmit={handleSubmit}>
      <FormField label="ID (slug, 例: canva)">
        <input
          className="w-full border border-hairline rounded px-2 py-1 text-[13px]"
          value={form.id}
          onChange={(e) => setForm({ ...form, id: e.target.value })}
          placeholder="canva"
          pattern="[a-z0-9_-]{1,64}"
          required
        />
      </FormField>
      <FormField label="表示名">
        <input
          className="w-full border border-hairline rounded px-2 py-1 text-[13px]"
          value={form.name}
          onChange={(e) => setForm({ ...form, name: e.target.value })}
          placeholder="Canva"
          required
        />
      </FormField>
      <FormField label="MCP URL (https://...)">
        <input
          className="w-full border border-hairline rounded px-2 py-1 text-[13px]"
          value={form.url}
          onChange={(e) => setForm({ ...form, url: e.target.value })}
          placeholder="https://example.com/mcp"
          type="url"
          required
        />
      </FormField>

      {/* Auth kind radio */}
      <fieldset>
        <legend className="block text-2xs text-slate-600 mb-1">認証方式</legend>
        <div className="flex gap-4">
          <label className="flex items-center gap-1.5 text-[13px] cursor-pointer">
            <input
              type="radio"
              name={`authKind-${sectionLabel}`}
              value="oauth"
              checked={form.authKind === 'oauth'}
              onChange={() => setForm({ ...form, authKind: 'oauth' })}
            />
            OAuth
          </label>
          <label className="flex items-center gap-1.5 text-[13px] cursor-pointer">
            <input
              type="radio"
              name={`authKind-${sectionLabel}`}
              value="api_key"
              checked={form.authKind === 'api_key'}
              onChange={() => setForm({ ...form, authKind: 'api_key' })}
            />
            API key
          </label>
        </div>
      </fieldset>

      {/* OAuth-only fields */}
      {form.authKind === 'oauth' && (
        <>
          <FormField label="OAuth client_id">
            <input
              className="w-full border border-hairline rounded px-2 py-1 text-[13px]"
              value={form.oauthClientId ?? ''}
              onChange={(e) => setForm({ ...form, oauthClientId: e.target.value })}
              required
            />
          </FormField>
          <FormField label="OAuth client_secret">
            <input
              className="w-full border border-hairline rounded px-2 py-1 text-[13px]"
              type="password"
              value={form.oauthClientSecret ?? ''}
              onChange={(e) => setForm({ ...form, oauthClientSecret: e.target.value })}
              required
            />
          </FormField>
          <FormField label="scopes (space-separated, 任意)">
            <input
              className="w-full border border-hairline rounded px-2 py-1 text-[13px]"
              value={form.oauthScopes ?? ''}
              onChange={(e) => setForm({ ...form, oauthScopes: e.target.value })}
              placeholder="read write"
            />
          </FormField>
        </>
      )}

      {/* API key field */}
      {form.authKind === 'api_key' && (
        <FormField label="API key / Bearer token">
          <input
            className="w-full border border-hairline rounded px-2 py-1 text-[13px]"
            type="password"
            value={form.staticToken ?? ''}
            onChange={(e) => setForm({ ...form, staticToken: e.target.value })}
            placeholder="sk-..."
            required
          />
        </FormField>
      )}

      {formError && (
        <div className="text-xs text-red-600">{formError}</div>
      )}
      <button
        type="submit"
        className="px-4 py-1.5 rounded-md text-xs font-semibold bg-accent text-accent-fg hover:bg-accent-deep transition-colors disabled:opacity-50"
        disabled={isPending}
      >
        {isPending ? '保存中…' : '追加'}
      </button>
    </form>
  );
}

// ── ServerTable ───────────────────────────────────────────────────────────────

interface ServerTableProps {
  servers: ServerPublic[];
  isGlobal: boolean;
  canDelete: boolean;
  onRefresh: (id: string, isGlobal: boolean) => void;
  onDelete: (id: string, name: string, isGlobal: boolean) => void;
  refreshPending: boolean;
  deletePending: boolean;
}

function ServerTable({
  servers,
  isGlobal,
  canDelete,
  onRefresh,
  onDelete,
  refreshPending,
  deletePending,
}: ServerTableProps) {
  if (servers.length === 0) {
    return (
      <div className="text-[13px] text-slate-400">
        {isGlobal ? '登録された global サーバーがありません。' : 'あなたのサーバーがありません。'}
      </div>
    );
  }

  return (
    <table className="w-full text-[13px]">
      <thead className="text-left text-2xs uppercase tracking-wide text-slate-500">
        <tr className="border-b border-hairline">
          <th className="py-2 pr-2">ID</th>
          <th className="py-2 pr-2">名前</th>
          <th className="py-2 pr-2">URL</th>
          <th className="py-2 pr-2 w-20">認証</th>
          <th className="py-2 pr-2 w-16">有効</th>
          <th className="py-2 pr-2 w-24">ツール数</th>
          <th className="py-2 pr-2 w-40">操作</th>
        </tr>
      </thead>
      <tbody className="divide-y divide-hairline">
        {servers.map((s) => (
          <tr key={s.id}>
            <td className="py-2 pr-2 font-mono">{s.id}</td>
            <td className="py-2 pr-2">{s.name}</td>
            <td className="py-2 pr-2 font-mono text-2xs truncate max-w-xs" title={s.url}>{s.url}</td>
            <td className="py-2 pr-2">
              <span className={`inline-block px-1.5 py-0.5 rounded text-[10px] font-medium leading-none ${
                s.authKind === 'oauth'
                  ? 'bg-purple-50 text-purple-600'
                  : 'bg-amber-50 text-amber-600'
              }`}>
                {s.authKind === 'oauth' ? 'OAuth' : 'API key'}
              </span>
            </td>
            <td className="py-2 pr-2">{s.enabled ? '✓' : '—'}</td>
            <td className="py-2 pr-2">
              {s.toolCount == null || s.toolCount === 0 ? (
                <span className="text-[10px] text-slate-400 italic">未取得 — ツール更新を押してください</span>
              ) : (
                <span className="inline-block px-1.5 py-0.5 rounded text-[10px] font-medium bg-green-50 text-green-700 leading-none">
                  {s.toolCount} ツール
                </span>
              )}
            </td>
            <td className="py-2 pr-2 space-x-2">
              <button
                type="button"
                className="text-2xs text-slate-600 hover:text-slate-800 underline"
                onClick={() => onRefresh(s.id, isGlobal)}
                disabled={refreshPending}
              >ツール更新</button>
              {canDelete && (
                <button
                  type="button"
                  className="text-2xs text-red-600 hover:text-red-800 underline"
                  onClick={() => onDelete(s.id, s.name, isGlobal)}
                  disabled={deletePending}
                >削除</button>
              )}
            </td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

// ── McpServersPanel ───────────────────────────────────────────────────────────

type ShowToast = (message: string, variant?: 'success' | 'error') => void;

interface McpServersPanelProps {
  showToast?: ShowToast;
}

export function McpServersPanel({ showToast }: McpServersPanelProps = {}) {
  const qc = useQueryClient();
  const auth = useAuthState();
  const isAdmin = auth.mode === 'authenticated' ? auth.user.role === 'admin' : true;

  // Admin fetches global servers from /api/mcp/servers
  const { data: globalServers, isLoading: globalLoading, error: globalError } = useQuery({
    queryKey: ['mcp-servers-admin'],
    queryFn: fetchAdminServers,
    staleTime: 30_000,
    enabled: isAdmin,
  });

  // All users fetch their own servers
  const { data: userServers, isLoading: userLoading, error: userError } = useQuery({
    queryKey: ['mcp-user-servers'],
    queryFn: fetchUserServers,
    staleTime: 30_000,
  });

  const createGlobal = useMutation({
    mutationFn: createGlobalServer,
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['mcp-servers-admin'] });
      qc.invalidateQueries({ queryKey: ['mcp-connections'] });
    },
  });

  const createUser = useMutation({
    mutationFn: createUserServer,
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['mcp-user-servers'] });
      qc.invalidateQueries({ queryKey: ['mcp-connections'] });
    },
  });

  const del = useMutation({
    mutationFn: ({ id, isGlobal }: { id: string; isGlobal: boolean }) =>
      deleteServer(id, isGlobal),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['mcp-servers-admin'] });
      qc.invalidateQueries({ queryKey: ['mcp-user-servers'] });
      qc.invalidateQueries({ queryKey: ['mcp-connections'] });
    },
  });

  const refresh = useMutation({
    mutationFn: ({ id, isGlobal }: { id: string; isGlobal: boolean }) =>
      refreshTools(id, isGlobal),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['mcp-servers-admin'] });
      qc.invalidateQueries({ queryKey: ['mcp-user-servers'] });
    },
    onError: (err) => {
      const msg = 'ツール更新に失敗: ' + (err instanceof Error ? err.message : String(err));
      if (showToast) showToast(msg, 'error');
      else console.error(msg);
    },
  });

  const handleDelete = (id: string, name: string, isGlobal: boolean) => {
    const msg = isGlobal
      ? `${id} を削除しますか? 全ユーザーのトークンも失効します。`
      : `${name} を削除しますか?`;
    if (window.confirm(msg)) {
      del.mutate({ id, isGlobal });
    }
  };

  const handleRefresh = (id: string, isGlobal: boolean) => {
    refresh.mutate({ id, isGlobal });
  };

  return (
    <div className="h-full overflow-y-auto">
      <div className="max-w-3xl mx-auto px-6 py-8 space-y-8">
        <div>
          <h2 className="text-base font-semibold text-slate-900 mb-1">MCP サーバー管理</h2>
          <p className="text-[13px] text-slate-500 leading-relaxed">
            MCP サーバーを登録すると、エージェントがそのサーバーのツールを利用できるようになります。
            {isAdmin
              ? ' 管理者は全ユーザー共有の global サーバーと自分専用の personal サーバーを登録できます。'
              : ' あなた専用の personal サーバーを登録できます。'}
            OAuth credentials と API key は AES-256-GCM で暗号化されて保存されます。
          </p>
        </div>

        {/* ── Global Servers (admin only) ──────────────────────────────── */}
        {isAdmin && (
          <section className="space-y-4">
            <div className="flex items-center gap-2">
              <h3 className="text-[13px] font-semibold text-slate-900">Global Servers (admin 管理)</h3>
              <span className="inline-block px-1.5 py-0.5 rounded text-[10px] font-medium bg-slate-100 text-slate-500 leading-none">
                全ユーザー共有
              </span>
            </div>
            {globalLoading && <div className="text-[13px] text-slate-400">読み込み中…</div>}
            {globalError && (
              <div className="text-[13px] text-red-500">読み込みに失敗しました: {String(globalError)}</div>
            )}
            {!globalLoading && !globalError && (
              <ServerTable
                servers={globalServers ?? []}
                isGlobal={true}
                canDelete={true}
                onRefresh={handleRefresh}
                onDelete={handleDelete}
                refreshPending={refresh.isPending}
                deletePending={del.isPending}
              />
            )}
            <div>
              <h4 className="text-xs font-semibold text-slate-700 mb-2">Global サーバーを追加</h4>
              <AddServerForm
                sectionLabel="global"
                onSubmit={createGlobal.mutateAsync}
                isPending={createGlobal.isPending}
              />
            </div>
          </section>
        )}

        {/* ── Your Servers (all users) ──────────────────────────────────── */}
        <section className="space-y-4">
          <div className="flex items-center gap-2">
            <h3 className="text-[13px] font-semibold text-slate-900">個人サーバー</h3>
            <span className="inline-block px-1.5 py-0.5 rounded text-[10px] font-medium bg-blue-50 text-blue-600 leading-none">
              personal
            </span>
          </div>
          {userLoading && <div className="text-[13px] text-slate-400">読み込み中…</div>}
          {userError && (
            <div className="text-[13px] text-red-500">読み込みに失敗しました: {String(userError)}</div>
          )}
          {!userLoading && !userError && (
            <ServerTable
              servers={userServers ?? []}
              isGlobal={false}
              canDelete={true}
              onRefresh={handleRefresh}
              onDelete={handleDelete}
              refreshPending={refresh.isPending}
              deletePending={del.isPending}
            />
          )}
          <div>
            <h4 className="text-xs font-semibold text-slate-700 mb-2">Personal サーバーを追加</h4>
            <AddServerForm
              sectionLabel="personal"
              onSubmit={createUser.mutateAsync}
              isPending={createUser.isPending}
            />
          </div>
        </section>
      </div>
    </div>
  );
}
