import { useCallback, useEffect, useRef } from 'react';
import Editor, { type OnMount } from '@monaco-editor/react';
import type { editor as MonacoEditor } from 'monaco-editor';
import { toast } from 'sonner';
import { getLanguage } from '../../CodeEditor/language-map';
import { useFilesAPI } from '../../../hooks/useFilesAPI';

type EditorRendererProps = {
  content: string;
  fileName: string;
  filePath: string;
  root: string;
  onSave?: (content: string) => void;
};

export const EditorRenderer = ({ content, fileName, filePath, root, onSave }: EditorRendererProps) => {
  const editorRef = useRef<MonacoEditor.IStandaloneCodeEditor | null>(null);
  const { writeFile } = useFilesAPI(root);

  const handleSave = useCallback(async () => {
    const editor = editorRef.current;
    if (!editor) return;
    const newContent = editor.getValue();
    try {
      await writeFile(filePath, newContent);
      onSave?.(newContent);
      toast.success('File saved');
    } catch {
      toast.error('Failed to save file');
    }
  }, [filePath, writeFile, onSave]);

  const handleMount: OnMount = (editor, monaco) => {
    editorRef.current = editor;
    editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
      handleSave();
    });
    editor.focus();
  };

  useEffect(() => {
    const handler = (ev: KeyboardEvent) => {
      if ((ev.ctrlKey || ev.metaKey) && ev.key === 's') {
        ev.preventDefault();
      }
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, []);

  return (
    <Editor
      theme="vs-dark"
      language={getLanguage(fileName)}
      defaultValue={content}
      onMount={handleMount}
      options={{
        automaticLayout: true,
        minimap: { enabled: false },
        fontSize: 14,
        tabSize: 2,
        wordWrap: 'on',
        scrollBeyondLastLine: false,
        renderWhitespace: 'selection',
        smoothScrolling: true,
        cursorBlinking: 'smooth',
        cursorSmoothCaretAnimation: 'on',
        padding: { top: 8 },
      }}
    />
  );
};
