<template>
  <div class="code-preview-wrapper relative w-full h-full min-h-[600px] flex flex-col font-sans text-gray-200">

    <!-- 背景噪点层 -->
    <div class="absolute inset-0 pointer-events-none z-0 opacity-20 mix-blend-overlay bg-noise"></div>

    <!-- 顶部工具栏 -->
    <div class="relative z-10 flex items-center justify-between px-6 py-4 bg-black/40 backdrop-blur-xl border-b border-white/5 rounded-t-2xl">
      <div class="flex items-center gap-4">
        <!-- 装饰性 Mac 窗口按钮 -->
        <div class="flex gap-2">
          <div class="w-3 h-3 rounded-full bg-[#ff5f56]"></div>
          <div class="w-3 h-3 rounded-full bg-[#ffbd2e]"></div>
          <div class="w-3 h-3 rounded-full bg-[#27c93f]"></div>
        </div>
        <span class="text-xs font-mono text-white/40 tracking-widest uppercase ml-2">Code Playground</span>

        <!-- 运行状态指示器 -->
        <div v-if="isRunning" class="flex items-center gap-2 px-2 py-0.5 rounded-full bg-yellow-500/10 border border-yellow-500/20">
          <span class="block w-1.5 h-1.5 rounded-full bg-yellow-500 animate-pulse"></span>
          <span class="text-[10px] font-mono text-yellow-500">Compiling...</span>
        </div>
      </div>

      <!-- 语言选择器 & 操作区 -->
      <div class="flex items-center gap-4">
        <CustomSelect
          v-model="selectedLanguage"
          :options="languageOptions"
          @update:modelValue="handleLanguageChange"
          placeholder="选择语言"
          style="width: 180px; font-family: monospace; font-size: 0.75rem;"
        />

        <button
            @click="runCode"
            class="flex items-center gap-2 px-3 py-1.5 bg-[#d4b383] hover:bg-[#c4a373] text-black text-xs font-bold rounded-lg transition-colors"
            title="运行代码 (Ctrl + Enter)"
        >
          <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M5 3l14 9-14 9V3z"/></svg>
          <span>RUN</span>
        </button>
      </div>
    </div>

    <!-- 主体内容区 -->
    <div class="relative z-10 flex-1 flex flex-col md:flex-row bg-[#050505]/80 backdrop-blur-sm rounded-b-2xl overflow-hidden border border-t-0 border-white/5">

      <!-- 左侧：代码编辑器 -->
      <div class="w-full md:w-1/2 relative flex flex-col border-b md:border-b-0 md:border-r border-white/5 group">
        <div class="absolute inset-0 bg-[#09090b]">
          <!-- 编辑器容器 -->
          <div class="relative w-full h-full font-mono text-sm leading-relaxed custom-scrollbar overflow-hidden">
            <pre
                ref="highlightBlock"
                class="absolute inset-0 p-6 m-0 pointer-events-none z-10 overflow-hidden whitespace-pre-wrap break-words"
                aria-hidden="true"
            ><code :class="`language-${selectedLanguage} !bg-transparent !p-0 font-mono`" v-html="highlightedCode"></code></pre>

            <textarea
                ref="textarea"
                v-model="code"
                @input="handleCodeChange"
                @scroll="syncScroll"
                @keydown.ctrl.enter.prevent="runCode"
                @keydown.meta.enter.prevent="runCode"
                class="absolute inset-0 w-full h-full p-6 m-0 bg-transparent text-transparent caret-[#d4b383] z-20 resize-none border-none outline-none font-mono whitespace-pre-wrap break-words"
                spellcheck="false"
                placeholder="// Type your code here..."
            ></textarea>
          </div>
        </div>
      </div>

      <!-- 右侧：实时预览 / 终端 -->
      <div class="w-full md:w-1/2 bg-[#121214] flex flex-col relative">
        <div class="h-8 flex items-center justify-between px-4 bg-white/5 border-b border-white/5 shrink-0">
          <span class="text-[10px] font-mono text-[#d4b383] tracking-widest uppercase">
            {{ isConsoleMode ? 'TERMINAL OUTPUT' : 'WEB PREVIEW' }}
          </span>
          <div class="flex items-center gap-2">
            <button @click="clearConsole" v-if="isConsoleMode" class="text-[10px] text-white/40 hover:text-white mr-2">CLEAR</button>
            <span v-if="error" class="flex items-center gap-1 text-[#ef4444] text-[10px]">
              <span class="w-1.5 h-1.5 rounded-full bg-[#ef4444]"></span> ERROR
            </span>
            <span v-else class="flex items-center gap-1 text-green-500 text-[10px]">
              <span class="w-1.5 h-1.5 rounded-full bg-green-500"></span> READY
            </span>
          </div>
        </div>

        <!-- Iframe 容器 -->
        <div class="flex-1 relative bg-white w-full h-full">
          <iframe
              ref="previewFrame"
              sandbox="allow-scripts allow-modals allow-same-origin"
              title="Code Preview"
              class="w-full h-full border-none"
              :class="{ 'bg-[#1e1e1e]': isConsoleMode }"
          ></iframe>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch, computed } from 'vue'
