import clsx from 'clsx';
import { AnimatePresence, motion } from 'framer-motion';
import { observer } from 'mobx-react-lite';
import { ChangeEvent, useEffect, useRef } from 'react';

import { AnimatedTabs } from '@/app/(root)/create/createV2/AnimatedTabs';
import { CreateV2Switch } from '@/app/(root)/create/createV2/CreateV2Switch';
import { useResizableDiv } from '@/app/(root)/create/createV2/useResizableDiv';
import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import Textarea from '@/components/textarea/Textarea';
import { Tooltip } from '@/components/tooltip/Tooltip';
import { FourStarIcon, LyricsIcon, TrashIcon } from '@/icons';
import logWebUserEvent from '@/logging/logWebUserEvent';
import {
  CREATE_VERSION,
  MAX_CUSTOM_PROMPT_CHARS_LONG,
} from '@/utils/constants';

type Props = {
  initialHeight?: number;
  onHeightChange: (height: number) => void;
  onGenerateLyrics: () => void;
  setIsEditingLyrics: (isEditing: boolean) => void;
  setHasPromptedLyrics: (hasPrompted: boolean) => void;
  activeLyricsMode: 'custom' | 'auto' | 'instrumental';
  setActiveLyricsMode: (mode: 'custom' | 'auto' | 'instrumental') => void;
  activeLyrics: string;
  setActiveLyrics: (lyrics: string) => void;
  activeLyricsSubject: string;
  setActiveLyricsSubject: (subject: string) => void;
  activeLyricsModeTab: 'auto' | 'custom' | 'instrumental';
  setActiveLyricsModeTab: (mode: 'auto' | 'custom' | 'instrumental') => void;
  generatingLyrics: boolean;
  enableLyricsGeneration: boolean;
};

