'use client';

import React, { useState, useCallback, useRef } from 'react';

interface Tool {
  name: string;
  description: string;
  method: string;
  endpoint: string;
  groupName?: string;
  inputSchema?: object;
  enabled: boolean;
}

interface GeneratedFile {
  path: string;
  content: string;
  preview?: string;
}

type Step = 'input' | 'analyzing' | 'review' | 'generating' | 'done';

export default function BuildPage() {
  const [step, setStep] = useState<Step>('input');
  const [specInput, setSpecInput] = useState('');
  const [serviceName, setServiceName] = useState('');
  const [tools, setTools] = useState<Tool[]>([]);
  const [analysis, setAnalysis] = useState<any>(null);
  const [files, setFiles] = useState<GeneratedFile[]>([]);
  const [progress, setProgress] = useState('');
  const [error, setError] = useState('');
  const [selectedFile, setSelectedFile] = useState<string | null>(null);
  const eventSourceRef = useRef<EventSource | null>(null);

  const handleAnalyze = useCallback(async () => {
    setError('');
    setStep('analyzing');
    setTools([]);
    setProgress('Starting analysis...');

    try {
      const isUrl = specInput.startsWith('http');
      const res = await fetch('/api/analyze', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(isUrl ? { specUrl: specInput } : { specContent: specInput }),
      });

      if (!res.body) throw new Error('No response body');

      const reader = res.body.getReader();
      const decoder = new TextDecoder();
      let buffer = '';

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split('\n');
        buffer = lines.pop() || '';

        let eventType = '';
        for (const line of lines) {
          if (line.startsWith('event: ')) {
            eventType = line.slice(7);
          } else if (line.startsWith('data: ') && eventType) {
            try {
              const data = JSON.parse(line.slice(6));
              if (eventType === 'progress') {
                setProgress(data.step);
              } else if (eventType === 'tool_found') {
                setTools(prev => [...prev, { ...data, enabled: true }]);
              } else if (eventType === 'complete') {
                setAnalysis(data.analysis);
                if (data.analysis?.toolGroups) {
                  const allTools: Tool[] = [];
                  for (const group of data.analysis.toolGroups) {
                    for (const tool of group.tools || []) {
                      allTools.push({ ...tool, groupName: group.name, enabled: true });
                    }
                  }
                  if (allTools.length > 0) setTools(allTools);
                }
                setStep('review');
              } else if (eventType === 'error') {
                setError(data.message);
                setStep('input');
              }
            } catch {}
            eventType = '';
          }
        }
      }
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : 'Analysis failed');
      setStep('input');
    }
  }, [specInput]);

  const handleGenerate = useCallback(async () => {
    setError('');
    setStep('generating');
    setFiles([]);
    setProgress('Generating MCP server...');

    try {
      const enabledTools = tools.filter(t => t.enabled);
      const res = await fetch('/api/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          analysis,
          tools: enabledTools,
          serviceName: serviceName || analysis?.service || 'custom',
        }),
      });

      if (!res.body) throw new Error('No response body');

      const reader = res.body.getReader();
      const decoder = new TextDecoder();
      let buffer = '';

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split('\n');
        buffer = lines.pop() || '';

        let eventType = '';
        for (const line of lines) {
          if (line.startsWith('event: ')) {
            eventType = line.slice(7);
          } else if (line.startsWith('data: ') && eventType) {
            try {
              const data = JSON.parse(line.slice(6));
              if (eventType === 'progress') {
                setProgress(data.step);
              } else if (eventType === 'file_ready') {
                setFiles(prev => [...prev, data]);
              } else if (eventType === 'complete') {
                setFiles(data.files || []);
                if (data.files?.length > 0) {
                  setSelectedFile(data.files[0].path);
                }
                setStep('done');
              } else if (eventType === 'error') {
                setError(data.message);
                setStep('review');
              }
            } catch {}
            eventType = '';
          }
        }
      }
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : 'Generation failed');
      setStep('review');
    }
  }, [tools, analysis, serviceName]);

  const toggleTool = (index: number) => {
    setTools(prev => prev.map((t, i) => i === index ? { ...t, enabled: !t.enabled } : t));
  };

  const downloadFiles = () => {
    const content = files.map(f => `// === ${f.path} ===\n\n${f.content}`).join('\n\n\n');
    const blob = new Blob([content], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${serviceName || 'mcp-server'}.txt`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const methodColors: Record<string, string> = {
    GET: 'bg-emerald-500/20 text-emerald-400',
    POST: 'bg-blue-500/20 text-blue-400',
    PUT: 'bg-amber-500/20 text-amber-400',
    PATCH: 'bg-amber-500/20 text-amber-400',
    DELETE: 'bg-red-500/20 text-red-400',
  };

  return (
    <div className="min-h-screen bg-[#0A0F1E]">
      {/* Header */}
      <header className="border-b border-gray-800 bg-gray-900/80 backdrop-blur-xl sticky top-0 z-50">
        <div className="max-w-5xl mx-auto px-6 py-4 flex items-center justify-between">
          <a href="/" className="text-xl font-bold">
            <span className="text-indigo-400">MCP</span>
            <span className="text-gray-100">Engine</span>
            <span className="text-gray-500 text-sm ml-2">Studio</span>
          </a>
          <div className="flex items-center gap-2 text-sm text-gray-400">
            <span className={`w-2 h-2 rounded-full ${step === 'done' ? 'bg-emerald-500' : step === 'input' ? 'bg-gray-500' : 'bg-indigo-500 animate-pulse'}`} />
            {step === 'input' && 'Ready'}
            {step === 'analyzing' && 'Analyzing...'}
            {step === 'review' && `${tools.filter(t => t.enabled).length} tools found`}
            {step === 'generating' && 'Generating...'}
            {step === 'done' && `${files.length} files generated`}
          </div>
        </div>
      </header>

      <main className="max-w-5xl mx-auto px-6 py-12">
        {/* Step 1: Input */}
        {step === 'input' && (
          <div className="space-y-8">
            <div className="text-center space-y-3">
              <h1 className="text-4xl font-bold">
                <span className="bg-gradient-to-r from-indigo-400 to-emerald-400 bg-clip-text text-transparent">
                  Build an MCP Server
                </span>
              </h1>
              <p className="text-gray-400 text-lg">Paste an OpenAPI spec or URL — we&apos;ll analyze it and generate a production MCP server.</p>
            </div>

            <div className="space-y-4">
              <div>
                <label className="block text-sm font-medium text-gray-300 mb-2">Server Name</label>
                <input
                  type="text"
                  value={serviceName}
                  onChange={e => setServiceName(e.target.value)}
                  placeholder="e.g., trello, stripe, my-api"
                  className="w-full bg-gray-800 border border-gray-600 rounded-lg px-4 py-3 text-gray-100 placeholder:text-gray-500 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 outline-none"
                />
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-300 mb-2">OpenAPI Spec (URL or paste content)</label>
                <textarea
                  value={specInput}
                  onChange={e => setSpecInput(e.target.value)}
                  placeholder={"Paste an OpenAPI/Swagger spec here (JSON or YAML)...\n\nOr paste a URL like:\nhttps://petstore3.swagger.io/api/v3/openapi.json"}
                  rows={12}
                  className="w-full bg-gray-800 border border-gray-600 rounded-lg px-4 py-3 text-gray-100 placeholder:text-gray-500 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 outline-none font-mono text-sm"
                />
              </div>
              {error && (
                <div className="bg-red-500/10 border border-red-500/30 rounded-lg p-4 text-red-400 text-sm">
                  {error}
                </div>
              )}
              <button
                onClick={handleAnalyze}
                disabled={!specInput.trim()}
                className="w-full bg-indigo-500 hover:bg-indigo-400 disabled:opacity-50 disabled:cursor-not-allowed text-white font-semibold py-3 px-6 rounded-lg transition-colors"
              >
                Analyze Spec →
              </button>
            </div>
          </div>
        )}

        {/* Step 2: Analyzing */}
        {step === 'analyzing' && (
          <div className="space-y-8">
            <div className="text-center space-y-3">
              <h2 className="text-2xl font-bold text-gray-100">Analyzing API...</h2>
              <p className="text-gray-400">{progress}</p>
              <div className="w-full bg-gray-800 rounded-full h-2 overflow-hidden">
                <div className="bg-indigo-500 h-2 rounded-full animate-pulse" style={{ width: '60%' }} />
              </div>
            </div>
            {tools.length > 0 && (
              <div className="space-y-3">
                <h3 className="text-sm font-medium text-gray-400 uppercase tracking-wider">Discovered Tools</h3>
                <div className="space-y-2">
                  {tools.map((tool, i) => (
                    <div key={i} className="bg-gray-800 border border-gray-700 rounded-lg p-3 flex items-center gap-3 animate-[fadeIn_0.3s_ease-out]">
                      <span className={`px-2 py-0.5 rounded text-xs font-mono font-bold ${methodColors[tool.method] || 'bg-gray-600 text-gray-300'}`}>
                        {tool.method}
                      </span>
                      <span className="text-gray-100 font-medium">{tool.name}</span>
                      <span className="text-gray-500 text-sm truncate">{tool.description}</span>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        )}

        {/* Step 3: Review Tools */}
        {step === 'review' && (
          <div className="space-y-8">
            <div className="text-center space-y-3">
              <h2 className="text-2xl font-bold text-gray-100">
                Found {tools.length} tools
              </h2>
              <p className="text-gray-400">Toggle tools on/off, then generate your MCP server.</p>
            </div>

            <div className="space-y-2">
              {tools.map((tool, i) => (
                <div
                  key={i}
                  className={`bg-gray-800 border rounded-lg p-4 flex items-center gap-4 transition-all cursor-pointer ${
                    tool.enabled ? 'border-gray-700 hover:border-gray-600' : 'border-gray-800 opacity-50'
                  }`}
                  onClick={() => toggleTool(i)}
                >
                  <input
                    type="checkbox"
                    checked={tool.enabled}
                    onChange={() => toggleTool(i)}
                    className="w-4 h-4 rounded border-gray-600 text-indigo-500 focus:ring-indigo-500 bg-gray-700"
                  />
                  <span className={`px-2 py-0.5 rounded text-xs font-mono font-bold shrink-0 ${methodColors[tool.method] || 'bg-gray-600 text-gray-300'}`}>
                    {tool.method}
                  </span>
                  <div className="min-w-0">
                    <span className="text-gray-100 font-medium">{tool.name}</span>
                    {tool.groupName && (
                      <span className="text-gray-600 text-xs ml-2">({tool.groupName})</span>
                    )}
                    <p className="text-gray-500 text-sm truncate">{tool.description}</p>
                  </div>
                </div>
              ))}
            </div>

            {error && (
              <div className="bg-red-500/10 border border-red-500/30 rounded-lg p-4 text-red-400 text-sm">
                {error}
              </div>
            )}

            <div className="flex gap-4">
              <button
                onClick={() => { setStep('input'); setError(''); }}
                className="flex-1 bg-gray-700 hover:bg-gray-600 text-gray-200 font-semibold py-3 px-6 rounded-lg transition-colors"
              >
                ← Back
              </button>
              <button
                onClick={handleGenerate}
                disabled={tools.filter(t => t.enabled).length === 0}
                className="flex-1 bg-emerald-500 hover:bg-emerald-400 disabled:opacity-50 text-white font-semibold py-3 px-6 rounded-lg transition-colors"
              >
                Generate Server ({tools.filter(t => t.enabled).length} tools) →
              </button>
            </div>
          </div>
        )}

        {/* Step 4: Generating */}
        {step === 'generating' && (
          <div className="space-y-8 text-center">
            <h2 className="text-2xl font-bold text-gray-100">Generating MCP Server...</h2>
            <p className="text-gray-400">{progress}</p>
            <div className="w-full bg-gray-800 rounded-full h-2 overflow-hidden">
              <div className="bg-emerald-500 h-2 rounded-full animate-pulse" style={{ width: '50%' }} />
            </div>
            {files.length > 0 && (
              <div className="text-left space-y-2">
                {files.map((f, i) => (
                  <div key={i} className="bg-gray-800 border border-gray-700 rounded-lg p-3 text-sm">
                    <span className="text-emerald-400 font-mono">✓ {f.path}</span>
                  </div>
                ))}
              </div>
            )}
          </div>
        )}

        {/* Step 5: Done */}
        {step === 'done' && (
          <div className="space-y-8">
            <div className="text-center space-y-3">
              <div className="text-5xl">🎉</div>
              <h2 className="text-2xl font-bold text-gray-100">
                MCP Server Generated!
              </h2>
              <p className="text-gray-400">{files.length} files ready — click to view, or download all.</p>
            </div>

            <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
              {/* File list */}
              <div className="space-y-2">
                {files.map((f, i) => (
                  <button
                    key={i}
                    onClick={() => setSelectedFile(f.path)}
                    className={`w-full text-left px-4 py-3 rounded-lg text-sm font-mono transition-colors ${
                      selectedFile === f.path
                        ? 'bg-indigo-500/20 border border-indigo-500/30 text-indigo-300'
                        : 'bg-gray-800 border border-gray-700 text-gray-300 hover:border-gray-600'
                    }`}
                  >
                    {f.path}
                  </button>
                ))}
              </div>

              {/* File preview */}
              <div className="lg:col-span-2 bg-gray-900 border border-gray-700 rounded-xl overflow-hidden">
                <div className="bg-gray-800 px-4 py-2 border-b border-gray-700 text-sm text-gray-400 font-mono">
                  {selectedFile || 'Select a file'}
                </div>
                <pre className="p-4 overflow-auto max-h-[500px] text-sm text-gray-300 font-mono whitespace-pre-wrap">
                  {files.find(f => f.path === selectedFile)?.content || 'Select a file to preview'}
                </pre>
              </div>
            </div>

            <div className="flex gap-4">
              <button
                onClick={() => { setStep('input'); setFiles([]); setTools([]); setAnalysis(null); setError(''); }}
                className="flex-1 bg-gray-700 hover:bg-gray-600 text-gray-200 font-semibold py-3 px-6 rounded-lg transition-colors"
              >
                ← Build Another
              </button>
              <button
                onClick={downloadFiles}
                className="flex-1 bg-emerald-500 hover:bg-emerald-400 text-white font-semibold py-3 px-6 rounded-lg transition-colors"
              >
                Download All Files ↓
              </button>
            </div>
          </div>
        )}
      </main>
    </div>
  );
}
