import React, { useContext } from 'react';
import { Button, ButtonProps } from '@digigov/react-core/Button';
import { ModalContainerProps } from '@digigov/react-core/ModalContainer';
import Modal from '@digigov/ui/app/Modal';
import { ModalId, UseModalReturn, useModal } from '@digigov/ui/app/Modal/hooks';

export const ModalContext = React.createContext<UseModalReturn | null>(null);

export interface ModalAutoProps extends ModalContainerProps {
  id: string;
  clickOutside?: boolean;
  closeOnEscape?: boolean;
}

export const ModalProvider = ({ children }: { children: React.ReactNode }) => {
  const modal = useModal();
  return (
    <ModalContext.Provider value={modal}>{children}</ModalContext.Provider>
  );
};

export const useModalContext = (): UseModalReturn | null => {
  const context = useContext(ModalContext);
  if (context === null) {
    throw new Error('useModalContext must be used within an ModalProvider');
  }
  return context;
};

export const ModalAuto = React.forwardRef<HTMLDivElement, ModalAutoProps>(
  function ModalAuto(
    { id, clickOutside = false, closeOnEscape = false, ...props },
    ref
  ) {
    const context = useModalContext();
    if (!context) {
      throw new Error('ModalAuto must be used within an ModalProvider');
    }
    const { registerModal } = context;
    return (
      <Modal
        {...registerModal(id, { clickOutside, closeOnEscape })}
        {...props}
        ref={ref}
      >
        {props.children}
      </Modal>
    );
  }
);

export interface ModalButtonAutoProps extends ButtonProps {
  modal: ModalId;
  open?: boolean;
  close?: boolean;
}

export const ModalButtonAuto = React.forwardRef<
  HTMLButtonElement,
  ModalButtonAutoProps
>(function ModalButtonAuto(
  { modal: forModal, open, variant = 'button', color = 'primary', ...props },
  ref
) {
  const context = useModalContext();
  if (!context) {
    throw new Error('ModalButtonAuto must be used within an ModalProvider');
  }
  const { registerAction } = context;
  return (
    <Button
      ref={ref}
      {...registerAction(forModal, open ? 'open' : 'close', { variant, color })}
      {...props}
    />
  );
});