export const LyricsSection = observer(
  ({
    initialHeight,
    onHeightChange,
    activeLyricsMode,
    setActiveLyricsMode,
    activeLyrics,
    setActiveLyrics,
    activeLyricsSubject,
    setActiveLyricsSubject,
    activeLyricsModeTab,
    setActiveLyricsModeTab,
    onGenerateLyrics,
    generatingLyrics,
    enableLyricsGeneration,
  }: Props) => {
    const { renderResizer, additionalHeight, isDragging } =
      useResizableDiv(initialHeight);
    const lyricsSectionRef = useRef<any>(null);
    useEffect(() => {
      onHeightChange(additionalHeight);
    }, [additionalHeight]);
    return (
      <div
        className={clsx('relative flex flex-col', {
          'flex-1': activeLyricsMode === 'custom',
          group: activeLyricsMode !== 'instrumental',
        })}
        ref={lyricsSectionRef}
      >
        <div
          className={clsx(
            'flex flex-col rounded-[20px] bg-[rgba(255,255,255,0.10)] p-2 backdrop-blur-[100px]',
            {
              'min-h-[200px]':
                activeLyricsMode === 'custom' || activeLyricsMode === 'auto',
              'transition-all duration-500 ease-in-out': !isDragging,
              'h-[60px] min-h-[60px] overflow-hidden':
                activeLyricsMode === 'instrumental',
            }
          )}
          style={{
            height:
              activeLyricsMode === 'custom' || activeLyricsMode === 'auto'
                ? `${280 + additionalHeight}px`
                : undefined,
          }}
        >
          <div
            className={clsx(
              'flex w-full flex-row items-center pr-2 pl-4 transition-[height,opacity] duration-500 ease-in-out',
              {
                'h-0 overflow-hidden opacity-0':
                  activeLyricsMode === 'instrumental',
                'h-[36px] opacity-100': activeLyricsMode !== 'instrumental',
              }
            )}
          >
            <div className='flex flex-row items-center gap-[5px]'>
              <LyricsIcon className='h-4 w-4' />
              <span className='flex-1 text-base font-medium select-none'>
                {activeLyricsMode === 'custom' ||
                activeLyricsMode === 'instrumental'
                  ? 'Lyrics'
                  : 'Describe your lyrics'}
              </span>
            </div>
            <div className='flex flex-1 flex-row-reverse items-center gap-2'>
              <AnimatedTabs
                value={activeLyricsModeTab}
                id='lyrics-tabs'
                buttonClassName='text-sm px-3 py-2'
                className='border-0 bg-transparent p-0 text-sm'
                disabled={activeLyricsMode === 'instrumental'}
                onChange={(option) => {
                  const previousLyricsMode = activeLyricsMode;
                  setActiveLyricsModeTab(
                    option.value as 'auto' | 'custom' | 'instrumental'
                  );
                  setTimeout(() => {
                    setActiveLyricsMode(
                      option.value as 'auto' | 'custom' | 'instrumental'
                    );
                    requestAnimationFrame(() => {
                      if (lyricsSectionRef.current) {
                        lyricsSectionRef.current.scrollIntoView({
                          behavior: 'smooth',
                          block: 'end',
                        });
                      }
                    });
                  }, 300);
                  logWebUserEvent({
                    actionName: 'ChangeLyricsMode',
                    context: {
                      createMode: 'custom',
                      lyricsModeAfter: option.value as
                        | 'auto'
                        | 'custom'
                        | 'instrumental',
                      lyricsModeBefore: previousLyricsMode,
                      createVersion: CREATE_VERSION,
                    },
                  });
                }}
                shouldAnimate={activeLyricsMode !== activeLyricsModeTab}
                options={[
                  {
                    value: 'auto',
                    title: 'Auto',
                  },
                  {
                    value: 'custom',
                    title: 'Write Lyrics',
                  },
                ]}
              />
            </div>
          </div>
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{
              duration: 0.3,
              scale: {
                type: 'spring',
                visualDuration: 0.4,
                bounce: 0.1,
              },
            }}
            className={clsx(
              'relative flex h-auto flex-1 flex-col overflow-hidden',
              {
                'p-0': activeLyricsMode === 'instrumental',
                'p-2 px-0 pt-2': activeLyricsMode !== 'instrumental',
                'pb-2': activeLyricsMode === 'auto',
              }
            )}
          >
            <Textarea
              className={clsx(
                'h-full rounded-2xl border border-white/10 transition-all duration-500 ease-in-out',
                {
                  'max-h-0 opacity-0': activeLyricsMode === 'instrumental',
                  'max-h-[2000px] opacity-100':
                    activeLyricsMode !== 'instrumental',
                }
              )}
              textareaClassName='placeholder:brightness-150 h-full custom-scrollbar-transparent'
              bgColor='transparent'
              isReadOnly={activeLyricsMode === 'instrumental'}
              showMaxLengthAtCharsRemaining={
                activeLyricsMode === 'custom' ? 200 : 20
              }
              paddingBottom={0}
              maxLength={
                activeLyricsMode === 'custom'
                  ? MAX_CUSTOM_PROMPT_CHARS_LONG
                  : 200
              }
              isScrollable
              placeholder={
                activeLyricsMode === 'custom'
                  ? 'Add your own lyrics here'
                  : activeLyricsMode === 'auto'
                    ? 'Describe your lyrics'
                    : ''
              }
              value={
                activeLyricsMode === 'custom'
                  ? activeLyrics
                  : activeLyricsSubject
              }
              onChange={function (
                event: ChangeEvent<HTMLTextAreaElement>
              ): void {
                if (activeLyricsMode === 'custom') {
                  setActiveLyrics(event.target.value);
                } else {
                  setActiveLyricsSubject(event.target.value);
                }
              }}
              data-testid='lyrics-input-textarea'
            />
            <div className='absolute right-1 bottom-4'>
              {activeLyrics.length > 0 && activeLyricsMode === 'custom' ? (
                <Button
                  variant={ButtonVariant.Secondary}
                  shape={ButtonShape.Pill}
                  size={ButtonSize.Mini}
                  className='mr-2'
                  onClick={(e) => {
                    setActiveLyrics('');
                    logWebUserEvent({
                      actionName: 'ClearLyrics',
                      context: {
                        createVersion: CREATE_VERSION,
                      },
                    });
                    e.stopPropagation();
                  }}
                  icon={TrashIcon}
                />
              ) : null}
            </div>
            <div className='absolute right-px bottom-[21px]'>
              <AnimatePresence>
                {activeLyricsMode === 'auto' && enableLyricsGeneration ? (
                  <motion.div
                    initial={{ opacity: 0 }}
                    animate={{ opacity: 1 }}
                    exit={{ opacity: 0 }}
                    transition={{
                      duration: 0.3,
                    }}
                  >
                    <Tooltip
                      label={
                        activeLyricsSubject?.length === 0
                          ? 'Please describe your lyrics first'
                          : ''
                      }
                    >
                      <Button
                        variant={ButtonVariant.Glass}
                        shape={ButtonShape.Pill}
                        size={ButtonSize.Small}
                        className='mr-2 bg-[rgba(255,255,255,0.04)] hover:bg-[rgba(255,255,255,0.08)]'
                        onClick={() => {
                          onGenerateLyrics();
                        }}
                        icon={generatingLyrics ? <SpinnerSVG /> : FourStarIcon}
                        disabled={
                          generatingLyrics || activeLyricsSubject?.length === 0
                        }
                      >
                        Generate Lyrics
                      </Button>
                    </Tooltip>
                  </motion.div>
                ) : null}
              </AnimatePresence>
            </div>
            <div className='absolute right-0 bottom-0 -mr-[7px]'>
              {renderResizer()}
            </div>
          </motion.div>
          <div
            className={clsx('flex flex-row items-center gap-2 px-2', {
              'pt-[6px] pb-[6px]': activeLyricsMode === 'instrumental',
              'pt-0': activeLyricsMode !== 'instrumental',
            })}
          >
            <CreateV2Switch
              label='Instrumental'
              checked={activeLyricsMode === 'instrumental'}
              containerClassName={clsx(
                'bg-white/10',
                activeLyricsMode === 'instrumental' && 'bg-primary/80'
              )}
              onChange={(checked: boolean) => {
                const previousLyricsMode = activeLyricsMode;
                if (checked) {
                  setActiveLyricsMode('instrumental');
                  setActiveLyricsModeTab('instrumental');
                } else {
                  setActiveLyricsMode('custom');
                  setActiveLyricsModeTab('custom');
                }
                logWebUserEvent({
                  actionName: 'ChangeLyricsMode',
                  context: {
                    createMode: 'custom',
                    lyricsModeAfter: checked ? 'instrumental' : 'custom',
                    lyricsModeBefore: previousLyricsMode,
                    createVersion: CREATE_VERSION,
                  },
                });
              }}
            />
          </div>
        </div>
      </div>
    );
  }
);