import hljs from 'highlight.js'
import 'highlight.js/styles/atom-one-dark.css'
import CustomSelect from './CustomSelect.vue'

// Props & Emits
const props = defineProps<{
  initialCode?: string
  initialLanguage?: string
}>()

// State
const code = ref('')
const selectedLanguage = ref(props.initialLanguage || 'html')
const error = ref('')
const isRunning = ref(false)
const previewFrame = ref<HTMLIFrameElement | null>(null)
const textarea = ref<HTMLTextAreaElement | null>(null)
const highlightBlock = ref<HTMLElement | null>(null)
const highlightedCode = ref('')

// Language options for CustomSelect
const languageOptions = [
  { value: 'html', label: 'HTML5' },
  { value: 'css', label: 'CSS3' },
  { value: 'javascript', label: 'JavaScript' },
  { value: 'vue', label: 'Vue 3 (SFC-ish)' },
  { value: 'react', label: 'React (JSX)' },
  { value: 'python', label: 'Python (Pyodide)' },
  { value: 'go', label: 'Go (Backend)' },
  { value: 'php', label: 'PHP (Backend)' },
  { value: 'node', label: 'Node.js (Backend)' }
]

// Default Templates
const templates: Record<string, string> = {
  html: `<h1>Hello HTML</h1>\n<p>Edit me!</p>`,
  css: `.box { \n  width: 100px; \n  height: 100px; \n  background: gold; \n}`,
  javascript: `console.log("Hello JS");\nconst x = 10;\nconsole.log(x * 2);`,
  vue: `<div id="app">\n  <h1>{{ message }}</h1>\n  <button @click="count++">Count: {{ count }}</button>\n</div>\n\n<script type="module">\n  import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'\n  createApp({\n    data() {\n      return {\n        message: 'Hello Vue 3!',\n        count: 0\n      }\n    }\n  }).mount('#app')\n<\/script>`,
  react: `// React Component\nfunction App() {\n  const [count, setCount] = React.useState(0);\n  return (\n    <div style={{padding: 20, textAlign: 'center'}}>\n      <h1>Hello React</h1>\n      <p>Count: {count}</p>\n      <button \n        onClick={() => setCount(count + 1)}\n        style={{padding: '8px 16px', background: '#61dafb', border: 'none', borderRadius: 4}}\n      >\n        Click Me\n      </button>\n    </div>\n  );\n}\n\n// Render\nconst root = ReactDOM.createRoot(document.getElementById('root'));\nroot.render(<App />);`,
  python: `# Python via Pyodide (Wasm)\nimport sys\n\nprint(f"Hello from Python {sys.version.split()[0]}")\n\ndef fib(n):\n    if n <= 1: return n\n    return fib(n-1) + fib(n-2)\n\nprint(f"Fib(10) = {fib(10)}")`,
  go: `package main\n\nimport "fmt"\n\nfunc main() {\n\tfmt.Println("Hello from Go!")\n}`,
  php: `<?php\n\necho "Hello from PHP " . phpversion();\n`,
  node: `console.log("Hello from Node.js " + process.version);`
}

// Computed
const isConsoleMode = computed(() => {
  return ['javascript', 'python', 'go', 'php', 'node'].includes(selectedLanguage.value)
})

// Initialize Code Logic - 修复：优先使用传入的代码
if (props.initialCode) {
  code.value = props.initialCode
} else {
  code.value = templates[selectedLanguage.value] || ''
}

// Watchers - 修复：监听 props 变化以支持从数据库动态加载
watch(() => props.initialCode, (newVal) => {
  if (newVal) {
    code.value = newVal
    highlightCode()
    // 延迟运行，给 DOM 一点时间
    setTimeout(() => runCode(), 100)
  }
})

watch(() => props.initialLanguage, (newVal) => {
  if (newVal) {
    selectedLanguage.value = newVal
  }
})

