import { ViewNeuron } from '@ibiz-template/controller';
import {
  IDrawerOptions,
  IModal,
  IModalData,
  IModalOptions,
  IPopoverOptions,
  ViewMode,
} from '@ibiz-template/runtime';
import { CreateElement, VNode } from 'vue';

export function createOverlayView(
  close: (_res: IModalData) => void,
  props?: IParams | undefined,
): (_h: CreateElement) => VNode {
  return (h: CreateElement) =>
    h('ViewShell', {
      attrs: props,
      on: {
        neuronInit: (neuron: ViewNeuron) => {
          neuron.evt.on('closeView', (res: IModalData) => {
            close(res);
          });
        },
      },
    });
}

export async function openViewModal(
  props?: IParams | undefined,
  opts?: IModalOptions | undefined,
): Promise<IModalData> {
  const modal: IModal = { mode: ViewMode.MODAL };
  const overlay = ibiz.overlay.createModal(
    createOverlayView(res => overlay.dismiss(res), { ...props, modal }),
    undefined,
    opts,
  );
  overlay.present();
  const result: IModalData | undefined = await overlay.onWillDismiss();
  return result || { ok: false };
}

export async function openViewDrawer(
  props?: IParams | undefined,
  opts?: IDrawerOptions | undefined,
): Promise<IModalData> {
  const modal: IModal = { mode: ViewMode.DRAWER };
  const overlay = ibiz.overlay.createDrawer(
    createOverlayView(res => overlay.dismiss(res), { ...props, modal }),
    undefined,
    opts,
  );
  overlay.present();
  const result: IModalData | undefined = await overlay.onWillDismiss();
  return result || { ok: false };
}

export async function openViewPopover(
  event: MouseEvent,
  props?: IParams | undefined,
  opts?: IPopoverOptions | undefined,
): Promise<IModalData> {
  const modal: IModal = { mode: ViewMode.DRAWER };
  const overlay = ibiz.overlay.createPopover(
    createOverlayView(res => overlay.dismiss(res), { ...props, modal }),
    undefined,
    opts,
  );
  overlay.present(event.target as HTMLElement);
  const result: IModalData | undefined = await overlay.onWillDismiss();
  return result || { ok: false };
}

const PlacementMap: IData = {
  DRAWER_LEFT: 'left',
  DRAWER_RIGHT: 'right',
  DRAWER_TOP: 'top',
  DRAWER_BOTTOM: 'bottom',
};

export function getDrawerPlacement(
  openMode: string,
): IDrawerOptions['placement'] {
  return PlacementMap[openMode] || 'right';
}