import { useRef, useState } from 'react';
import CodeMirror, { EditorView } from '@uiw/react-codemirror';
import { json } from '@codemirror/lang-json';
import { xml } from '@codemirror/lang-xml';
import { oneDark } from '@codemirror/theme-one-dark';
import { Eye, Pencil, Save } from 'lucide-react';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';

export type CodeMode = 'text' | 'json' | 'xml';

interface CodeEditorProps {
  text: string;
  mode: CodeMode;
  readOnly?: boolean;
  onSave?: (text: string) => Promise<void>;
}

const cmTheme = EditorView.theme({
  '&': { height: '100%', background: '#0a0a0a' },
  '.cm-scroller': { overflow: 'auto', fontFamily: 'ui-monospace,monospace', fontSize: '12px', lineHeight: '1.5' },
  '.cm-content': { padding: '12px 0' },
  '.cm-focused': { outline: 'none' },
});

const langExt: Record<CodeMode, any> = {
  json: json(),
  xml:  xml(),
  text: [],
};

const syntaxLang: Record<CodeMode, string> = {
  text: 'text', json: 'json', xml: 'xml',
};

function prettify(text: string, mode: CodeMode): string {
  if (mode === 'json') {
    try { return JSON.stringify(JSON.parse(text), null, 2); } catch { /* fall through */ }
  }
  return text;
}

export default function CodeEditor({ text, mode, readOnly = false, onSave }: CodeEditorProps) {
  const [editMode, setEditMode] = useState(false);
  const [saving, setSaving]     = useState(false);
  const editorViewRef = useRef<EditorView | null>(null);

  const displayText = prettify(text, mode);
  const extensions  = [langExt[mode], cmTheme].flat();

  const handleSave = async () => {
    if (!editorViewRef.current || !onSave) return;
    setSaving(true);
    try { await onSave(editorViewRef.current.state.doc.toString()); }
    finally { setSaving(false); }
  };

  if (!editMode) {
    return (
      <div className="flex flex-col h-full">
        {!readOnly && (
          <div className="flex items-center gap-2 px-3 py-1.5 bg-neutral-900 border-b border-neutral-700 flex-shrink-0 text-xs">
            <button
              onClick={() => setEditMode(true)}
              className="px-2 py-1 rounded bg-neutral-700 text-neutral-300 hover:bg-neutral-600 inline-flex items-center gap-1"
            >
              <Pencil className="w-3.5 h-3.5" /> Edit
            </button>
          </div>
        )}
        <div className="flex-1 overflow-auto text-xs">
          <SyntaxHighlighter
            language={syntaxLang[mode]}
            style={vscDarkPlus}
            customStyle={{ margin: 0, minHeight: '100%', background: '#0a0a0a', fontSize: '12px', lineHeight: '1.5' }}
            showLineNumbers
            wrapLongLines
          >
            {displayText}
          </SyntaxHighlighter>
        </div>
      </div>
    );
  }

  return (
    <div className="flex flex-col h-full">
      <div className="flex items-center gap-2 px-3 py-1.5 bg-neutral-900 border-b border-neutral-700 flex-shrink-0 text-xs">
        <button
          onClick={() => setEditMode(false)}
          className="px-2 py-1 rounded bg-amber-600 text-white inline-flex items-center gap-1"
        >
          <Eye className="w-3.5 h-3.5" /> View
        </button>
        {onSave && (
          <button
            onClick={() => void handleSave()}
            disabled={saving}
            className="px-2 py-1 rounded bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50 inline-flex items-center gap-1"
          >
            <Save className="w-3.5 h-3.5" /> {saving ? 'Saving…' : 'Save'}
          </button>
        )}
        <span className="text-neutral-600 ml-auto">Ctrl+Z/Y undo · Ctrl+F search</span>
      </div>
      <div className="flex-1 overflow-hidden">
        <CodeMirror
          defaultValue={displayText}
          extensions={extensions}
          theme={oneDark}
          height="100%"
          onCreateEditor={view => { editorViewRef.current = view; }}
        />
      </div>
    </div>
  );
}
