import * as $ from 'jquery';
import * as _ from 'lodash';
import {IXosSidePanelService} from '../side-panel/side-panel.service';

export interface IXosKeyboardShortcutService {
  keyMapping: IXosKeyboardShortcutMap;
  registerKeyBinding(binding: IXosKeyboardShortcutBinding, target?: string);
  setup(): void;
}

export interface IXosKeyboardShortcutMap {
  global: IXosKeyboardShortcutBinding[];
  view: IXosKeyboardShortcutBinding[];
}

export interface IXosKeyboardShortcutBinding {
  key: string;
  cb: any;
  modifiers?: string[];
  label?: string;
  description?: string;
  onInput?: boolean;
}

export class XosKeyboardShortcut implements IXosKeyboardShortcutService {
  static $inject = ['$log', '$transitions', 'XosSidePanel'];
  public keyMapping: IXosKeyboardShortcutMap = {
    global: [],
    view: []
  };
  public allowedModifiers: string[] = ['meta', 'alt', 'shift', 'control'];
  public activeModifiers: string[] = [];

  private toggleKeyBindingPanel = (): void => {
    if (!this.isPanelOpen) {
      this.XosSidePanel.injectComponent('xosKeyBindingPanel');
      this.isPanelOpen = true;
    }
    else {
      this.XosSidePanel.removeInjectedComponents();
      this.isPanelOpen = false;
    }
  };

  /* tslint:disable */
  public baseBindings: IXosKeyboardShortcutBinding[] = [
    {
      key: 'slash',
      label: '/',
      description: 'Toggle Shortcut Panel',
      cb: this.toggleKeyBindingPanel,
    },
    {
      key: 'esc',
      label: 'Esc',
      cb: (event) => {
        // NOTE removing focus from input elements on Esc
        event.target.blur();
      },
      onInput: true
    }
  ];
  /* tslint:enable */

  private isPanelOpen: boolean;

  constructor(
    private $log: ng.ILogService,
    $transitions: any,
    private XosSidePanel: IXosSidePanelService
  ) {
    this.keyMapping.global = this.keyMapping.global.concat(this.baseBindings);

    $transitions.onStart({ to: '**' }, (transtion) => {
      // delete view keys before that a new view is loaded
        this.$log.debug(`[XosKeyboardShortcut] Deleting view keys`);
        this.keyMapping.view = [];
    });
  }


  public setup(): void {
    this.$log.info(`[XosKeyboardShortcut] Setup`);
    $('body').on('keydown', (e) => {

      const pressedKey = this.whatKey(e.which);

      if (this.allowedModifiers.indexOf(e.key) > -1) {
        this.addActiveModifierKey(e.key);
        return;
      }

      // NOTE e.key change if we are using some modifiers (eg: Alt) while getting the value from the keyCode works
      const binding = this.findBindedShortcut(pressedKey);
      if (angular.isDefined(binding) && angular.isFunction(binding.cb)) {
        // NOTE disable binding if they come from an input or textarea
        // if not different specified
        const t = e.target.tagName.toLowerCase();
        if ((t === 'input' || t === 'textarea') && !binding.onInput) {
          return;
        }
        binding.cb(e);
        e.preventDefault();
      }
    });

    $('body').on('keyup', (e) => {
      if (this.allowedModifiers.indexOf(e.key) > -1) {
        this.removeActiveModifierKey(e.key);
        return;
      }
    });
  }

  public registerKeyBinding(binding: IXosKeyboardShortcutBinding, target: string = 'view'): void {

    if (target !== 'global' && target !== 'view') {
      throw new Error('[XosKeyboardShortcut] A shortcut can be registered with scope "global" or "view" only');
    }

    binding.key = binding.key.toLowerCase();
    if (_.find(this.keyMapping.global, {key: binding.key}) || _.find(this.keyMapping.view, {key: binding.key})) {
      this.$log.warn(`[XosKeyboardShortcut] A shortcut for key "${binding.key}" has already been registered`);
      return;
    }

    this.$log.debug(`[XosKeyboardShortcut] Registering binding for key: ${binding.key}`);
    this.keyMapping[target].push(binding);
  }

  private addActiveModifierKey(key: string) {
    if (this.activeModifiers.indexOf(key) === -1) {
      this.activeModifiers.push(key);
    }
  }

  private removeActiveModifierKey(key: string) {
    _.remove(this.activeModifiers, k => k === key);
  }

  private findBindedShortcut(key: string): IXosKeyboardShortcutBinding {
    const globalTargets =  _.filter(this.keyMapping.global, {key: key.toLowerCase()});

    const localTargets = _.filter(this.keyMapping.view, {key: key.toLowerCase()});

    let targets = globalTargets.concat(localTargets);

    if (targets.length === 0) {
      return;
    }

    // NOTE remove targets that does not match modifiers
    targets = _.filter(targets, (t: IXosKeyboardShortcutBinding) => {
      if (this.activeModifiers.length === 0) {
        return true;
      }
      else if (t.modifiers && _.difference(t.modifiers, this.activeModifiers).length === 0) {
        return true;
      }
      return false;
    });

    return targets[0];
  }

  private whatKey(code: number) {
    switch (code) {
      case 8: return 'delete';
      case 9: return 'tab';
      case 13: return 'enter';
      case 16: return 'shift';
      case 17: return 'control';
      case 18: return 'alt';
      case 27: return 'esc';
      case 32: return 'space';
      case 37: return 'leftArrow';
      case 38: return 'upArrow';
      case 39: return 'rightArrow';
      case 40: return 'downArrow';
      case 91: return 'meta';
      case 186: return 'semicolon';
      case 187: return 'equals';
      case 188: return 'comma';
      case 189: return 'dash';
      case 190: return 'dot';
      case 191: return 'slash';
      case 192: return 'backQuote';
      case 219: return 'openBracket';
      case 220: return 'backSlash';
      case 221: return 'closeBracket';
      case 222: return 'quote';
      default:
        if ((code >= 48 && code <= 57) ||
          (code >= 65 && code <= 90)) {
          return String.fromCharCode(code);
        } else if (code >= 112 && code <= 123) {
          return 'F' + (code - 111);
        }
        return null;
  }
}

}
