// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only

import type { ReactNode, JSX } from 'react';
import { useState, useCallback } from 'react';

import type { LocalizerType } from '../types/Util.std.ts';
import type { ShowToastAction } from '../state/ducks/toast.preload.ts';
import { ContextMenu } from './ContextMenu.dom.tsx';
import { ToastType } from '../types/Toast.dom.tsx';
import {
  isVideoGoodForStories,
  ReasonVideoNotGood,
} from '../util/isVideoGoodForStories.std.ts';
import { AxoConfirmDialog } from '../axo/AxoConfirmDialog.dom.tsx';

export type PropsType = {
  children?: ReactNode;
  i18n: LocalizerType;
  maxAttachmentVideoSize: number;
  moduleClassName?: string;
  onAddStory: (file?: File) => unknown;
  onContextMenuShowingChanged?: (value: boolean) => void;
  showToast: ShowToastAction;
};

export function StoriesAddStoryButton({
  children,
  i18n,
  maxAttachmentVideoSize,
  moduleClassName,
  onAddStory,
  showToast,
  onContextMenuShowingChanged,
}: PropsType): JSX.Element {
  const [error, setError] = useState<string | undefined>();

  const onAddMedia = useCallback(() => {
    const input = document.createElement('input');
    input.accept = 'image/*,video/mp4';
    input.type = 'file';
    input.onchange = async () => {
      const file = input.files ? input.files[0] : undefined;

      if (!file) {
        return;
      }

      const result = await isVideoGoodForStories(file, {
        maxAttachmentVideoSize,
      });

      if (
        result.reason === ReasonVideoNotGood.UnsupportedCodec ||
        result.reason === ReasonVideoNotGood.UnsupportedContainer
      ) {
        showToast({ toastType: ToastType.StoryVideoUnsupported });
        return;
      }

      if (result.reason === ReasonVideoNotGood.TooLong) {
        setError(
          i18n('icu:StoryCreator__error--video-too-long', {
            maxDurationInSec: result.maxDurationInSec,
          })
        );
        return;
      }

      if (result.reason === ReasonVideoNotGood.TooBig) {
        setError(
          i18n('icu:StoryCreator__error--video-too-big', {
            limit: result.renderDetails.limit,
            units: result.renderDetails.units,
          })
        );
        return;
      }

      if (result.reason !== ReasonVideoNotGood.AllGoodNevermind) {
        showToast({ toastType: ToastType.StoryVideoError });
        return;
      }

      onAddStory(file);
    };
    input.click();
  }, [setError, showToast, i18n, maxAttachmentVideoSize, onAddStory]);

  return (
    <>
      <ContextMenu
        ariaLabel={i18n('icu:Stories__add')}
        i18n={i18n}
        onMenuShowingChanged={onContextMenuShowingChanged}
        menuOptions={[
          {
            label: i18n('icu:Stories__add-story--media'),
            onClick: onAddMedia,
          },
          {
            label: i18n('icu:Stories__add-story--text'),
            onClick: () => onAddStory(),
          },
        ]}
        moduleClassName={moduleClassName}
        popperOptions={{
          placement: 'bottom',
          strategy: 'absolute',
        }}
      >
        {children}
      </ContextMenu>
      <AxoConfirmDialog.Root
        open={error != null}
        onOpenChange={() => setError(undefined)}
        // @ts-expect-error ConfirmationDialog migration: Needs title
        title={null}
        // @ts-expect-error ConfirmationDialog migration: Needs description
        description={error}
      >
        <AxoConfirmDialog.Action
          variant="strong-primary"
          onClick={() => setError(undefined)}
        >
          {i18n('icu:Confirmation--confirm')}
        </AxoConfirmDialog.Action>
      </AxoConfirmDialog.Root>
    </>
  );
}
