'use client';

import { useState, useRef, useEffect } from 'react';
import { useRouter } from 'next/navigation';

const TEMPLATES = [
  {
    id: 'blank',
    name: '空白',
    html: '<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n  <meta charset="UTF-8">\n  <meta name="viewport" content="width=device-width, initial-scale=1.0">\n  <title>页面</title>\n  <style>\n    body {\n      font-family: system-ui, sans-serif;\n      max-width: 720px;\n      margin: 0 auto;\n      padding: 2rem;\n    }\n  </style>\n</head>\n<body>\n  <h1>Hello, World!</h1>\n  <script>\n    console.log("Hello from Code Sandbox!");\n  </script>\n</body>\n</html>',
  },
  {
    id: 'react',
    name: 'React (CDN)',
    html: '<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n  <meta charset="UTF-8">\n  <meta name="viewport" content="width=device-width, initial-scale=1.0">\n  <title>React Demo</title>\n  <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>\n  <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>\n  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>\n</head>\n<body>\n  <div id="root"></div>\n  <script type="text/babel">\n    function App() {\n      const [count, setCount] = React.useState(0);\n      return (\n        <div style={{ textAlign: "center", padding: "2rem" }}>\n          <h1>React 计数器</h1>\n          <p>计数: {count}</p>\n          <button onClick={() => setCount(c => c + 1)}>+1</button>\n          <button onClick={() => setCount(c => c - 1)}>-1</button>\n        </div>\n      );\n    }\n    ReactDOM.createRoot(document.getElementById("root")).render(<App />);\n  </script>\n</body>\n</html>',
  },
  {
    id: 'chart',
    name: '图表 (Chart.js)',
    html: '<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n  <meta charset="UTF-8">\n  <meta name="viewport" content="width=device-width, initial-scale=1.0">\n  <title>图表</title>\n  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>\n  <style>\n    body { font-family: system-ui, sans-serif; display: flex; justify-content: center; padding: 2rem; }\n    canvas { max-width: 600px; max-height: 400px; }\n  </style>\n</head>\n<body>\n  <div style="width: 600px;">\n    <h2 style="text-align: center;">示例图表</h2>\n    <canvas id="myChart"></canvas>\n  </div>\n  <script>\n    new Chart(document.getElementById("myChart"), {\n      type: "bar",\n      data: {\n        labels: ["一月", "二月", "三月", "四月", "五月", "六月"],\n        datasets: [{\n          label: "销量",\n          data: [12, 19, 3, 5, 2, 3],\n          backgroundColor: "rgba(99, 102, 241, 0.5)",\n          borderColor: "rgb(99, 102, 241)",\n          borderWidth: 1,\n        }],\n      },\n    });\n  </script>\n</body>\n</html>',
  },
  {
    id: 'three',
    name: '3D (Three.js)',
    html: '<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n  <meta charset="UTF-8">\n  <meta name="viewport" content="width=device-width, initial-scale=1.0">\n  <title>Three.js</title>\n  <script type="importmap">\n    { "imports": { "three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js" } }\n  </script>\n</head>\n<body>\n  <script type="module">\n    import * as THREE from "three";\n    const scene = new THREE.Scene();\n    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);\n    const renderer = new THREE.WebGLRenderer();\n    renderer.setSize(window.innerWidth, window.innerHeight);\n    document.body.appendChild(renderer.domElement);\n    const geo = new THREE.BoxGeometry(1, 1, 1);\n    const mat = new THREE.MeshPhongMaterial({ color: 0x6366f1 });\n    const cube = new THREE.Mesh(geo, mat);\n    scene.add(cube);\n    const light = new THREE.DirectionalLight(0xffffff, 1);\n    light.position.set(5, 5, 5);\n    scene.add(light);\n    scene.add(new THREE.AmbientLight(0x404060));\n    camera.position.z = 3;\n    function animate() {\n      requestAnimationFrame(animate);\n      cube.rotation.x += 0.01;\n      cube.rotation.y += 0.01;\n      renderer.render(scene, camera);\n    }\n    animate();\n  </script>\n</body>\n</html>',
  },
];