// Syntax Highlight
const highlightCode = () => {
  if (!code.value) {
    highlightedCode.value = ''
    return
  }
  try {
    const lang = selectedLanguage.value === 'vue' || selectedLanguage.value === 'react' ? 'javascript' : selectedLanguage.value
    const result = hljs.highlight(code.value, { language: lang })
    highlightedCode.value = result.value
  } catch (err) {
    highlightedCode.value = code.value
  }
}

const syncScroll = (e: Event) => {
  const target = e.target as HTMLTextAreaElement
  if (highlightBlock.value) {
    highlightBlock.value.scrollTop = target.scrollTop
    highlightBlock.value.scrollLeft = target.scrollLeft
  }
}

// --- Execution Engine ---

const runCode = async () => {
  if (!previewFrame.value) return
  isRunning.value = true
  error.value = ''

  const iframe = previewFrame.value
  const doc = iframe.contentDocument || iframe.contentWindow?.document
  if (!doc) return

  // 重置
  doc.open()

  // 1. HTML / CSS
  if (selectedLanguage.value === 'html') {
    doc.write(code.value)
    doc.close()
    isRunning.value = false
  }
  else if (selectedLanguage.value === 'css') {
    doc.write(`<html><head><style>${code.value}</style></head><body><div class="box">CSS Demo</div></body></html>`)
    doc.close()
    isRunning.value = false
  }
  // 2. JavaScript / Console
  else if (selectedLanguage.value === 'javascript') {
    const consoleTemplate = getConsoleTemplate(code.value)
    doc.write(consoleTemplate)
    doc.close()
    isRunning.value = false
  }
  // 3. Vue 3 (Global Build)
  else if (selectedLanguage.value === 'vue') {
    const vueTemplate = `
      <!DOCTYPE html>
      <html>
      <head>
        <style>body { font-family: sans-serif; background: #fff; color: #333; padding: 20px; }</style>
        <script src="https://unpkg.com/vue@3/dist/vue.global.js"><\/script>
      </head>
      <body>
        ${code.value}
      </body>
      </html>
    `
    doc.write(vueTemplate)
    doc.close()
    isRunning.value = false
  }
  // 4. React (Babel Standalone)
  else if (selectedLanguage.value === 'react') {
    const reactTemplate = `
      <!DOCTYPE html>
      <html>
      <head>
        <style>body { font-family: sans-serif; background: #fff; color: #333; margin: 0; }</style>
        <script src="https://unpkg.com/react@18/umd/react.development.js"><\/script>
        <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"><\/script>
        <script src="https://unpkg.com/@babel/standalone/babel.min.js"><\/script>
      </head>
      <body>
        <div id="root"></div>
        <script type="text/babel">
          ${code.value}
        <\/script>
      </body>
      </html>
    `
    doc.write(reactTemplate)
    doc.close()
    isRunning.value = false
  }
  // 5. Python (Pyodide Wasm)
  else if (selectedLanguage.value === 'python') {
    // Python 加载比较慢，显示 Loading
    const pythonTemplate = `
      <!DOCTYPE html>
      <html>
      <head>
        <style>
          body { background: #1e1e1e; color: #fff; font-family: monospace; padding: 20px; font-size: 14px; }
          .log { border-bottom: 1px solid #333; padding: 4px 0; white-space: pre-wrap; }
          .error { color: #ff6b6b; }
          .loading { color: #d4b383; }
        </style>
        <script src="https://cdn.jsdelivr.net/pyodide/v0.25.0/full/pyodide.js"><\/script>
      </head>
      <body>
        <div id="output">
          <div class="loading">Initializing Python Environment (Pyodide)... This may take a moment.</div>
        </div>
        <script>
          const output = document.getElementById('output');
          function print(text, type = '') {
            const div = document.createElement('div');
            div.className = 'log ' + type;
            div.textContent = text;
            output.appendChild(div);
          }

          async function main() {
            try {
              if (!window.pyodide) {
                window.pyodide = await loadPyodide();
                // 清除 Loading 文字
                output.innerHTML = '';
                print("Python 3.11 Ready.", "loading");
                print("------------------");
              }

              // 重定向 stdout
              pyodide.setStdout({ batched: (msg) => print(msg) });

              // 运行用户代码
              await pyodide.runPythonAsync(\`${code.value.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$')}\`);

            } catch (err) {
              print(err, 'error');
            }
          }
          main();
        <\/script>
      </body>
      </html>
    `
    doc.write(pythonTemplate)
    doc.close()
    isRunning.value = false
  }
  // 6. Backend Languages (Go, PHP, Node.js)
  else if (['go', 'php', 'node'].includes(selectedLanguage.value)) {
    // 显示 Loading 状态
    const loadingTemplate = `
      <!DOCTYPE html>
      <html>
      <body style="background:#1e1e1e;padding:20px;font-family:'JetBrains Mono', monospace;font-size:13px;color:#d4d4d8;margin:0;">
        <div style="color: #d4b383;">Running code on server...</div>
      </body>
      </html>
    `
    doc.write(loadingTemplate)
    
    try {
      const response = await fetch('/api/run', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          language: selectedLanguage.value,
          code: code.value
        })
      })
      
      if (!response.ok) {
        const errorData = await response.json()
        throw new Error(errorData.message || '代码执行失败')
      }
      
      const data = await response.json()
      const result = data.result // 从统一响应格式中提取 result
      
      let outputHtml = ''
      if (result.error) {
        outputHtml = `<div style="color: #ef4444; white-space: pre-wrap;">Error:\n${result.error}</div>`
      } else {
        outputHtml = `<div style="white-space: pre-wrap;">${result.output}</div>`
        if (result.exitCode !== 0) {
          outputHtml += `<div style="color: #ef4444; margin-top: 10px; border-top: 1px solid #333; padding-top: 5px;">Process exited with code ${result.exitCode}</div>`
        }
      }
      
      const resultTemplate = `
        <!DOCTYPE html>
        <html>
        <body style="background:#1e1e1e;padding:20px;font-family:'JetBrains Mono', monospace;font-size:13px;color:#d4d4d8;margin:0;">
          ${outputHtml}
          <div style="margin-top: 20px; font-size: 11px; color: #666;">Execution time: ${result.duration}ms</div>
        </body>
        </html>
      `
      
      // 重新写入结果
      doc.open()
      doc.write(resultTemplate)
      doc.close()
      
    } catch (err) {
      const errorTemplate = `
        <!DOCTYPE html>
        <html>
        <body style="background:#1e1e1e;padding:20px;font-family:'JetBrains Mono', monospace;font-size:13px;color:#ef4444;margin:0;">
          <div>Failed to connect to server. Ensure backend is running at http://localhost:8081</div>
          <div style="margin-top:10px;">${err}</div>
        </body>
        </html>
      `
      doc.open()
      doc.write(errorTemplate)
      doc.close()
    } finally {
      isRunning.value = false
    }
  }
}

