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

import React, { useState } from 'react';
import type {
  ConversationType,
  ShowConversationType,
} from '../state/ducks/conversations';
import type {
  ConversationStoryType,
  MyStoryType,
  StoryViewType,
} from '../types/Stories';
import type { LocalizerType, ThemeType } from '../types/Util';
import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
import type { ShowToastAction } from '../state/ducks/toast';
import type {
  AddStoryData,
  ViewUserStoriesActionCreatorType,
  ViewStoryActionCreatorType,
} from '../state/ducks/stories';
import { MyStories } from './MyStories';
import { StoriesPane } from './StoriesPane';
import { NavSidebar, NavSidebarActionButton } from './NavSidebar';
import { StoriesAddStoryButton } from './StoriesAddStoryButton';
import { ContextMenu } from './ContextMenu';
import { I18n } from './I18n';
import type { WidthBreakpoint } from './_util';
import type { UnreadStats } from '../util/countUnreadStats';

export type PropsType = {
  addStoryData: AddStoryData;
  otherTabsUnreadStats: UnreadStats;
  deleteStoryForEveryone: (story: StoryViewType) => unknown;
  getPreferredBadge: PreferredBadgeSelectorType;
  hasFailedStorySends: boolean;
  hasPendingUpdate: boolean;
  hasViewReceiptSetting: boolean;
  hiddenStories: Array<ConversationStoryType>;
  i18n: LocalizerType;
  isStoriesSettingsVisible: boolean;
  isViewingStory: boolean;
  maxAttachmentSizeInKb: number;
  me: ConversationType;
  myStories: Array<MyStoryType>;
  navTabsCollapsed: boolean;
  onForwardStory: (storyId: string) => unknown;
  onSaveStory: (story: StoryViewType) => unknown;
  onToggleNavTabsCollapse: (navTabsCollapsed: boolean) => void;
  onMediaPlaybackStart: () => void;
  preferredLeftPaneWidth: number;
  preferredWidthFromStorage: number;
  queueStoryDownload: (storyId: string) => unknown;
  renderStoryCreator: () => JSX.Element;
  renderToastManager: (_: {
    containerWidthBreakpoint: WidthBreakpoint;
  }) => JSX.Element;
  retryMessageSend: (messageId: string) => unknown;
  savePreferredLeftPaneWidth: (preferredLeftPaneWidth: number) => void;
  setAddStoryData: (data: AddStoryData) => unknown;
  showConversation: ShowConversationType;
  showStoriesSettings: () => unknown;
  showToast: ShowToastAction;
  stories: Array<ConversationStoryType>;
  theme: ThemeType;
  toggleHideStories: (conversationId: string) => unknown;
  viewStory: ViewStoryActionCreatorType;
  viewUserStories: ViewUserStoriesActionCreatorType;
};

