import { type FC, memo } from 'react';

import { useDrawerV2 } from '@material-hu/hooks/useDrawerV2';

import { useAuth } from 'src/contexts/JWTContext';
import InsightsMenuItem from 'src/pages/dashboard/feed/components/InsightsMenuItem';
import PostDelete from 'src/pages/dashboard/feed/components/PostDelete';
import PostEdit from 'src/pages/dashboard/feed/components/PostEdit';
import { feedRoutes } from 'src/pages/dashboard/feed/routes';
import { CopyTypePath } from 'src/types/deeplinks';
import { type GroupPost } from 'src/types/groups';
import { type Poll, type Post } from 'src/types/posts';
import { canDelete, canMarkAsKeyUpdate, canPinPost } from 'src/utils/feed';
import { getPollMenuFlags } from 'src/utils/poll';

import PostCommentEnableOrDisable from 'src/components/comments/PostCommentEnableOrDisable';
import CopyUrlMenuItem from 'src/components/deeplinks/CopyUrlMenuItem';
import {
  SharePostMenuItem,
  useCanSharePost,
} from 'src/components/post/SharePost';

import { groupsRoutes } from '../../groups/routes';
import useCanViewPostInsights from '../hooks/useCanViewPostInsights';
import { postDeleted } from '../queries';

import { GenericPostMenu } from './GenericPostMenu';
import MarkPostAsKeyUpdateMenuItem from './MarkPostAsKeyUpdateMenuItem';
import PinPostMenuItem from './PinPostMenuItem';
import PollEditDeadlineMenuItem from './PollEditDeadlineMenuItem';
import PollEndNowMenuItem from './PollEndNowMenuItem';
import PublishNowMenuItem from './PublishNowMenuItem';
import ReschedulePostMenuItem from './ReschedulePostMenuItem';
import getScheduleDrawerConfig from './schedule/components/ScheduleDrawerContent';
import { useScheduleDrawerState } from './schedule/components/useScheduleDrawerState';

export type PostMenuProps = {
  id: number;
  user: Post['user'];
  canEdit?: boolean;
  isGroupPost: {
    value: boolean;
    groupId: number;
  };
  commentsEnabled?: boolean;
  isKeyUpdate?: boolean;
  isPendingApproval?: boolean;
  isSegmented?: boolean;
  poll?: Poll | null;
  isLive?: boolean;
  originalPost?: Post | GroupPost;
} & (
  | {
      isSchedulePost: true;
      publicationDatetime: string;
      reschedulePost: (
        publicationDateTime: string,
        sendNotification: boolean,
      ) => void;
      handlePublishPostNow: () => void;
      canPostNow: boolean;
    }
  | {
      isSchedulePost?: false;
      publicationDatetime?: never;
      reschedulePost?: never;
      handlePublishPostNow?: never;
      canPostNow?: never;
    }
);

