import type { editor as monacoEditor } from 'monaco-editor';

export interface MkDocsSnippet {
  id: string;
  label: string;
  group: 'formatting' | 'heading' | 'admonition' | 'code' | 'insert';
  type: 'wrap' | 'block' | 'insert';
  prefix?: string;
  suffix?: string;
  template?: string;
  keybinding?: 'ctrl+b' | 'ctrl+i';
}

export const SNIPPETS: MkDocsSnippet[] = [
  // Formatting
  { id: 'bold', label: 'Bold', group: 'formatting', type: 'wrap', prefix: '**', suffix: '**', keybinding: 'ctrl+b' },
  { id: 'italic', label: 'Italic', group: 'formatting', type: 'wrap', prefix: '*', suffix: '*', keybinding: 'ctrl+i' },
  { id: 'strikethrough', label: 'Strikethrough', group: 'formatting', type: 'wrap', prefix: '~~', suffix: '~~' },
  { id: 'highlight', label: 'Highlight', group: 'formatting', type: 'wrap', prefix: '==', suffix: '==' },
  { id: 'inline-code', label: 'Inline Code', group: 'formatting', type: 'wrap', prefix: '`', suffix: '`' },
  { id: 'kbd', label: 'Keyboard Key', group: 'formatting', type: 'wrap', prefix: '++', suffix: '++' },
  // Headings
  { id: 'h1', label: 'Heading 1', group: 'heading', type: 'block', template: '# $CURSOR' },
  { id: 'h2', label: 'Heading 2', group: 'heading', type: 'block', template: '## $CURSOR' },
  { id: 'h3', label: 'Heading 3', group: 'heading', type: 'block', template: '### $CURSOR' },
  { id: 'h4', label: 'Heading 4', group: 'heading', type: 'block', template: '#### $CURSOR' },
  // Admonitions
  ...(['note', 'warning', 'tip', 'danger', 'info', 'success', 'question', 'abstract', 'example', 'bug', 'quote'] as const).map((t) => ({
    id: `admonition-${t}`,
    label: `${t.charAt(0).toUpperCase() + t.slice(1)}`,
    group: 'admonition' as const,
    type: 'block' as const,
    template: `!!! ${t} "Title"\n    Content here`,
  })),
  { id: 'admonition-collapsible-open', label: 'Collapsible (open)', group: 'admonition', type: 'block', template: '???+ note "Title"\n    Content here' },
  { id: 'admonition-collapsible-closed', label: 'Collapsible (closed)', group: 'admonition', type: 'block', template: '??? note "Title"\n    Content here' },
  // Code
  { id: 'code-block', label: 'Code Block', group: 'code', type: 'block', template: '```python\n$CURSOR\n```' },
  { id: 'code-annotated', label: 'Annotated Code', group: 'code', type: 'block', template: '```python\ncode  # (1)!\n```\n\n1. Annotation' },
  { id: 'mermaid', label: 'Mermaid Diagram', group: 'code', type: 'block', template: '```mermaid\ngraph LR\n    A --> B\n```' },
  // Inserts (standard markdown — no auth required)
  { id: 'link', label: 'Link', group: 'insert', type: 'wrap', prefix: '[', suffix: '](url)' },
  { id: 'image', label: 'Image', group: 'insert', type: 'insert', template: '![Alt text](image.png)' },
  { id: 'button', label: 'Button', group: 'insert', type: 'insert', template: '[Text](url){ .md-button }' },
  { id: 'button-primary', label: 'Primary Button', group: 'insert', type: 'insert', template: '[Text](url){ .md-button .md-button--primary }' },
  { id: 'icon', label: 'Material Icon', group: 'insert', type: 'insert', template: ':material-icon-name:' },
  { id: 'table', label: 'Table', group: 'insert', type: 'insert', template: '| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Cell 1   | Cell 2   | Cell 3   |\n| Cell 4   | Cell 5   | Cell 6   |' },
  { id: 'tasklist', label: 'Task List', group: 'insert', type: 'insert', template: '- [ ] Task 1\n- [ ] Task 2\n- [x] Done' },
  { id: 'tabs', label: 'Tabs', group: 'insert', type: 'insert', template: '=== "Tab 1"\n\n    Content\n\n=== "Tab 2"\n\n    Content' },
  { id: 'math-block', label: 'Math Block', group: 'insert', type: 'block', template: '$$\n$CURSOR\n$$' },
  { id: 'footnote', label: 'Footnote', group: 'insert', type: 'insert', template: '[^1]\n\n[^1]: Text' },
  { id: 'def-list', label: 'Definition List', group: 'insert', type: 'insert', template: 'Term\n:   Definition' },
  { id: 'hr', label: 'Horizontal Rule', group: 'insert', type: 'insert', template: '---' },
  // Platform-specific inserts (require auth — handled by DocsPage modals)
  { id: 'video-card', label: 'Video Card', group: 'insert', type: 'insert', template: '' },
  { id: 'photo-insert', label: 'Photo', group: 'insert', type: 'insert', template: '' },
  { id: 'donate-button', label: 'Donate Button', group: 'insert', type: 'insert', template: '' },
  { id: 'pricing-table', label: 'Pricing Table', group: 'insert', type: 'insert', template: '' },
  { id: 'product-card', label: 'Product Card', group: 'insert', type: 'insert', template: '' },
  { id: 'ad-insert', label: 'Ad', group: 'insert', type: 'insert', template: '' },
  { id: 'scheduling-poll', label: 'Scheduling Poll', group: 'insert', type: 'insert', template: '' },
  { id: 'wiki-link', label: 'Wiki Link [[]]', group: 'insert', type: 'insert', template: '' },
];

/** IDs of insert snippets that require authenticated API access (modal-based) */
export const PLATFORM_INSERT_IDS = new Set([
  'video-card', 'photo-insert', 'donate-button', 'pricing-table',
  'product-card', 'ad-insert', 'scheduling-poll', 'wiki-link',
]);

export function applySnippet(
  ed: monacoEditor.IStandaloneCodeEditor,
  snippet: MkDocsSnippet,
  monaco: typeof import('monaco-editor'),
) {
  const sel = ed.getSelection();
  const model = ed.getModel();
  if (!sel || !model) return;

  const selectedText = model.getValueInRange(sel);

  if (snippet.type === 'wrap' && snippet.prefix != null && snippet.suffix != null) {
    if (selectedText) {
      ed.executeEdits('mkdocs-snippet', [{
        range: sel,
        text: snippet.prefix + selectedText + snippet.suffix,
      }]);
    } else {
      const placeholder = 'text';
      ed.executeEdits('mkdocs-snippet', [{
        range: sel,
        text: snippet.prefix + placeholder + snippet.suffix,
      }]);
      const pos = sel.getStartPosition();
      const startCol = pos.column + snippet.prefix.length;
      ed.setSelection(new monaco.Selection(pos.lineNumber, startCol, pos.lineNumber, startCol + placeholder.length));
    }
  } else if (snippet.type === 'block' && snippet.template) {
    const pos = sel.getStartPosition();
    let text = snippet.template.replace('$CURSOR', selectedText);
    const lineContent = model.getLineContent(pos.lineNumber);
    if (pos.column > 1 && lineContent.substring(0, pos.column - 1).trim().length > 0) {
      text = '\n' + text;
    }
    ed.executeEdits('mkdocs-snippet', [{
      range: sel,
      text,
    }]);
  } else if (snippet.type === 'insert' && snippet.template) {
    ed.executeEdits('mkdocs-snippet', [{
      range: sel,
      text: snippet.template,
    }]);
  }

  ed.focus();
}
