import clsx from 'clsx';
import { observer } from 'mobx-react-lite';
import { useCallback, useContext, useState } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import { ConditionalTooltip } from '@/app/(root)/create/createV2/ConditionalTooltip';
import {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import Button from '@/components/button/ReactAriaCompatButton';
import { ModalTypes } from '@/components/modal/constants/ModalTypes';
import { useModalContext } from '@/context/ModalContext';
import ContestClipContext from '@/hooks/useContestClip';
import { GlobeIcon, GlobeSlashIcon, SuccessIcon } from '@/icons';
import PublishSongEventType from '@/logging/eventTypes/PublishSongEventType';
import logWebUserEvent from '@/logging/logWebUserEvent';
import { Clip } from '@/state/clipStore';
import { isUnpublishableUploadClip } from '@/utils/clip';
import { UNPUBLISHABLE_UPLOAD_CLIP_MESSAGE } from '@/utils/constants';

export const PublishButton = observer(({ clip }: { clip: Clip }) => {
  const { library } = useStores();
  const { openModal, openModalWithData } = useModalContext();
  const { isContestSubmission, isContestEligible } =
    useContext(ContestClipContext);
  const [isHovered, setIsHovered] = useState(false);
  const isSubmission = isContestSubmission({ clip });
  const isEligibleForContest = isContestEligible({ clip });

  const handlePublish = () => {
    const eventProps: PublishSongEventType = isEligibleForContest
      ? {
          actionName: 'SubmitRemixButtonClicked',
          principalObjectType: 'song',
          principalObjectValue: clip.id,
        }
      : {
          actionName: 'PublishButtonPublishClicked',
          principalObjectType: 'song',
          principalObjectValue: clip.id,
        };

    logWebUserEvent(eventProps);
    library.setActiveClip(clip);
    openModal(ModalTypes.PUBLISH_SONG, 'PublishButton');
  };

  const handleUnpublish = () => {
    const eventProps: PublishSongEventType = isSubmission
      ? {
          actionName: 'SubmitRemixButtonUnpublishClicked',
          principalObjectType: 'song',
          principalObjectValue: clip.id,
          context: {
            contestId: clip.metadata.contest_ids?.[0] ?? null,
          },
        }
      : {
          actionName: 'PublishButtonUnpublishClicked',
          principalObjectType: 'song',
          principalObjectValue: clip.id,
        };
    logWebUserEvent(eventProps);
    openModalWithData(ModalTypes.UNPUBLISH_SONG, { clipId: clip.id });
  };

  const handleClick = () => {
    if (clip.is_public) {
      handleUnpublish();
    } else {
      handlePublish();
    }
  };

  const getButtonProps = useCallback(() => {
    if (clip.is_public && isHovered) {
      return {
        text: 'Unpublish',
        icon: GlobeSlashIcon,
        iconClassName: isSubmission ? 'text-tertiary' : 'text-accent-pink',
      };
    } else if (clip.is_public && isSubmission) {
      return {
        text: 'Submitted',
        icon: SuccessIcon,
        iconClassName: 'text-primary',
      };
    } else if (clip.is_public && !isSubmission) {
      return {
        text: 'Published',
        icon: GlobeIcon,
        iconClassName: 'text-accent-pink',
      };
    } else if (!clip.is_public && isEligibleForContest) {
      return {
        text: 'Submit Remix',
      };
    }
    return {
      text: 'Publish',
    };
  }, [clip.is_public, isHovered, isSubmission, isEligibleForContest]);

  const { icon, text, iconClassName } = getButtonProps();

  return (
    <Button
      size={ButtonSize.Mini}
      shape={ButtonShape.Rounded}
      variant={ButtonVariant.Standard}
      onClick={handleClick}
      icon={icon}
      disabled={isUnpublishableUploadClip(clip)}
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => setIsHovered(false)}
      iconClassName={iconClassName}
      className={clsx('whitespace-nowrap', {
        'px-[7.5px]': clip.is_public && isHovered,
        'px-2': clip.is_public && !isHovered,
      })}
    >
      <ConditionalTooltip
        label={UNPUBLISHABLE_UPLOAD_CLIP_MESSAGE}
        isTooltipEnabled={isUnpublishableUploadClip(clip)}
      >
        {text}
      </ConditionalTooltip>
    </Button>
  );
});
