import { useState, useEffect, useRef } from 'react'
import { FileText, Save, RefreshCw, AlertTriangle, Check, X, ChevronDown } from 'lucide-react'
import { getPalworldConfigs, getPalworldConfig, savePalworldConfig } from '../api'

export default function PalworldConfigEditor({ token }) {
  const [files, setFiles] = useState([])
  const [selectedFile, setSelectedFile] = useState(null)
  const [content, setContent] = useState('')
  const [originalContent, setOriginalContent] = useState('')
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState(null)
  const [success, setSuccess] = useState(null)
  const [hasChanges, setHasChanges] = useState(false)
  const textareaRef = useRef(null)
  const highlightRef = useRef(null)

  // Load file list
  useEffect(() => {
    loadFiles()
  }, [token])

  // Track changes
  useEffect(() => {
    setHasChanges(content !== originalContent)
  }, [content, originalContent])

  // Sync scroll between textarea and highlight div
  const handleScroll = () => {
    if (highlightRef.current && textareaRef.current) {
      highlightRef.current.scrollTop = textareaRef.current.scrollTop
      highlightRef.current.scrollLeft = textareaRef.current.scrollLeft
    }
  }

  async function loadFiles() {
    setLoading(true)
    setError(null)
    try {
      const data = await getPalworldConfigs(token)
      setFiles(data.files || [])
      if (data.files?.length > 0 && !selectedFile) {
        loadFile(data.files[0].filename)
      }
    } catch (err) {
      setError('Fehler beim Laden der Config-Dateien: ' + err.message)
    } finally {
      setLoading(false)
    }
  }

  async function loadFile(filename) {
    setLoading(true)
    setError(null)
    setSuccess(null)
    try {
      const data = await getPalworldConfig(token, filename)
      setSelectedFile(filename)
      // Format the config for better readability
      let formattedContent = data.content
      if (filename === 'PalWorldSettings.ini') {
        formattedContent = formatPalworldConfig(data.content)
      }
      setContent(formattedContent)
      setOriginalContent(formattedContent)
    } catch (err) {
      setError('Fehler beim Laden: ' + err.message)
    } finally {
      setLoading(false)
    }
  }

  // Format Palworld config for better readability
  function formatPalworldConfig(content) {
    // The config is one long line with OptionSettings=(...)
    // We'll split key=value pairs for better readability
    return content
      .replace(/,(?=[A-Z])/g, ',\n')  // Add newline before each key
      .replace(/\((?=[A-Z])/g, '(\n')  // Newline after opening paren
      .replace(/\)$/gm, '\n)')  // Newline before closing paren
  }

  // Compact config back to single line for saving
  function compactPalworldConfig(content) {
    if (!selectedFile?.includes('PalWorldSettings.ini')) return content
    return content
      .split('\n')
      .map(line => line.trim())
      .join('')
      .replace(/,\s+/g, ',')
  }

  async function handleSave() {
    if (!selectedFile || !hasChanges) return

    setSaving(true)
    setError(null)
    setSuccess(null)
    try {
      const saveContent = selectedFile === 'PalWorldSettings.ini'
        ? compactPalworldConfig(content)
        : content
      await savePalworldConfig(token, selectedFile, saveContent)
      setOriginalContent(content)
      setSuccess('Config gespeichert! Server-Neustart erforderlich.')
      setTimeout(() => setSuccess(null), 5000)
    } catch (err) {
      setError('Fehler beim Speichern: ' + err.message)
    } finally {
      setSaving(false)
    }
  }

  function handleDiscard() {
    setContent(originalContent)
    setError(null)
    setSuccess(null)
  }

  function getFileDescription(filename) {
    const descriptions = {
      'PalWorldSettings.ini': 'Server-Einstellungen (Spieler, Raten, RCON)',
      'Engine.ini': 'Engine-Konfiguration (Performance)',
      'GameUserSettings.ini': 'Grafik und Audio Einstellungen'
    }
    return descriptions[filename] || filename
  }

  // Highlight syntax for INI files
  function highlightSyntax(text) {
    if (!text) return ''

    const lines = text.split('\n')

    return lines.map((line) => {
      let highlighted = line
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')

      // Section headers [Section]
      if (line.trim().startsWith('[') && line.trim().endsWith(']')) {
        highlighted = `<span class="text-purple-400">${highlighted}</span>`
      }
      // Comments (;)
      else if (line.trim().startsWith(';')) {
        highlighted = `<span class="text-emerald-500">${highlighted}</span>`
      }
      // Highlight key=value
      else if (line.includes('=')) {
        const idx = line.indexOf('=')
        const key = highlighted.substring(0, idx)
        const value = highlighted.substring(idx + 1)

        // Color numbers first (before adding any HTML tags), then booleans
        // This prevents the regex from matching numbers in CSS class names like "text-orange-400"
        let coloredValue = value
          .replace(/\b(\d+\.?\d*)\b/g, '%%%NUM_START%%%$1%%%NUM_END%%%')
          .replace(/\b(True|False)\b/gi, '<span class="text-orange-400">$1</span>')
          .replace(/%%%NUM_START%%%/g, '<span class="text-cyan-400">')
          .replace(/%%%NUM_END%%%/g, '</span>')

        highlighted = `<span class="text-blue-400">${key}</span>=<span class="text-amber-300">${coloredValue}</span>`
      }

      return highlighted
    }).join('\n')
  }

  if (loading && files.length === 0) {
    return (
      <div className="flex items-center justify-center p-8">
        <RefreshCw className="w-6 h-6 animate-spin text-gray-400" />
        <span className="ml-2 text-gray-400">Lade Config-Dateien...</span>
      </div>
    )
  }

  return (
    <div className="space-y-4">
      {/* File selector */}
      <div className="flex items-center gap-4">
        <div className="relative flex-1 max-w-md">
          <select
            value={selectedFile || ''}
            onChange={(e) => {
              if (hasChanges) {
                if (!confirm('Ungespeicherte Änderungen verwerfen?')) return
              }
              loadFile(e.target.value)
            }}
            className="w-full bg-gray-800 border border-gray-700 rounded-lg px-4 py-2 pr-10 text-white appearance-none cursor-pointer focus:outline-none focus:ring-2 focus:ring-blue-500"
          >
            {files.map(file => (
              <option key={file.filename} value={file.filename}>
                {file.filename}
              </option>
            ))}
          </select>
          <ChevronDown className="absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 pointer-events-none" />
        </div>

        <button
          onClick={() => loadFile(selectedFile)}
          disabled={loading}
          className="p-2 text-gray-400 hover:text-white hover:bg-gray-700 rounded-lg transition-colors"
          title="Neu laden"
        >
          <RefreshCw className={"w-5 h-5 " + (loading ? 'animate-spin' : '')} />
        </button>
      </div>

      {/* File description */}
      {selectedFile && (
        <div className="flex items-center gap-2 text-sm text-gray-400">
          <FileText className="w-4 h-4" />
          <span>{getFileDescription(selectedFile)}</span>
        </div>
      )}

      {/* Error/Success messages */}
      {error && (
        <div className="flex items-center gap-2 p-3 bg-red-500/10 border border-red-500/30 rounded-lg text-red-400">
          <AlertTriangle className="w-5 h-5 flex-shrink-0" />
          <span>{error}</span>
        </div>
      )}

      {success && (
        <div className="flex items-center gap-2 p-3 bg-green-500/10 border border-green-500/30 rounded-lg text-green-400">
          <Check className="w-5 h-5 flex-shrink-0" />
          <span>{success}</span>
        </div>
      )}

      {/* Editor with syntax highlighting */}
      <div className="relative h-[500px] rounded-lg overflow-hidden border border-gray-700">
        {/* Highlighted background layer */}
        <pre
          ref={highlightRef}
          className="absolute inset-0 p-4 m-0 text-sm font-mono bg-gray-900 text-gray-100 overflow-auto pointer-events-none whitespace-pre-wrap break-words"
          style={{ wordBreak: 'break-word' }}
          aria-hidden="true"
          dangerouslySetInnerHTML={{ __html: highlightSyntax(content) + '\n' }}
        />

        {/* Transparent textarea for editing */}
        <textarea
          ref={textareaRef}
          value={content}
          onChange={(e) => setContent(e.target.value)}
          onScroll={handleScroll}
          className="absolute inset-0 w-full h-full p-4 text-sm font-mono bg-transparent text-transparent caret-white resize-none focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-inset"
          spellCheck={false}
          disabled={loading}
          style={{ caretColor: 'white' }}
        />

        {/* Change indicator */}
        {hasChanges && (
          <div className="absolute top-2 right-2 px-2 py-1 bg-yellow-500/20 text-yellow-400 text-xs rounded z-10">
            Ungespeichert
          </div>
        )}
      </div>

      {/* Actions */}
      <div className="flex items-center justify-between">
        <div className="text-sm text-gray-500">
          {selectedFile && files.find(f => f.filename === selectedFile)?.modified && (
            <span>Zuletzt geändert: {files.find(f => f.filename === selectedFile).modified}</span>
          )}
        </div>

        <div className="flex items-center gap-3">
          {hasChanges && (
            <button
              onClick={handleDiscard}
              className="flex items-center gap-2 px-4 py-2 text-gray-400 hover:text-white hover:bg-gray-700 rounded-lg transition-colors"
            >
              <X className="w-4 h-4" />
              Verwerfen
            </button>
          )}

          <button
            onClick={handleSave}
            disabled={!hasChanges || saving}
            className={"flex items-center gap-2 px-4 py-2 rounded-lg transition-colors " +
              (hasChanges && !saving
                ? 'bg-green-600 hover:bg-green-500 text-white border-2 border-green-400'
                : 'bg-gray-700 text-gray-500 cursor-not-allowed border-2 border-gray-600'
              )}
          >
            {saving ? (
              <>
                <RefreshCw className="w-4 h-4 animate-spin" />
                Speichern...
              </>
            ) : (
              <>
                <Save className="w-4 h-4" />
                Speichern
              </>
            )}
          </button>
        </div>
      </div>

      {/* Legend */}
      <div className="mt-4 p-4 bg-gray-800/50 rounded-lg border border-gray-700">
        <h4 className="text-sm font-medium text-gray-300 mb-2">Legende</h4>
        <div className="flex flex-wrap gap-4 text-xs">
          <div className="flex items-center gap-2">
            <span className="w-3 h-3 rounded bg-purple-400"></span>
            <span className="text-gray-400">Sektion</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="w-3 h-3 rounded bg-blue-400"></span>
            <span className="text-gray-400">Einstellung</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="w-3 h-3 rounded bg-amber-300"></span>
            <span className="text-gray-400">Wert</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="w-3 h-3 rounded bg-orange-400"></span>
            <span className="text-gray-400">Boolean</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="w-3 h-3 rounded bg-cyan-400"></span>
            <span className="text-gray-400">Zahlen</span>
          </div>
        </div>
        <p className="text-xs text-gray-500 mt-3">Änderungen werden erst nach Server-Neustart aktiv. Ein Backup wird automatisch erstellt.</p>
      </div>
    </div>
  )
}
