'use client';

import { Tooltip } from '@chakra-ui/react';
import { useAuth, useClerk } from '@clerk/nextjs';
import clsx from 'clsx';
import { observer } from 'mobx-react-lite';
import { usePathname, useRouter } from 'next/navigation';
import React, { useEffect, useRef, useState } from 'react';
import { twMerge } from 'tailwind-merge';

import { useStores } from '@/app/(root)/AppProviders';
import {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import { ClipLikeButton } from '@/components/button/ClipLikeButton';
import Button from '@/components/button/ReactAriaCompatButton';
import { GetFullSongButton } from '@/components/song/GetFullSongButton';
import { PublishButton } from '@/components/song/PublishButton';
import RemixOptions from '@/components/song/RemixOptions';
import { SongMenuWithContextForMultiselect } from '@/components/song/newActions/SongMenuWithContextForMultiselect';
import { useBreakpointLg } from '@/hooks/useBreakpoint';
import {
  BookmarkIcon,
  CommentIcon,
  PlayIcon,
  ShareArrowIcon,
  ThumbsDownIcon,
} from '@/icons';
import logWebUserEvent from '@/logging/logWebUserEvent';
import { Clip, isDisliked, isLiked } from '@/state/clipStore';
import { PlanFeature } from '@/state/sessionStore';
import { getExtendTask, shouldShowGetFullSong } from '@/utils/clip';
import { TOOLTIP_BACKGROUND } from '@/utils/constants';
import { eventLogger } from '@/utils/event-logger';
import { ActionName, ComponentContext } from '@/utils/event-names';
import { shouldShowRemixButton } from '@/utils/remixUtils';
import {
  isFeatureEnabledForPlan,
  isProjectsFeatureEnabled,
} from '@/utils/session';
import {
  getClerkSignInRedirectProps,
  getCountString,
  isSecretStatsProfile,
} from '@/utils/utils';

import { shareClip } from '../../utils/download';
import { showCoverInSongRow, showExtentedInSongRow } from './songUtils';

interface SongActionsProps {
  clip: Clip;
  className?: string;
  rowKey?: string;
  showStats?: boolean;
  trendingMode?: boolean;
  asCardActions?: boolean;
  isFromSongRow?: boolean;
  isSongPage?: boolean;
  isPlaybar?: boolean;
  dropdownOnly?: boolean;
  buttonVariant?: ButtonVariant;
  buttonShape?: ButtonShape;
  buttonSize?: ButtonSize;
  buttonAspectSquare?: boolean;
  buttonIconClassName?: string;
  hideCreationActions?: boolean;
  hideEditActions?: boolean;
  isContestClip?: boolean;
  showDislike?: boolean;
  mini?: boolean;
  enablePin?: boolean;
  sectionName?: string;
  onTriggerEditMode?: () => void;
  onPinClipToProject?: () => void;
  onPlayCountClick: (
    e: React.MouseEvent<HTMLButtonElement, MouseEvent>
  ) => void;
}

const SongActions = observer(
  ({
    clip,
    className,
    rowKey,
    showStats = false,
    asCardActions = false,
    trendingMode = false,
    isFromSongRow = false,
    isPlaybar = false,
    dropdownOnly = false,
    isContestClip = false,
    mini = false,
    enablePin = false,
    showDislike: explicitShowDislike,
    sectionName,
    buttonVariant = ButtonVariant.Tertiary,
    buttonShape = ButtonShape.Rounded,
    buttonSize = ButtonSize.Mini,
    buttonAspectSquare,
    buttonIconClassName,
    onTriggerEditMode,
    onPinClipToProject,
    onPlayCountClick,
  }: SongActionsProps) => {
    const {
      playbar: playbarState,
      clips,
      genForm,
      session,
      project,
    } = useStores();

    const isDesktop = useBreakpointLg();
    const isMobile = !isDesktop;
    const router = useRouter();
    const pathname = usePathname();
    const isComplete = clip?.status === 'complete';
    const isLikedPlaylist = pathname === '/playlist/liked/';
    const isSharelist = pathname === '/playlist/sharelist/';
    const isVirtualPlaylist = isLikedPlaylist || isSharelist;

    const { isSignedIn } = useAuth();
    const clerk = useClerk();

    const [likeStatus, setLikeStatus] = useState(isLiked(clip));
    const [dislikeStatus, setDislikeStatus] = useState(isDisliked(clip));

    const [shouldPulse, setShouldPulse] = useState(false);
    const pulseTimerRef = useRef<NodeJS.Timeout | null>(null);
    const shareButtonRef = useRef<any>(null);
    const likeButtonRef = useRef<any>(null);

    useEffect(() => {
      setLikeStatus(isLiked(clips.clipById[clip.id]));
      setDislikeStatus(isDisliked(clips.clipById[clip.id]));
    }, [clips.clipById[clip.id]?.reaction?.reaction_type]);

    const handleLikeClick = ({ isLiked }: { isLiked: boolean }) => {
      session.clearTooltipOnLike();
      logWebUserEvent({
        actionName: 'SongActionLikeClicked',
        principalObjectValue: clip?.id,
        principalObjectType: 'song',
        context: {
          likeStatus: isLiked,
        },
      });
    };

    const handleDislikeClick = () => {
      if (!isSignedIn) {
        clerk.openSignIn({
          withSignUp: true,
          ...getClerkSignInRedirectProps(pathname),
        });
      } else {
        const newStatus = !isDisliked(clips.clipById[clip.id]);
        setDislikeStatus(newStatus);
        clips.dislikeClip(clip.id, newStatus);
        logWebUserEvent({
          actionName: 'SongActionDislikeClicked',
          principalObjectValue: clip?.id,
          principalObjectType: 'song',
          context: {
            dislikeStatus: newStatus,
          },
        });
      }
    };

    const isLastCharNumber = (userId: string): boolean => {
      const lastChar = userId.charAt(userId.length - 1);
      return !isNaN(parseInt(lastChar, 10));
    };

    useEffect(() => {
      if (session.flags?.['thumbs-exp']) {
        if (
          playbarState.clip?.id === clip.id &&
          playbarState.isPlaying &&
          !likeStatus &&
          !dislikeStatus
        ) {
          setShouldPulse(true);
          if (pulseTimerRef.current) {
            clearTimeout(pulseTimerRef.current);
          }
          pulseTimerRef.current = setTimeout(() => {
            setShouldPulse(false);
          }, 10000);
        } else {
          setShouldPulse(false);
          if (pulseTimerRef.current) {
            clearTimeout(pulseTimerRef.current);
          }
        }

        return () => {
          if (pulseTimerRef.current) {
            clearTimeout(pulseTimerRef.current);
          }
        };
      }
    }, [
      playbarState.clip?.id,
      playbarState.isPlaying,
      likeStatus,
      dislikeStatus,
      clip.id,
    ]);

    const isUserSongOwner =
      session?.userId !== undefined && clip?.user_id === session?.userId;
    const visibleStats = !isSecretStatsProfile({ handle: clip?.handle || '' });
    const enableClipComments = !!clip.allow_comments;
    const showCommentCount = visibleStats && !isPlaybar && isUserSongOwner;
    const showDislike = explicitShowDislike ?? !trendingMode;
    // For the risky change of removing the dislike button from playbar:
    // const showDislike = explicitShowDislike ?? !(trendingMode || isPlaybar);

    if (clip.preview_seconds !== undefined) return null;

    return (
      <>
        <div
          className={twMerge(
            clsx('flex w-full flex-row items-center gap-1', {
              'justify-between': asCardActions,
              'gap-0': enablePin,
            }),
            className
          )}
        >
          {isFromSongRow && !clip.is_trashed && !dropdownOnly && !mini ? (
            <div className='flex flex-row items-center gap-2'>
              {showCoverInSongRow(isContestClip) ? (
                <Button
                  size={buttonSize}
                  onClick={() => {
                    eventLogger.logAudioActionWithContext({
                      isMobile,
                      actionName: ActionName.coverSong,
                      clip,
                      session,
                      pathname,
                      componentContext: ComponentContext.SONG_ACTIONS,
                    });

                    genForm.resetPersona();
                    genForm.resetContinueClip();
                    genForm.resetInfill();
                    genForm.setCoverClip(clip);

                    if (isMobile) {
                      genForm.shouldOpenMobileCreate = true;
                    }

                    genForm.setTask('cover');

                    if (pathname !== '/create') {
                      router.push('/create');
                    }
                  }}
                >
                  Cover
                </Button>
              ) : null}
              {session.sessionIsLoaded &&
              !shouldShowRemixButton({ clip, session }) &&
              showExtentedInSongRow(
                isVirtualPlaylist,
                isComplete,
                isContestClip,
                clip,
                session.user?.id
              ) ? (
                <Button
                  size={buttonSize}
                  onClick={(e) => {
                    if (
                      isFeatureEnabledForPlan(session, PlanFeature.EditMode) &&
                      session.flags?.['edit-mode-extend'] &&
                      clip?.user_id === session.userId &&
                      !isMobile
                    ) {
                      if (e.metaKey || e.ctrlKey) {
                        window.open(`/edit/${clip?.id}`, '_blank');
                      } else {
                        genForm.cacheState();
                        onTriggerEditMode?.();
                        window.location.href = `/edit/${clip?.id}`;
                      }
                    } else if (clip?.metadata?.infill) {
                      clips.runConcat(clip?.id, clip?.metadata?.infill, {
                        editSessionId: clip?.metadata?.edit_session_id,
                      });
                    } else {
                      eventLogger.logAudioActionWithContext({
                        isMobile,
                        actionName: ActionName.extendSong,
                        clip,
                        session,
                        pathname,
                        componentContext: ComponentContext.SONG_ACTIONS,
                      });
                      genForm.resetArtistClip();
                      genForm.resetCoverClip();
                      genForm.resetPersona();
                      genForm.setContinueClip(clip);
                      genForm.matchClipModel(clip);

                      if (isMobile) {
                        genForm.shouldOpenMobileCreate = true;
                      }

                      genForm.setTask(getExtendTask(clip));
                      if (pathname !== '/create') {
                        router.push('/create');
                      }
                    }
                  }}
                >
                  {session.flags?.['edit-mode-extend'] &&
                  isFeatureEnabledForPlan(session, PlanFeature.EditMode) &&
                  clip.user_id === session.userId &&
                  !isMobile
                    ? 'Edit'
                    : clip.metadata.infill
                      ? 'Confirm'
                      : 'Extend'}
                </Button>
              ) : null}

              {isFeatureEnabledForPlan(session, PlanFeature.EditMode) &&
              clip.status === 'complete' &&
              clip.user_id === session.userId ? (
                <Button
                  variant={ButtonVariant.Standard}
                  shape={buttonShape}
                  size={buttonSize}
                  onClick={async () => {
                    window.location.href = `/edit/${clip.id}`;
                  }}
                >
                  Edit
                </Button>
              ) : null}

              <RemixOptions
                clip={clip}
                dropdownPosition='bottom'
                showDropdownIcon={true}
                buttonVariant={ButtonVariant.Primary}
                buttonSize={buttonSize}
                buttonShape={buttonShape}
                buttonClassName='py-2'
                hideOnOwnSong
              />

              {!isVirtualPlaylist &&
              session.user?.id === clip.user_id &&
              isComplete &&
              !clip.is_trashed ? (
                shouldShowGetFullSong(clip, session?.user?.id) ? (
                  <GetFullSongButton clip={clip} />
                ) : (
                  <PublishButton clip={clip} />
                )
              ) : null}
            </div>
          ) : null}
          {dropdownOnly || mini ? null : (
            <div className='flex flex-row gap-1'>
              {(asCardActions || trendingMode) && (
                <Button
                  variant={buttonVariant}
                  shape={buttonShape}
                  size={buttonSize}
                  aspectSquare={buttonAspectSquare}
                  icon={PlayIcon}
                  iconClassName={buttonIconClassName}
                  onClick={onPlayCountClick}
                  aria-label='Play Count'
                  active={false}
                >
                  {visibleStats ? getCountString(clip.play_count || 0) : null}
                </Button>
              )}

              <ClipLikeButton
                clipId={clip.id}
                onClick={handleLikeClick}
                ref={likeButtonRef}
                variant={buttonVariant}
                shape={buttonShape}
                size={buttonSize}
                aspectSquare={buttonAspectSquare}
                iconClassName={clsx(
                  {
                    'animate-pulse':
                      !isLastCharNumber(session.userId ?? '') && shouldPulse,
                  },
                  buttonIconClassName
                )}
                aria-label='Playbar: Like'
                showCount={showStats && visibleStats}
              />
              {showDislike && (
                <Button
                  variant={buttonVariant}
                  size={buttonSize}
                  shape={buttonShape}
                  aspectSquare={buttonAspectSquare}
                  icon={ThumbsDownIcon}
                  iconClassName={clsx(
                    {
                      'animate-pulse':
                        !isLastCharNumber(session.userId ?? '') && shouldPulse,
                    },
                    buttonIconClassName
                  )}
                  onClick={handleDislikeClick}
                  aria-label='Playbar: Dislike'
                  active={dislikeStatus}
                />
              )}
            </div>
          )}
          {dropdownOnly || mini || !enableClipComments ? null : (
            <Button
              variant={buttonVariant}
              size={buttonSize}
              shape={buttonShape}
              aspectSquare={buttonAspectSquare}
              icon={CommentIcon}
              iconClassName={buttonIconClassName}
              href={`/song/${clip.id}?show_comments=true`}
              onClick={() => {
                logWebUserEvent({
                  actionName: 'SongActionCommentsClicked',
                  context: {
                    clipId: clip?.id,
                    commentCount: isPlaybar ? undefined : clip.comment_count,
                  },
                });
              }}
              aria-label='Playbar: Comment'
              active={isPlaybar}
              className={
                isProjectsFeatureEnabled(session) && enablePin ? 'pr-0' : ''
              }
            >
              {showCommentCount ? (
                <span className='min-w-5'>
                  {getCountString(clip.comment_count || 0)}
                </span>
              ) : null}
            </Button>
          )}
          {dropdownOnly ||
          mini ||
          (enablePin && !isMobile) ||
          (isPlaybar && !isDesktop) ? null : (
            <>
              <Tooltip
                label='Copy Song Link'
                size='sm'
                background={TOOLTIP_BACKGROUND}
                backdropFilter='blur(40px)'
                rounded='md'
                color='#ffffff'
                padding='10px'
                fontFamily={'Neue Montreal'}
              >
                <Button
                  ref={shareButtonRef}
                  variant={buttonVariant}
                  shape={buttonShape}
                  size={buttonSize}
                  aspectSquare={buttonAspectSquare}
                  icon={ShareArrowIcon}
                  iconClassName={buttonIconClassName}
                  onClick={async () => {
                    logWebUserEvent({
                      actionName: 'SongActionShareClicked',
                      principalObjectValue: clip?.id,
                      principalObjectType: 'song',
                    });
                    await shareClip(clips.apiClient, clip);
                  }}
                  aria-label='Playbar: Share'
                  active={isPlaybar}
                />
              </Tooltip>
            </>
          )}
          {isProjectsFeatureEnabled(session) && enablePin && (
            <div className='flex items-center'>
              <Button
                variant={buttonVariant}
                shape={buttonShape}
                size={buttonSize}
                aspectSquare={buttonAspectSquare}
                icon={BookmarkIcon}
                iconClassName={buttonIconClassName}
                onClick={(e) => {
                  onPinClipToProject?.();
                  e.preventDefault();
                  e.stopPropagation();
                }}
                aria-label='Pin to Project'
                active={project.isPinned(clip.id)}
              />
            </div>
          )}
          {!!clip.id ? (
            <SongMenuWithContextForMultiselect
              clip={clip}
              sectionName={sectionName}
              rowKey={rowKey}
            />
          ) : null}
        </div>
      </>
    );
  }
);

export default SongActions;
