import { useState, useEffect, useRef } from 'react'
import { FiPlay, FiSave, FiShare2, FiSettings, FiDownload, FiUpload } from 'react-icons/fi'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { atomDark } from 'react-syntax-highlighter/dist/cjs/styles/prism'
import dynamic from 'next/dynamic'

const MonacoEditor = dynamic(() => import('@monaco-editor/react'), {
  ssr: false,
  loading: () => <div className="h-full bg-gray-800 rounded-lg animate-pulse" />
})

export default function CodeEditor() {
  const [code, setCode] = useState('')
  const [language, setLanguage] = useState('javascript')
  const [output, setOutput] = useState('')
  const [isRunning, setIsRunning] = useState(false)
  const [error, setError] = useState(null)
  const [theme, setTheme] = useState('vs-dark')
  const [fontSize, setFontSize] = useState(14)
  const [showSettings, setShowSettings] = useState(false)
  const [savedSnippets, setSavedSnippets] = useState([])
  const [snippetName, setSnippetName] = useState('')
  const editorRef = useRef(null)

  const languages = [
    { value: 'javascript', label: 'JavaScript', icon: '🟡' },
    { value: 'python', label: 'Python', icon: '🐍' },
    { value: 'java', label: 'Java', icon: '☕' },
    { value: 'csharp', label: 'C#', icon: '🔧' },
    { value: 'typescript', label: 'TypeScript', icon: '🔵' },
    { value: 'go', label: 'Go', icon: '🐹' },
    { value: 'rust', label: 'Rust', icon: '🦀' }
  ]

  const themes = [
    { value: 'vs-dark', label: 'Dark' },
    { value: 'vs-light', label: 'Light' },
    { value: 'hc-black', label: 'High Contrast' }
  ]

  useEffect(() => {
    const saved = localStorage.getItem('codeSnippets')
    if (saved) {
      setSavedSnippets(JSON.parse(saved))
    }
  }, [])

  const handleRunCode = async () => {
    if (!code.trim()) return

    setIsRunning(true)
    setError(null)
    setOutput('')

    try {
      const response = await fetch('/api/execute', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ code, language }),
      })

      const data = await response.json()

      if (response.ok) {
        setOutput(data.output)
      } else {
        throw new Error(data.error || 'Execution failed')
      }
    } catch (err) {
      setError(err.message)
    } finally {
      setIsRunning(false)
    }
  }

  const handleSaveSnippet = () => {
    if (!snippetName.trim()) return

    const newSnippet = {
      id: Date.now(),
      name: snippetName,
      code,
      language,
      createdAt: new Date().toISOString()
    }

    const updatedSnippets = [...savedSnippets, newSnippet]
    setSavedSnippets(updatedSnippets)
    localStorage.setItem('codeSnippets', JSON.stringify(updatedSnippets))
    setSnippetName('')
  }

  const handleLoadSnippet = (snippet) => {
    setCode(snippet.code)
    setLanguage(snippet.language)
  }

  const handleDownloadCode = () => {
    const blob = new Blob([code], { type: 'text/plain' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `code.${language === 'javascript' ? 'js' : language === 'python' ? 'py' : 'txt'}`
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
    URL.revokeObjectURL(url)
  }

  const handleUploadCode = (e) => {
    const file = e.target.files[0]
    if (!file) return

    const reader = new FileReader()
    reader.onload = (event) => {
      setCode(event.target.result)
    }
    reader.readAsText(file)
  }

  const handleEditorMount = (editor) => {
    editorRef.current = editor
  }

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap justify-between items-center gap-4">
        <div className="flex items-center space-x-4">
          <select
            value={language}
            onChange={(e) => setLanguage(e.target.value)}
            className="bg-gray-700 text-white px-3 py-2 rounded-lg"
          >
            {languages.map((lang) => (
              <option key={lang.value} value={lang.value}>
                {lang.icon} {lang.label}
              </option>
            ))}
          </select>

          <button
            onClick={handleRunCode}
            disabled={isRunning}
            className={`px-4 py-2 rounded-lg flex items-center space-x-2 ${isRunning ? 'bg-gray-600' : 'bg-accent hover:bg-purple-600'} text-white transition-colors`}
          >
            <FiPlay />
            <span>{isRunning ? 'Running...' : 'Run Code'}</span>
          </button>

          <button
            onClick={() => setShowSettings(!showSettings)}
            className="px-4 py-2 bg-gray-700 hover:bg-gray-600 text-white rounded-lg flex items-center space-x-2 transition-colors"
          >
            <FiSettings />
            <span>Settings</span>
          </button>
        </div>

        <div className="flex items-center space-x-2">
          <label className="px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-lg cursor-pointer flex items-center space-x-2 transition-colors">
            <FiUpload />
            <span>Upload</span>
            <input type="file" className="hidden" onChange={handleUploadCode} accept=".js,.py,.java,.cs,.ts,.go,.rs" />
          </label>

          <button
            onClick={handleDownloadCode}
            className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg flex items-center space-x-2 transition-colors"
          >
            <FiDownload />
            <span>Download</span>
          </button>

          <div className="flex items-center space-x-2">
            <input
              type="text"
              placeholder="Snippet name"
              value={snippetName}
              onChange={(e) => setSnippetName(e.target.value)}
              className="px-3 py-2 bg-gray-700 text-white rounded-lg text-sm"
            />
            <button
              onClick={handleSaveSnippet}
              disabled={!snippetName.trim()}
              className="px-4 py-2 bg-yellow-600 hover:bg-yellow-700 text-white rounded-lg flex items-center space-x-2 transition-colors disabled:opacity-50"
            >
              <FiSave />
              <span>Save</span>
            </button>
          </div>
        </div>
      </div>

      {showSettings && (
        <div className="bg-gray-800 rounded-lg p-4 mb-4">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <label className="block text-sm font-medium text-gray-300 mb-1">Theme</label>
              <select
                value={theme}
                onChange={(e) => setTheme(e.target.value)}
                className="w-full bg-gray-700 text-white px-3 py-2 rounded-lg"
              >
                {themes.map((t) => (
                  <option key={t.value} value={t.value}>{t.label}</option>
                ))}
              </select>
            </div>
            <div>
              <label className="block text-sm font-medium text-gray-300 mb-1">Font Size</label>
              <input
                type="range"
                min="12"
                max="24"
                value={fontSize}
                onChange={(e) => setFontSize(parseInt(e.target.value))}
                className="w-full"
              />
              <div className="text-center text-sm text-gray-300 mt-1">{fontSize}px</div>
            </div>
          </div>
        </div>
      )}

      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 h-[calc(100vh-250px)]">
        <div className="bg-gray-800 rounded-lg overflow-hidden">
          <div className="bg-gray-900 px-4 py-2 flex justify-between items-center">
            <span className="text-sm text-gray-300">Editor</span>
            {savedSnippets.length > 0 && (
              <select
                onChange={(e) => handleLoadSnippet(JSON.parse(e.target.value))}
                className="bg-gray-700 text-white px-2 py-1 rounded text-sm"
              >
                <option value="">Load Snippet</option>
                {savedSnippets.map((snippet) => (
                  <option key={snippet.id} value={JSON.stringify(snippet)}>
                    {snippet.name} ({snippet.language})
                  </option>
                ))}
              </select>
            )}
          </div>
          <div className="h-[calc(100%-40px)]">
            <MonacoEditor
              height="100%"
              language={language}
              theme={theme}
              value={code}
              onChange={setCode}
              onMount={handleEditorMount}
              options={{
                fontSize,
                minimap: { enabled: false },
                wordWrap: 'on',
                scrollBeyondLastLine: false,
                automaticLayout: true

            />
          </div>
        </div>

        <div className="bg-gray-100 rounded-lg p-4 overflow-auto">
          <div className="flex justify-between items-center mb-4">
            <h3 className="font-bold text-gray-800">Output Console</h3>
            <button
              onClick={() => setOutput('')}
              className="text-sm text-gray-500 hover:text-gray-700"
            >
              Clear
            </button>
          </div>
          {error ? (
            <div className="text-red-600 p-3 bg-red-50 rounded-lg">
              <strong>Error:</strong> {error}
            </div>
          ) : (
            <div className="bg-white p-3 rounded-lg h-[calc(100%-50px)] overflow-auto">
              {output ? (
                <SyntaxHighlighter language={language} style={atomDark} customStyle={{ background: 'transparent' }}>
                  {output}
                </SyntaxHighlighter>
              ) : (
                <p className="text-gray-500">Code execution output will appear here...</p>
              )}
            </div>
          )}
        </div>
      </div>

      {savedSnippets.length > 0 && (
        <div className="mt-4 bg-gray-800 rounded-lg p-4">
          <h3 className="font-bold text-white mb-3">Saved Snippets</h3>
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
            {savedSnippets.map((snippet) => (
              <div key={snippet.id} className="bg-gray-700 rounded-lg p-3 hover:bg-gray-600 transition-colors cursor-pointer" onClick={() => handleLoadSnippet(snippet)}>
                <div className="flex justify-between items-start">
                  <div>
                    <h4 className="font-medium text-white">{snippet.name}</h4>
                    <p className="text-xs text-gray-400">{snippet.language}</p>
                  </div>
                  <span className="text-xs text-gray-400">
                    {new Date(snippet.createdAt).toLocaleDateString()}
                  </span>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  )
}