import * as React from 'react';
import { getFormValues } from '@theoryofnekomata/formxtra';

export interface UseImageControlsOptions {
  actionFormKey?: string;
  forwardedRef?: React.Ref<HTMLImageElement>;
}

export const useImageControls = (options = {} as UseImageControlsOptions) => {
  const { actionFormKey = 'action' as const, forwardedRef } = options;
  const [fullScreen, setFullScreen] = React.useState(false);
  const defaultRef = React.useRef<HTMLImageElement>(null);
  const imageRef = forwardedRef ?? defaultRef;
  const filenameRef = React.useRef<HTMLElement>(null);

  React.useEffect(() => {
    if (fullScreen) {
      window.document.body.style.overflow = 'hidden';
    }

    if (!fullScreen) {
      window.document.body.style.overflow = '';
    }
  }, [fullScreen]);

  const toggleFullScreen = React.useCallback(() => {
    setFullScreen((b) => !b);
  }, []);

  const download = React.useCallback(() => {
    if (!(typeof imageRef === 'object' && imageRef?.current !== null)) {
      return;
    }

    if (!(typeof filenameRef === 'object' && filenameRef?.current !== null)) {
      return;
    }

    const downloadLink = window.document.createElement('a');
    downloadLink.download = filenameRef.current.textContent ?? 'image';
    downloadLink.href = imageRef.current.currentSrc;
    downloadLink.addEventListener('click', () => {
      downloadLink.remove();
    });
    downloadLink.click();
  }, [imageRef, filenameRef]);

  const actions = React.useMemo(() => ({
    toggleFullScreen,
    download,
  }), [toggleFullScreen, download]);

  const handleAction: React.FormEventHandler<HTMLFormElement> = React.useCallback((e) => {
    e.preventDefault();
    const nativeEvent = e.nativeEvent as unknown as { submitter: HTMLElement };
    const formData = getFormValues(
      e.currentTarget,
      {
        submitter: nativeEvent.submitter,
      }
    );
    const actionName = formData[actionFormKey] as keyof typeof actions;
    const { [actionName]: actionFunction } = actions;
    actionFunction?.();
  }, [actions, actionFormKey]);

  return React.useMemo(() => ({
    fullScreen,
    handleAction,
    imageRef,
    filenameRef,
  }), [fullScreen, handleAction, imageRef, filenameRef]);
};
