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

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

import { logEvent } from 'src/config/logging';
import { useAuth } from 'src/contexts/JWTContext';
import useRequiredParams from 'src/hooks/useRequiredParams';
import { type Links } from 'src/types/actionLinks';
import { EventName } from 'src/types/amplitude';
import { CopyTypePath } from 'src/types/deeplinks';
import { type GroupPost } from 'src/types/groups';
import { type Poll, type Post } from 'src/types/posts';
import {
  canPerformAnyAction,
  EDIT_ACTIONS,
  hasActionLinks,
} from 'src/utils/actionsLinks';
import { canMarkAsKeyUpdate } from 'src/utils/feed';
import { getPollMenuFlags } from 'src/utils/poll';

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

import { GenericPostMenu } from '../../feed/components/GenericPostMenu';
import MarkPostAsKeyUpdateMenuItem from '../../feed/components/MarkPostAsKeyUpdateMenuItem';
import PollEditDeadlineMenuItem from '../../feed/components/PollEditDeadlineMenuItem';
import PollEndNowMenuItem from '../../feed/components/PollEndNowMenuItem';
import PostDelete from '../../feed/components/PostDelete';
import PostEdit from '../../feed/components/PostEdit';
import ReschedulePostMenuItem from '../../feed/components/ReschedulePostMenuItem';
import getScheduleDrawerConfig from '../../feed/components/schedule/components/ScheduleDrawerContent';
import { useScheduleDrawerState } from '../../feed/components/schedule/components/useScheduleDrawerState';
import { useGroupMember } from '../GroupMemberContext';
import useCanViewGroupsInsights from '../hooks/useCanViewGroupsInsights';
import { groupPostDeleted } from '../queries';
import { groupsRoutes } from '../routes';

import GroupInsightsMenuItem from './GroupInsightsMenuItem';
import GroupPinPostMenuItem from './GroupPinPostMenuItem';
import GroupPostCommentEnableOrDisable from './GroupPostCommentEnableOrDisable';

type GroupPostMenuProps = {
  id: number;
  user: Post['user'];
  isPinned?: boolean;
  isKeyUpdate?: boolean;
  isPendingApproval?: boolean;
  isSegmented?: boolean;
  isSchedulePost?: boolean;
  commentsEnabled?: boolean;
  poll?: Poll | null;
  actionLinks?: Links;
  isLive?: boolean;
  originalPost?: Post | GroupPost;
} & (
  | {
      isSchedulePost: true;
      publicationDatetime: string;
      reschedulePost: (
        publicationDateTime: string,
        sendNotification: boolean,
      ) => void;
    }
  | {
      isSchedulePost?: false;
      publicationDatetime?: never;
      reschedulePost?: never;
    }
);

