'use client';

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

import { useStores } from '@/app/(root)/AppProviders';
import { ModalTypes } from '@/components/modal/constants/ModalTypes';
import { LabelWithSwitch } from '@/components/modal/publishSong/LabelWithSwitch';
import ModalHeader from '@/components/modal/publishSong/ModalHeader';
import { showErrorToast } from '@/components/modal/publishSong/publishSongToasts';
import { toast } from '@/components/toast/Toast';
import { useContestClips } from '@/hooks/useContestClip';
import SongModalContext from '@/hooks/useSongModal';
import { CommentIcon, PinIcon, RemixIcon } from '@/icons';
import logWebUserEvent from '@/logging/logWebUserEvent';
import { Clip } from '@/state/clipStore';
import {
  MAX_PINNED_SONGS_ARTIST_PROFILE,
  MAX_PINNED_SONGS_PROFILE,
} from '@/utils/constants';
import { getPinModalOptions } from '@/utils/pinnedClips';

export const MoreOptionsScreen = observer(
  ({
    isPinned,
    setIsPinned,
  }: {
    isPinned: boolean;
    setIsPinned: (isPinned: boolean) => void;
  }) => {
    const { library, clips, session } = useStores();
    const { navigateTo, modalType } = useContext(SongModalContext);
    const { isContestEligible, isContestBaseClip } = useContestClips();

    const clip = clips.clipById[library.activeClip?.id || ''] as Clip;
    const clipId = clip?.id || '';
    const isOwner = session.user?.id === clip?.user_id;
    const showRemixSwitch = isOwner;
    const allowPinning =
      isOwner &&
      (modalType !== ModalTypes.UPDATE_CLIP_METADATA ||
        (modalType === ModalTypes.UPDATE_CLIP_METADATA && clip.is_public));

    const handleRemixToggle = async ({ isAllowed }: { isAllowed: boolean }) => {
      logWebUserEvent({
        actionName: 'PublishSongModalEnableRemixClicked',
        principalObjectType: 'song',
        principalObjectValue: clipId,
        context: {
          remixEnabled: isAllowed,
        },
      });
      try {
        await clips.toggleCanRemix(clipId, isAllowed);
        toast({
          title: `Remixes have been ${isAllowed ? 'enabled' : 'disabled'}.`,
          duration: 2000,
          isClosable: true,
        });
      } catch (error) {
        console.error(error);
        toast({
          title: 'Error',
          description:
            error instanceof Error
              ? error.message
              : 'An error occurred while updating your settings.',
          status: 'error',
          duration: 5000,
          isClosable: true,
        });
      }
    };

    const handleCommentsToggle = async ({
      isAllowed,
    }: {
      isAllowed: boolean;
    }) => {
      logWebUserEvent({
        actionName: 'PublishSongModalAllowCommentsClicked',
        principalObjectType: 'song',
        principalObjectValue: clip.id,
        context: {
          allowComments: isAllowed,
        },
      });
      try {
        await clips.setCommentsEnabled(clipId, isAllowed);
        toast({
          title: `Comments have been ${isAllowed ? 'enabled' : 'disabled'}.`,
          duration: 2000,
          isClosable: true,
        });
      } catch (error) {
        console.error(error);
        showErrorToast();
      }
    };

    const handlePinSongToProfile = async ({
      shouldPin,
    }: {
      shouldPin: boolean;
    }) => {
      logWebUserEvent({
        actionName: 'PublishSongModalPinSongToProfileClicked',
        principalObjectType: 'song',
        principalObjectValue: clip?.id,
        context: {
          isPinned: shouldPin,
        },
      });
      setIsPinned(shouldPin);

      const { title, message, showModal } = getPinModalOptions({
        clipIsPrivate: true,
        pinnedCount: clips.getPinnedCount(),
        isPublishFlow: true,
        maxPins: session.flags?.['artist-profiles']
          ? MAX_PINNED_SONGS_ARTIST_PROFILE
          : MAX_PINNED_SONGS_PROFILE,
      });

      if (shouldPin && showModal) {
        toast({
          title: title,
          description: message,
          duration: 5000,
          isClosable: true,
        });
      } else {
        toast({
          title: `This song will ${shouldPin ? '' : 'not'} be pinned to Profile.`,
          duration: 2000,
          isClosable: true,
        });
      }
    };

    const isContestRemix =
      isContestEligible({ clip }) && !isContestBaseClip({ clipId });
    const isAllowRemixToggleDisabled = !isOwner || isContestRemix;

    return (
      <div className='flex h-full min-h-[300px] w-full flex-col justify-between'>
        <div className='flex flex-col'>
          <ModalHeader title='More Options' onBack={() => navigateTo('main')} />
          <div className='flex flex-col px-6 pt-6'>
            {isOwner && (
              <LabelWithSwitch
                label='Allow Comments'
                checked={!!clip?.allow_comments}
                onChange={(isAllowed) => handleCommentsToggle({ isAllowed })}
                icon={CommentIcon}
                className={clsx({
                  'rounded-b-none border-b-0': allowPinning || showRemixSwitch,
                })}
              />
            )}
            {showRemixSwitch && (
              <LabelWithSwitch
                label='Allow Remix'
                checked={!!clip?.metadata?.can_remix}
                onChange={(isAllowed) => handleRemixToggle({ isAllowed })}
                icon={RemixIcon}
                className={clsx('rounded-t-none', {
                  'rounded-none border-b-0': allowPinning,
                })}
                tooltipText={
                  isContestRemix
                    ? `Remixes are not allowed for contest remixes.`
                    : `You can now remix songs on Suno — and other users can remix yours too! By default, all your tracks are remixable, but you can turn this off anytime. Every remix will link back to your original, so you'll always get credit where it's due.`
                }
                disabled={isAllowRemixToggleDisabled}
              />
            )}
            {allowPinning && (
              <LabelWithSwitch
                label='Pin Song to Profile'
                checked={isPinned}
                onChange={(shouldPin) => handlePinSongToProfile({ shouldPin })}
                icon={PinIcon}
                className='rounded-t-none'
              />
            )}
          </div>
        </div>
      </div>
    );
  }
);

export default MoreOptionsScreen;
