import {
  KeyBinding,
  highlightActiveLineGutter,
  highlightSpecialChars,
  drawSelection,
  dropCursor,
  rectangularSelection,
  crosshairCursor,
  highlightActiveLine,
  keymap,
} from '@codemirror/view';
import { EditorState, Extension } from '@codemirror/state';
import { history, defaultKeymap, historyKeymap } from '@codemirror/commands';
import { highlightSelectionMatches, searchKeymap } from '@codemirror/search';
import {
  closeBrackets,
  autocompletion,
  closeBracketsKeymap,
  completionKeymap,
} from '@codemirror/autocomplete';
import {
  foldGutter,
  indentOnInput,
  bracketMatching,
  indentUnit,
  foldKeymap,
} from '@codemirror/language';

import { lintKeymap } from '@codemirror/lint';

export interface MinimalSetupOptions {
  highlightSpecialChars?: boolean;
  history?: boolean;
  drawSelection?: boolean;
  syntaxHighlighting?: boolean;
  defaultKeymap?: boolean;
  historyKeymap?: boolean;
}
export interface BasicSetupOptions extends MinimalSetupOptions {
  lineNumbers?: boolean;
  highlightActiveLineGutter?: boolean;
  foldGutter?: boolean;
  dropCursor?: boolean;
  allowMultipleSelections?: boolean;
  indentOnInput?: boolean;
  bracketMatching?: boolean;
  closeBrackets?: boolean;
  autocompletion?: boolean;
  rectangularSelection?: boolean;
  crosshairCursor?: boolean;
  highlightActiveLine?: boolean;
  highlightSelectionMatches?: boolean;
  closeBracketsKeymap?: boolean;
  searchKeymap?: boolean;
  foldKeymap?: boolean;
  completionKeymap?: boolean;
  lintKeymap?: boolean;
  tabSize?: number;
  readonly?: boolean;
  enableSearch?: boolean;
}

export const isValidSetup = (item: any) => {
  return typeof item === 'undefined' || item;
};

export const basicSetup = (options: BasicSetupOptions = {}): Extension[] => {
  const { crosshairCursor: initCrosshairCursor = false } = options;
  let keymaps: KeyBinding[] = [];
  isValidSetup(options.defaultKeymap) && keymaps.push(...defaultKeymap);
  isValidSetup(options.closeBracketsKeymap) && keymaps.push(...closeBracketsKeymap);
  isValidSetup(options.searchKeymap) && keymaps.push(...searchKeymap);
  isValidSetup(options.historyKeymap) && keymaps.push(...historyKeymap);
  isValidSetup(options.foldKeymap) && keymaps.push(...foldKeymap);
  isValidSetup(options.lintKeymap) && keymaps.push(...lintKeymap);
  const extensions: Extension[] = [];
  isValidSetup(options.highlightActiveLineGutter) && extensions.push(highlightActiveLineGutter());
  isValidSetup(options.highlightSpecialChars) && extensions.push(highlightSpecialChars());
  isValidSetup(options.history) && extensions.push(history());
  isValidSetup(options.foldGutter) && extensions.push(foldGutter());
  isValidSetup(options.drawSelection) && extensions.push(drawSelection());
  isValidSetup(options.dropCursor) && extensions.push(dropCursor());
  isValidSetup(options.allowMultipleSelections) && extensions.push(EditorState.allowMultipleSelections.of(true));
  isValidSetup(options.indentOnInput) && extensions.push(indentOnInput());
  isValidSetup(options.bracketMatching) && extensions.push(bracketMatching());
  isValidSetup(options.closeBrackets) && extensions.push(closeBrackets());
  isValidSetup(options.autocompletion) && extensions.push(autocompletion());
  isValidSetup(options.rectangularSelection) && extensions.push(rectangularSelection());
  isValidSetup(options.crosshairCursor) && extensions.push(crosshairCursor());
  isValidSetup(options.highlightActiveLine) && extensions.push(highlightActiveLine());
  isValidSetup(options.highlightSelectionMatches) && extensions.push(highlightSelectionMatches());

  if(!options.enableSearch){
  extensions.push(
    keymap.of([{
      key: "Mod-f", // Ctrl+F (Cmd+F on Mac)
      run: () => {
        return true;
      }
    }]))
  }

  if (options.tabSize && typeof options.tabSize === 'number')
    extensions.push(indentUnit.of(' '.repeat(options.tabSize)));
  return extensions.concat([keymap.of(keymaps.flat())]).filter(Boolean);
};


