'use client';

import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { apiFetch } from '@/lib/api';
import { Button } from '@/components/ui/button';
import { Input, Label, Textarea } from '@/components/input';
import { StreamingLogs } from '@/components/streaming-logs';
import { InstallSnippets } from '@/components/install-snippets';
import { CodeBlock } from '@/components/code-block';

const EXAMPLE_PROMPTS = [
  'Read-only Postgres reader for the users and orders tables at db.example.com',
  'Search and read pages from our Notion workspace via the Notion API',
  'Wrap our internal HTTP API at api.acme.com — endpoints /search and /lookup',
  'Stripe charges and customers (read-only)',
];

type Step = 'prompt' | 'building' | 'done';

interface BuildResult {
  serverId: string;
  publicUrl: string | null;
}

export default function NewServerPage() {
  const router = useRouter();
  const [step, setStep] = useState<Step>('prompt');
  const [name, setName] = useState('');
  const [slug, setSlug] = useState('');
  const [prompt, setPrompt] = useState('');
  const [secretRows, setSecretRows] = useState<{ key: string; value: string }[]>([{ key: '', value: '' }]);
  const [error, setError] = useState<string | null>(null);
  const [buildId, setBuildId] = useState<string | null>(null);
  const [serverId, setServerId] = useState<string | null>(null);
  const [result, setResult] = useState<BuildResult | null>(null);

  const trySlug = (n: string) =>
    n.toLowerCase().replace(/[^a-z0-9-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 32);

  async function submit() {
    setError(null);
    if (!name || !slug || prompt.length < 10) {
      setError('Name, slug and a prompt of at least 10 characters are required.');
      return;
    }
    const secrets: Record<string, string> = {};
    for (const row of secretRows) {
      if (row.key && row.value) secrets[row.key.trim()] = row.value;
    }
    try {
      const res = await apiFetch<{ server: { id: string }; build: { id: string } }>(
        '/v1/servers',
        { method: 'POST', body: JSON.stringify({ name, slug, prompt, secrets }) },
      );
      setBuildId(res.build.id);
      setServerId(res.server.id);
      setStep('building');
    } catch (e) {
      const detail = (e as { detail?: { error?: string } }).detail;
      setError(detail?.error ?? (e as Error).message);
    }
  }

  return (
    <div className="mx-auto max-w-3xl px-6 py-8">
      <div className="flex items-baseline justify-between">
        <h1 className="text-[22px] font-semibold tracking-tight">New MCP server</h1>
        <div className="mono text-[11px] tracking-wider text-[--color-fg-subtle]">
          STEP {step === 'prompt' ? '1' : step === 'building' ? '2' : '3'} / 3
        </div>
      </div>

      {step === 'prompt' && (
        <div className="mt-7 space-y-5">
          <div className="space-y-1.5">
            <Label htmlFor="prompt">Describe your tool</Label>
            <Textarea
              id="prompt"
              rows={5}
              value={prompt}
              onChange={(e) => setPrompt(e.target.value)}
              placeholder="A sentence is enough. Mention APIs, secrets, scopes, expected tool names."
            />
            <div className="flex flex-wrap gap-1.5">
              {EXAMPLE_PROMPTS.map((p) => (
                <button
                  type="button"
                  key={p}
                  onClick={() => setPrompt(p)}
                  className="rounded-full border border-[--color-border] bg-[--color-bg-subtle] px-2.5 py-1 text-[11.5px] text-[--color-fg-muted] transition-colors hover:border-[--color-border-strong] hover:text-[--color-fg]"
                >
                  {p}
                </button>
              ))}
            </div>
          </div>

          <div className="grid gap-3 md:grid-cols-2">
            <div className="space-y-1.5">
              <Label htmlFor="name">Name</Label>
              <Input
                id="name"
                value={name}
                onChange={(e) => {
                  setName(e.target.value);
                  if (!slug || slug === trySlug(name)) setSlug(trySlug(e.target.value));
                }}
                placeholder="Notion Reader"
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="slug" hint="subdomain / id">Slug</Label>
              <Input
                id="slug"
                value={slug}
                onChange={(e) => setSlug(trySlug(e.target.value))}
                placeholder="notion-reader"
              />
            </div>
          </div>

          <div className="space-y-2">
            <Label hint="environment variables, encrypted at rest">Secrets</Label>
            <div className="space-y-2">
              {secretRows.map((row, i) => (
                <div key={i} className="grid grid-cols-[1fr_1fr_auto] gap-2">
                  <Input
                    placeholder="NOTION_API_KEY"
                    value={row.key}
                    onChange={(e) => {
                      const next = [...secretRows];
                      next[i] = { key: e.target.value.toUpperCase(), value: row.value };
                      setSecretRows(next);
                    }}
                  />
                  <Input
                    placeholder="secret_xxx"
                    type="password"
                    value={row.value}
                    onChange={(e) => {
                      const next = [...secretRows];
                      next[i] = { key: row.key, value: e.target.value };
                      setSecretRows(next);
                    }}
                  />
                  <Button
                    variant="ghost"
                    size="md"
                    onClick={() =>
                      setSecretRows((rs) => (rs.length > 1 ? rs.filter((_, j) => j !== i) : rs))
                    }
                  >
                    Remove
                  </Button>
                </div>
              ))}
              <Button
                variant="ghost"
                size="sm"
                onClick={() => setSecretRows((rs) => [...rs, { key: '', value: '' }])}
              >
                + Add secret
              </Button>
            </div>
          </div>

          {error && <p className="text-[12.5px] text-[--color-danger]">{error}</p>}

          <div className="flex justify-end gap-2">
            <Button variant="ghost" size="md" onClick={() => router.push('/servers')}>
              Cancel
            </Button>
            <Button variant="primary" size="md" onClick={submit}>
              Build server →
            </Button>
          </div>
        </div>
      )}

      {step === 'building' && buildId && (
        <div className="mt-7 space-y-4">
          <p className="text-[13px] text-[--color-fg-muted]">
            Building your server. Logs stream live over WebSocket from the generator.
          </p>
          <StreamingLogs
            buildId={buildId}
            onDone={(status, publicUrl) => {
              if (status === 'success') {
                setResult({ serverId: serverId!, publicUrl });
                setStep('done');
              } else {
                setError(`Build ${status}`);
              }
            }}
          />
          {error && <p className="text-[12.5px] text-[--color-danger]">{error}</p>}
        </div>
      )}

      {step === 'done' && result && (
        <div className="mt-7 space-y-6">
          <div className="panel p-4">
            <div className="flex items-baseline justify-between">
              <h2 className="text-[14px] font-semibold tracking-tight">Your server is live</h2>
              <span className="mono text-[11px] text-emerald-300">200 OK</span>
            </div>
            <p className="mt-1 text-[12.5px] text-[--color-fg-muted]">
              OAuth-protected Streamable HTTP endpoint:
            </p>
            <div className="mt-3">
              <CodeBlock code={`${result.publicUrl}/mcp`} label="endpoint" />
            </div>
          </div>

          {result.publicUrl && (
            <div>
              <h2 className="text-[14px] font-semibold tracking-tight">Install</h2>
              <p className="mt-1 text-[12.5px] text-[--color-fg-muted]">
                Drop this into your client. OAuth handshake runs automatically on first use.
              </p>
              <div className="mt-3">
                <InstallSnippets
                  input={{ name, slug, publicUrl: result.publicUrl }}
                />
              </div>
            </div>
          )}

          <div className="flex justify-end gap-2">
            <Button
              variant="secondary"
              size="md"
              onClick={() => router.push(`/servers/${result.serverId}`)}
            >
              Open server →
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}