export function StoriesTab({
  addStoryData,
  otherTabsUnreadStats,
  deleteStoryForEveryone,
  getPreferredBadge,
  hasFailedStorySends,
  hasPendingUpdate,
  hasViewReceiptSetting,
  hiddenStories,
  i18n,
  maxAttachmentSizeInKb,
  me,
  myStories,
  navTabsCollapsed,
  onForwardStory,
  onSaveStory,
  onToggleNavTabsCollapse,
  onMediaPlaybackStart,
  preferredLeftPaneWidth,
  queueStoryDownload,
  renderStoryCreator,
  renderToastManager,
  retryMessageSend,
  savePreferredLeftPaneWidth,
  setAddStoryData,
  showConversation,
  showStoriesSettings,
  showToast,
  stories,
  theme,
  toggleHideStories,
  viewStory,
  viewUserStories,
}: PropsType): JSX.Element {
  const [isMyStories, setIsMyStories] = useState(false);

  function onAddStory(file?: File) {
    if (file) {
      setAddStoryData({ type: 'Media', file });
    } else {
      setAddStoryData({ type: 'Text' });
    }
  }

  return (
    <div className="Stories">
      {addStoryData && renderStoryCreator()}
      {isMyStories && myStories.length ? (
        <MyStories
          otherTabsUnreadStats={otherTabsUnreadStats}
          hasFailedStorySends={hasFailedStorySends}
          hasPendingUpdate={hasPendingUpdate}
          hasViewReceiptSetting={hasViewReceiptSetting}
          i18n={i18n}
          myStories={myStories}
          navTabsCollapsed={navTabsCollapsed}
          onBack={() => setIsMyStories(false)}
          onDelete={deleteStoryForEveryone}
          onForward={onForwardStory}
          onSave={onSaveStory}
          onMediaPlaybackStart={onMediaPlaybackStart}
          onToggleNavTabsCollapse={onToggleNavTabsCollapse}
          preferredLeftPaneWidth={preferredLeftPaneWidth}
          queueStoryDownload={queueStoryDownload}
          retryMessageSend={retryMessageSend}
          renderToastManager={renderToastManager}
          savePreferredLeftPaneWidth={savePreferredLeftPaneWidth}
          theme={theme}
          viewStory={viewStory}
        />
      ) : (
        <NavSidebar
          title={i18n('icu:Stories__title')}
          i18n={i18n}
          hasFailedStorySends={hasFailedStorySends}
          hasPendingUpdate={hasPendingUpdate}
          navTabsCollapsed={navTabsCollapsed}
          onToggleNavTabsCollapse={onToggleNavTabsCollapse}
          preferredLeftPaneWidth={preferredLeftPaneWidth}
          requiresFullWidth
          savePreferredLeftPaneWidth={savePreferredLeftPaneWidth}
          otherTabsUnreadStats={otherTabsUnreadStats}
          renderToastManager={renderToastManager}
          actions={
            <>
              <StoriesAddStoryButton
                i18n={i18n}
                maxAttachmentSizeInKb={maxAttachmentSizeInKb}
                moduleClassName="Stories__pane__add-story"
                onAddStory={onAddStory}
                showToast={showToast}
              />
              <ContextMenu
                i18n={i18n}
                menuOptions={[
                  {
                    label: i18n('icu:StoriesSettings__context-menu'),
                    onClick: showStoriesSettings,
                  },
                ]}
                moduleClassName="Stories__pane__settings"
                popperOptions={{
                  placement: 'bottom',
                  strategy: 'absolute',
                }}
                portalToRoot
              >
                {({ onClick, onKeyDown, ref }) => {
                  return (
                    <NavSidebarActionButton
                      ref={ref}
                      onClick={onClick}
                      onKeyDown={onKeyDown}
                      icon={<span className="StoriesTab__MoreActionsIcon" />}
                      label={i18n('icu:StoriesTab__MoreActionsLabel')}
                    />
                  );
                }}
              </ContextMenu>
            </>
          }
        >
          <StoriesPane
            getPreferredBadge={getPreferredBadge}
            hiddenStories={hiddenStories}
            i18n={i18n}
            maxAttachmentSizeInKb={maxAttachmentSizeInKb}
            me={me}
            myStories={myStories}
            onAddStory={onAddStory}
            onMyStoriesClicked={() => {
              if (myStories.length) {
                setIsMyStories(true);
              } else {
                setAddStoryData({ type: 'Text' });
              }
            }}
            onStoriesSettings={showStoriesSettings}
            onMediaPlaybackStart={onMediaPlaybackStart}
            queueStoryDownload={queueStoryDownload}
            showConversation={showConversation}
            showToast={showToast}
            stories={stories}
            theme={theme}
            toggleHideStories={toggleHideStories}
            viewUserStories={viewUserStories}
          />
        </NavSidebar>
      )}
      <div className="Stories__placeholder">
        <div className="Stories__placeholder__icon" />
        <div className="Stories__placeholder__text">
          {stories.length ? (
            i18n('icu:Stories__placeholder--text')
          ) : (
            <I18n
              i18n={i18n}
              id="icu:Stories__placeholder-with-icon--text-2"
              components={{
                // eslint-disable-next-line react/no-unstable-nested-components
                newStoryButtonIcon: () => {
                  return (
                    <span
                      className="Stories__placeholder__text__action"
                      aria-label={i18n('icu:Stories__add')}
                    />
                  );
                },
              }}
            />
          )}
        </div>
      </div>
    </div>
  );
}