const GroupPostMenu: FC<GroupPostMenuProps> = props => {
  const {
    id,
    user,
    isPinned = false,
    isKeyUpdate = false,
    isPendingApproval = false,
    isSegmented = false,
    isSchedulePost = false,
    commentsEnabled = false,
    publicationDatetime,
    reschedulePost,
    poll = null,
    actionLinks,
    isLive = false,
    originalPost,
  } = props;

  const { id: groupId } = useRequiredParams(['id']);
  const { isGroupAdmin, isGroupArchived, postsNeedApproval } = useGroupMember();
  const { user: loggedUser, permissions } = useAuth();
  const canViewInsights = useCanViewGroupsInsights(isGroupAdmin, user?.id);
  const canSharePost = useCanSharePost();

  const sameUser = loggedUser?.id === user.id;

  // Reschedule drawer state
  const scheduleDrawerState = useScheduleDrawerState({
    onSchedulePost: (date, sendNotification) => {
      reschedulePost?.(date, sendNotification);
    },
    canSendPush: isGroupAdmin,
    allowsOnlyChangingPush: true,
    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 hasBackendActions = hasActionLinks(actionLinks);
  const isEnabledByBackend = (...actions: string[]) =>
    !hasBackendActions || canPerformAnyAction(actionLinks ?? {}, actions);

  const showEditBase = !isGroupArchived;
  const canShowEditWithoutBackendActions =
    sameUser &&
    (!poll || poll.totalAnswerCount === 0) &&
    (isGroupAdmin || !postsNeedApproval);
  const showEdit =
    showEditBase &&
    (hasBackendActions
      ? isEnabledByBackend(...EDIT_ACTIONS)
      : canShowEditWithoutBackendActions);
  const showDeleteBase = !isGroupArchived;
  const showDelete = showDeleteBase && (isGroupAdmin || sameUser);
  const showMarkAsKeyUpdateBase =
    !isGroupArchived && !isSegmented && !isSchedulePost;
  const showMarkAsKeyUpdate =
    showMarkAsKeyUpdateBase && canMarkAsKeyUpdate(permissions);
  const showInsights = !!loggedUser && canViewInsights && !isSchedulePost;
  const showPinPostBase = !isGroupArchived && !isSchedulePost;
  const showPinPost = showPinPostBase && isGroupAdmin;
  const showReschedulePost =
    isSchedulePost && !!publicationDatetime && !!reschedulePost;
  const showEnableDisableCommentsBase = !isGroupArchived && !isSchedulePost;
  const showEnableDisableComments = showEnableDisableCommentsBase && sameUser;
  const showShare =
    !!originalPost && !isSchedulePost && !isPendingApproval && canSharePost;

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

  const onDelete = () => {
    groupPostDeleted(groupId);
    logEvent(EventName.GROUPS_POST_DELETED, {
      postId: id,
      isScheduled: false,
      groupId: Number(groupId),
    });
  };

  const menuOptions = [
    {
      id: 'copy-url',
      enabled: true,
      closeOnSelect: true,
      option: (
        <CopyUrlMenuItem
          type={CopyTypePath.POST}
          route={groupsRoutes.post.detail(groupId!, 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
          groupId={Number(groupId)}
        />
      ),
    },
    {
      id: 'reschedule-post',
      enabled: showReschedulePost,
      option: (
        <ReschedulePostMenuItem onOpenDrawer={() => showRescheduleDrawer({})} />
      ),
    },
    {
      id: 'poll-end-now',
      enabled: false,
      option: (
        <PollEndNowMenuItem
          postId={id}
          pollId={poll?.id!}
          isGroupPoll
          groupId={groupId}
        />
      ),
    },
    {
      id: 'poll-edit-deadline',
      enabled: canEditPollDeadline,
      option: (
        <PollEditDeadlineMenuItem
          postId={id}
          pollId={poll?.id!}
          endsAt={poll?.pollConfiguration?.endsAt}
          isGroupPoll
          groupId={groupId}
        />
      ),
    },
    {
      id: 'edit-post',
      enabled: showEdit,
      option: (
        <PostEdit
          id={id}
          disabled={hasPollThatIsVoted}
          editRoute={groupsRoutes.post.edit(groupId!, id)}
        />
      ),
    },
    {
      id: 'enable-disable-comments',
      enabled: showEnableDisableComments,
      closeOnSelect: true,
      option: (
        <GroupPostCommentEnableOrDisable
          id={id}
          commentsEnabled={commentsEnabled}
        />
      ),
    },
    {
      id: 'pin-post',
      enabled: showPinPost,
      closeOnSelect: true,
      option: (
        <GroupPinPostMenuItem
          id={id}
          isPinned={isPinned}
        />
      ),
    },
    {
      id: 'insights',
      enabled: showInsights,
      option: (
        <GroupInsightsMenuItem
          id={id}
          groupId={groupId!}
        />
      ),
    },
    {
      id: 'delete-post',
      enabled: showDelete,
      option: (
        <PostDelete
          id={id}
          onDelete={onDelete}
          groupId={Number(groupId)}
          isLive={isLive}
        />
      ),
    },
  ];

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

export default memo(GroupPostMenu);
