import * as AlloyEvents from '../../api/events/AlloyEvents';
import * as NativeEvents from '../../api/events/NativeEvents';
import * as SystemEvents from '../../api/events/SystemEvents';
import type { DomDefinitionDetail } from '../../dom/DomDefinition';
import * as DomModification from '../../dom/DomModification';

import * as FocusApis from './FocusApis';
import type { FocusingConfig } from './FocusingTypes';

// TODO: DomModification types
const exhibit = (base: DomDefinitionDetail, focusConfig: FocusingConfig): any => {
  const mod = focusConfig.ignore ? { } : {
    attributes: {
      tabindex: '-1'
    }
  };

  return DomModification.nu(mod);
};

const events = (focusConfig: FocusingConfig): AlloyEvents.AlloyEventRecord => AlloyEvents.derive([
  AlloyEvents.run(SystemEvents.focus(), (component, simulatedEvent) => {
    FocusApis.focus(component, focusConfig);
    simulatedEvent.stop();
  })
].concat(focusConfig.stopMousedown ? [
  AlloyEvents.run(NativeEvents.mousedown(), (_, simulatedEvent) => {
    // This setting is often used in tandem with ignoreFocus. Basically, if you
    // don't prevent default on a menu that has fake focus, then it can transfer
    // focus to the outer body when they click on it, which can break things
    // which dismiss on blur (e.g. typeahead)
    simulatedEvent.event.prevent();
  })
] : [ ]));

export {
  exhibit,
  events
};
