/**
 * Self-hosted Monaco Editor loader.
 *
 * `@monaco-editor/react` defaults to fetching Monaco from a CDN, which
 * is unusable in clawx's offline Electron environment.  We instead bundle
 * the editor + its language workers locally via Vite's `?worker` import
 * so each preview overlay can spin up Monaco without any network.
 *
 * Importing this module once is enough — `loader.config({ monaco })`
 * registers the bundled Monaco instance globally.
 */
import * as monaco from 'monaco-editor';
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
import { loader } from '@monaco-editor/react';

interface MonacoEnvironment {
  getWorker(workerId: string, label: string): Worker;
}

(self as unknown as { MonacoEnvironment: MonacoEnvironment }).MonacoEnvironment = {
  getWorker(_workerId: string, label: string): Worker {
    if (label === 'json') return new jsonWorker();
    if (label === 'typescript' || label === 'javascript') return new tsWorker();
    if (label === 'css' || label === 'scss' || label === 'less') return new cssWorker();
    if (label === 'html' || label === 'handlebars' || label === 'razor') return new htmlWorker();
    return new editorWorker();
  },
};

loader.config({ monaco });

export { monaco };
export { Editor, DiffEditor, loader } from '@monaco-editor/react';

const EXT_LANGUAGE_MAP: Record<string, string> = {
  '.ts': 'typescript',
  '.tsx': 'typescript',
  '.js': 'javascript',
  '.jsx': 'javascript',
  '.mjs': 'javascript',
  '.cjs': 'javascript',
  '.json': 'json',
  '.html': 'html',
  '.htm': 'html',
  '.css': 'css',
  '.scss': 'scss',
  '.less': 'less',
  '.md': 'markdown',
  '.markdown': 'markdown',
  '.yaml': 'yaml',
  '.yml': 'yaml',
  '.toml': 'plaintext',
  '.xml': 'xml',
  '.py': 'python',
  '.rb': 'ruby',
  '.go': 'go',
  '.rs': 'rust',
  '.java': 'java',
  '.kt': 'kotlin',
  '.swift': 'swift',
  '.sh': 'shell',
  '.bash': 'shell',
  '.zsh': 'shell',
  '.ps1': 'powershell',
  '.sql': 'sql',
  '.dart': 'dart',
  '.php': 'php',
  '.c': 'c',
  '.cc': 'cpp',
  '.cpp': 'cpp',
  '.h': 'cpp',
  '.hpp': 'cpp',
  '.cs': 'csharp',
  '.vue': 'html',
  '.dockerfile': 'dockerfile',
};

export function languageForExt(ext: string): string {
  if (!ext) return 'plaintext';
  const lower = ext.toLowerCase();
  return EXT_LANGUAGE_MAP[lower] ?? 'plaintext';
}

export function languageForPath(path: string): string {
  if (!path) return 'plaintext';
  const norm = path.replace(/\\/g, '/').toLowerCase();
  if (norm.endsWith('/dockerfile') || norm === 'dockerfile') return 'dockerfile';
  const dot = norm.lastIndexOf('.');
  if (dot < 0) return 'plaintext';
  return languageForExt(norm.slice(dot));
}