export default function CodeSandboxPage() {
  const router = useRouter();
  const [code, setCode] = useState(TEMPLATES[0].html);
  const [template, setTemplate] = useState('blank');
  const [previewKey, setPreviewKey] = useState(0);
  const [logs, setLogs] = useState<string[]>([]);
  const [error, setError] = useState('');
  const iframeRef = useRef<HTMLIFrameElement>(null);

  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const initialCode = params.get('code');
    if (initialCode) {
      try {
        setCode(atob(initialCode));
        setTemplate('');
      } catch (err) {
        console.error('Failed to decode code param:', err);
      }
    }
  }, []);

  function handleTemplateSelect(tplId: string) {
    const tpl = TEMPLATES.find(t => t.id === tplId);
    if (tpl) {
      setCode(tpl.html);
      setTemplate(tplId);
      setLogs([]);
      setError('');
    }
  }

  function handleRun() {
    setPreviewKey(k => k + 1);
    setLogs([]);
    setError('');
  }

  function handleIframeLoad() {
    try {
      const iframe = iframeRef.current;
      if (!iframe || !iframe.contentWindow) return;
      const win = iframe.contentWindow as unknown as { console: Console };
      const origLog = win.console.log;
      const origError = win.console.error;
      const newLogs: string[] = [];
      win.console.log = (...args: any[]) => {
        newLogs.push(args.map(a => typeof a === 'object' ? JSON.stringify(a, null, 2) : String(a)).join(' '));
        setLogs(prev => [...prev, ...newLogs.slice(prev.length)]);
      };
      win.console.error = (...args: any[]) => {
        const msg = '❌ ' + args.map(a => String(a)).join(' ');
        newLogs.push(msg);
        setLogs(prev => [...prev, msg]);
      };
      setTimeout(() => {
        setLogs(newLogs);
      }, 500);
    } catch (err) {
      console.error('Failed to setup iframe console:', err);
    }
  }

  function handleKeyDown(e: React.KeyboardEvent) {
    if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {
      e.preventDefault();
      handleRun();
    }
  }

  return (
    <div className="h-[calc(100vh-4rem)] flex flex-col">
      <div className="flex items-center justify-between px-4 sm:px-6 py-2 border-b border-border bg-card shrink-0">
        <div className="flex items-center gap-3">
          <button onClick={() => router.push('/sandbox')} className="text-sm text-muted-foreground hover:text-foreground">
            &larr; 沙盒
          </button>
          <span className="text-sm font-medium text-foreground">代码沙盒</span>
        </div>
        <div className="flex items-center gap-2">
          <select value={template} onChange={e => handleTemplateSelect(e.target.value)}
            className="px-2 py-1 text-xs border border-border rounded-lg bg-background text-foreground focus:outline-none">
            <option value="">模板...</option>
            {TEMPLATES.map(t => <option key={t.id} value={t.id}>{t.name}</option>)}
          </select>
          <button onClick={handleRun}
            className="px-3 py-1.5 text-xs font-medium bg-brand-600 text-white rounded-lg hover:bg-brand-700">
            运行 (⌘⏎)
          </button>
        </div>
      </div>

      <div className="flex-1 flex flex-col lg:flex-row min-h-0">
        <div className="flex-1 flex flex-col min-h-0 lg:w-1/2">
          <div className="px-4 py-1.5 text-xs text-muted-foreground border-b border-border bg-muted/30 shrink-0">
            HTML / CSS / JavaScript
          </div>
          <textarea
            value={code}
            onChange={e => { setCode(e.target.value); setTemplate(''); }}
            onKeyDown={handleKeyDown}
            className="flex-1 w-full p-4 text-sm font-mono leading-relaxed bg-background text-foreground resize-none focus:outline-none"
            spellCheck={false}
          />
        </div>

        <div className="flex-1 flex flex-col min-h-0 lg:w-1/2 border-t lg:border-t-0 lg:border-l border-border">
          <div className="flex-1 bg-background relative">
            <iframe
              key={previewKey}
              ref={iframeRef}
              srcDoc={code}
              onLoad={handleIframeLoad}
              className="w-full h-full border-0"
              title="预览"
               sandbox="allow-scripts allow-modals"
            />
          </div>
          {logs.length > 0 && (
            <div className="h-32 border-t border-border bg-card overflow-y-auto p-3 shrink-0">
              <div className="text-xs font-medium text-muted-foreground mb-1">控制台输出</div>
              {logs.map((log, i) => (
                <div key={i} className="text-xs font-mono text-foreground py-0.5">{log}</div>
              ))}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