// Helper: Custom Console for JS
const getConsoleTemplate = (jsCode: string) => {
  return `
    <!DOCTYPE html>
    <html>
    <body style="background:#1e1e1e;padding:20px;font-family:'JetBrains Mono', monospace;font-size:13px;color:#d4d4d8;margin:0;">
      <div id="console"></div>
      <script type="module">
        const logDiv = document.getElementById('console');
        const originalLog = console.log;

        // 劫持 console.log
        console.log = function(...args) {
          const line = document.createElement('div');
          line.style.borderBottom = '1px solid #333';
          line.style.padding = '6px 0';
          // 简单的对象转字符串
          line.textContent = '> ' + args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' ');
          logDiv.appendChild(line);
          originalLog.apply(console, args);
        };

        window.onerror = function(msg, url, line) {
          const err = document.createElement('div');
          err.style.color = '#ef4444';
          err.style.marginTop = '8px';
          err.textContent = 'Error: ' + msg;
          logDiv.appendChild(err);
        };

        try {
          ${jsCode}
        } catch(e) { console.error(e); }
      <\/script>
    </body>
    </html>
  `
}

let runTimer: ReturnType<typeof setTimeout> | null = null

const handleCodeChange = () => {
  highlightCode()
  // 对于非 Web 语言（如 Python/React），不自动运行，等待用户点击 Run
  if (['html', 'css', 'javascript'].includes(selectedLanguage.value)) {
    // Debounce auto-run for lightweight languages
    if (runTimer) clearTimeout(runTimer)
    runTimer = setTimeout(() => runCode(), 1000)
  }
}

const handleLanguageChange = () => {
  code.value = templates[selectedLanguage.value] || ''
  highlightCode()
  runCode()
}

const clearConsole = () => {
  if (previewFrame.value) {
    const doc = previewFrame.value.contentDocument
    if (doc) doc.body.innerHTML = '<div id="console"></div>' // 简单清空
  }
}

onMounted(() => {
  highlightCode()
  // Initial Run
  setTimeout(() => runCode(), 500)
})

</script>

<style scoped>
.bg-noise {
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)' opacity='0.07'/%3E%3C/svg%3E");
}

pre, textarea, code {
  font-family: 'JetBrains Mono', 'Fira Code', monospace !important;
}

.custom-scrollbar::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
.custom-scrollbar::-webkit-scrollbar-track {
  background: transparent;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 3px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
  background: #d4b383;
}
</style>