import React, { useContext } from 'react';
import { Button, ButtonProps } from '@digigov/react-core/Button';
import { Drawer, DrawerProps } from '@digigov/react-core/Drawer';
import {
  DrawerHeading,
  DrawerHeadingProps,
} from '@digigov/react-core/DrawerHeading';
import {
  DrawerId,
  UseDrawerReturn,
  useDrawer,
} from '@digigov/ui/navigation/Drawer/hooks';

export const DrawerContext = React.createContext<UseDrawerReturn | null>(null);
export interface DrawerHeadingAutoProps extends DrawerHeadingProps {
  drawer: DrawerId;
  open?: boolean;
  close?: boolean;
}

export interface DrawerOpenButtonProps extends ButtonProps {
  drawer: DrawerId;
  open?: boolean;
  close?: boolean;
}

export interface DrawerAutoProps extends DrawerProps {
  id: string;
  clickOutside?: boolean;
  closeOnEscape?: boolean;
}

export const DrawerProvider = ({ children }: { children: React.ReactNode }) => {
  const modal = useDrawer();
  return (
    <DrawerContext.Provider value={modal}>{children}</DrawerContext.Provider>
  );
};

export const useDrawerContext = (): UseDrawerReturn | null => {
  const context = useContext(DrawerContext);
  return context;
};

export const DrawerAuto = React.forwardRef<HTMLDivElement, DrawerAutoProps>(
  function DrawerAuto(
    { id, direction = 'left', upRelative = 'never', ...props },
    ref
  ) {
    const context = useDrawerContext();
    if (!context) {
      throw new Error('DrawerAuto must be used within an DrawerProvider');
    }
    const { registerDrawer } = context;
    return (
      <Drawer
        {...registerDrawer(id, { upRelative, direction })}
        {...props}
        ref={ref}
      >
        {props.children}
      </Drawer>
    );
  }
);

export const DrawerButtonAuto = React.forwardRef<
  HTMLButtonElement,
  DrawerOpenButtonProps
>(function DrawerButtonAuto({ drawer: forDrawer, open, ...props }, ref) {
  const context = useDrawerContext();
  if (!context) {
    throw new Error('DrawerButtonAuto must be used within an DrawerProvider');
  }
  const { registerAction } = context;
  return (
    <Button
      ref={ref}
      {...registerAction(forDrawer, open ? 'open' : 'close')}
      {...props}
    />
  );
});

export const DrawerHeadingAuto = React.forwardRef<
  HTMLDivElement,
  DrawerHeadingAutoProps
>(function DrawerHeadingAuto({ drawer: forDrawer, ...props }, ref) {
  const context = useDrawerContext();
  if (!context) {
    throw new Error('DrawerHeadingAuto must be used within an DrawerProvider');
  }
  const { registerAction } = context;
  return (
    <DrawerHeading
      color="secondary"
      ref={ref}
      {...registerAction(forDrawer, 'close')}
      {...props}
    />
  );
});