export const PostMenu: FC<PostMenuProps> = props => {
  const {
    id,
    user,
    canEdit = true,
    isGroupPost,
    commentsEnabled = false,
    isKeyUpdate = false,
    isPendingApproval = false,
    isSegmented = false,
    isSchedulePost = false,
    publicationDatetime,
    reschedulePost,
    handlePublishPostNow,
    canPostNow = false,
    poll = null,
    isLive = false,
    originalPost,
  } = props;

  const { user: loggedUser, permissions } = useAuth();
  const canViewInsights = useCanViewPostInsights(user.id);
  const canSharePost = useCanSharePost();

  // Reschedule drawer state
  const scheduleDrawerState = useScheduleDrawerState({
    onSchedulePost: (date, sendNotification) => {
      reschedulePost?.(date, sendNotification);
    },
    canSendPush: false, // Changing push notification is not supported for feed posts
    isReschedule: true,
    ...(publicationDatetime && {
      initialValues: {
        date: new Date(publicationDatetime).toISOString(),
        hours: new Date(publicationDatetime).getHours(),
        minutes: new Date(publicationDatetime).getMinutes(),
      },
    }),
  });

  const { showDrawer: showRescheduleDrawer, drawer: rescheduleDrawer } =
    useDrawerV2(({ closeDrawer }) =>
      getScheduleDrawerConfig(scheduleDrawerState, closeDrawer),
    );

  if (isPendingApproval) {
    return null;
  }

  const isGroupPostOnFeed = isGroupPost.value;

  const showPin =
    canPinPost(permissions) && !isGroupPostOnFeed && !isSchedulePost;
  const showEnableDisableComments =
    loggedUser?.id === user.id && !isGroupPostOnFeed && !isSchedulePost;
  const showEdit = canEdit && !isGroupPostOnFeed;
  const showInsights =
    !!loggedUser && canViewInsights && !isGroupPostOnFeed && !isSchedulePost;
  const showDelete =
    !!loggedUser &&
    canDelete(loggedUser.id, user.id, permissions) &&
    !isGroupPostOnFeed;
  const showMarkAsKeyUpdate =
    !isSegmented && canMarkAsKeyUpdate(permissions) && !isSchedulePost;
  const showReschedule =
    isSchedulePost && !!publicationDatetime && !!reschedulePost;
  const showPublishNow = isSchedulePost && canPostNow && !!handlePublishPostNow;
  const showShare =
    !!originalPost && !isSchedulePost && !isPendingApproval && canSharePost;

  const { hasPollThatIsVoted, canEditPollDeadline } = getPollMenuFlags(
    poll,
    loggedUser?.id,
    user.id,
  );

  const menuOptions = [
    {
      id: 'copy-url',
      enabled: true,
      closeOnSelect: true,
      option: (
        <CopyUrlMenuItem
          type={CopyTypePath.POST}
          route={
            isGroupPost.value
              ? groupsRoutes.post.detail(isGroupPost.groupId, id)
              : feedRoutes.post.detail(id)
          }
        />
      ),
    },
    {
      id: 'share-post',
      enabled: showShare && !!originalPost,
      closeOnSelect: true,
      option: originalPost ? <SharePostMenuItem post={originalPost} /> : null,
    },
    {
      id: 'mark-as-key-update',
      enabled: showMarkAsKeyUpdate,
      option: (
        <MarkPostAsKeyUpdateMenuItem
          id={id}
          isKeyUpdate={isKeyUpdate}
          isGroupPost={isGroupPost.value}
          groupId={isGroupPost.groupId}
        />
      ),
    },
    {
      id: 'reschedule-post',
      enabled: showReschedule,
      option: (
        <ReschedulePostMenuItem onOpenDrawer={() => showRescheduleDrawer({})} />
      ),
    },
    {
      id: 'publish-now',
      enabled: showPublishNow,
      option: (
        <PublishNowMenuItem handlePublishPostNow={handlePublishPostNow!} />
      ),
    },
    {
      id: 'poll-end-now',
      enabled: false,
      option: (
        <PollEndNowMenuItem
          postId={id}
          pollId={poll?.id!}
          isGroupPoll={isGroupPost.value}
          groupId={
            isGroupPost.value ? isGroupPost.groupId.toString() : undefined
          }
        />
      ),
    },
    {
      id: 'poll-edit-deadline',
      enabled: canEditPollDeadline,
      option: (
        <PollEditDeadlineMenuItem
          postId={id}
          pollId={poll?.id!}
          endsAt={poll?.pollConfiguration?.endsAt}
          isGroupPoll={isGroupPost.value}
          groupId={
            isGroupPost.value ? isGroupPost.groupId.toString() : undefined
          }
        />
      ),
    },
    {
      id: 'pin-post',
      enabled: showPin,
      closeOnSelect: true,
      option: <PinPostMenuItem id={id} />,
    },
    {
      id: 'enable-disable-comments',
      enabled: showEnableDisableComments,
      closeOnSelect: true,
      option: (
        <PostCommentEnableOrDisable
          id={id}
          commentsEnabled={commentsEnabled}
        />
      ),
    },
    {
      id: 'edit-post',
      enabled: showEdit,
      option: (
        <PostEdit
          id={id}
          disabled={hasPollThatIsVoted}
          editRoute={feedRoutes.post.edit(id)}
        />
      ),
    },
    {
      id: 'insights',
      enabled: showInsights,
      option: <InsightsMenuItem id={id} />,
    },
    {
      id: 'delete-post',
      enabled: showDelete,
      option: (
        <PostDelete
          id={id}
          onDelete={() => postDeleted()}
          isLive={isLive}
          {...(isGroupPost.value && { groupId: isGroupPost.groupId })}
        />
      ),
    },
  ];

  return (
    <>
      <GenericPostMenu
        id={id}
        menuOptions={menuOptions}
      />
      {rescheduleDrawer}
    </>
  );
};

export default memo(PostMenu);
