import type React from 'react';

function isInteractiveTarget(target: EventTarget | null) {
  return target instanceof HTMLElement
    ? Boolean(target.closest('button, a, input, textarea, select, [role="button"], [contenteditable="true"]'))
    : false;
}

export function renderModalWithEnterConfirm(node: React.ReactNode) {
  return (
    <div
      onKeyDown={(event) => {
        const target = event.target;
        const shouldIgnoreInteractiveTarget =
          target instanceof HTMLElement &&
          event.currentTarget.contains(target) &&
          isInteractiveTarget(target);

        if (event.nativeEvent.isComposing) {
          return;
        }

        if (event.key === 'Escape') {
          const cancelButton =
            event.currentTarget.querySelector<HTMLButtonElement>('.ant-modal-footer .ant-btn:not(.ant-btn-primary)') ??
            event.currentTarget.querySelector<HTMLButtonElement>('.ant-modal-close');

          if (!cancelButton || cancelButton.disabled) {
            return;
          }

          event.preventDefault();
          event.stopPropagation();
          cancelButton.click();
          return;
        }

        if (event.key !== 'Enter' || shouldIgnoreInteractiveTarget) {
          return;
        }

        const okButton = event.currentTarget.querySelector<HTMLButtonElement>('.ant-modal-footer .ant-btn-primary');

        if (!okButton || okButton.disabled) {
          return;
        }

        event.preventDefault();
        event.stopPropagation();
        okButton.click();
      }}
    >
      {node}
    </div>
  );
}

type ModalConfirmApi = {
  confirm: (config: Record<string, unknown>) => void;
};

type ConfirmWithKeyboardOptions = {
  onOk?: (...args: unknown[]) => unknown;
  onCancel?: (...args: unknown[]) => unknown;
} & Record<string, unknown>;

export async function confirmWithKeyboard(modalApi: ModalConfirmApi, config: ConfirmWithKeyboardOptions) {
  const { onOk, onCancel, getContainer, ...restConfig } = config;

  return await new Promise<boolean>((resolve) => {
    let settled = false;

    const finish = (value: boolean) => {
      if (settled) {
        return;
      }

      settled = true;
      resolve(value);
    };

    modalApi.confirm({
      ...restConfig,
      getContainer: getContainer ?? (() => document.body),
      modalRender: renderModalWithEnterConfirm,
      async onOk(...args: unknown[]) {
        await onOk?.(...args);
        finish(true);
      },
      onCancel(...args: unknown[]) {
        onCancel?.(...args);
        finish(false);
      },
    });
  });
}
