'use client';

/* eslint jsx-a11y/click-events-have-key-events: warn */

/* eslint jsx-a11y/no-static-element-interactions: warn */
import clsx from 'clsx';
import { motion } from 'framer-motion';
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 Button from '@/components/button/ReactAriaCompatButton';
import {
  ChevronDownIcon,
  ChevronUpIcon,
  CoverCreateIcon,
  ExtendRightIcon,
  RemixIcon,
  ReuseStylesLyricsIcon,
  SpeedIcon,
} from '@/icons';
import logWebUserEvent from '@/logging/logWebUserEvent';
import { Clip } from '@/state/clipStore';
import {
  handleAdjustSpeedAction,
  handleRemixCoverAction,
  handleRemixExtendAction,
  handleRemixUseStylesLyricsAction,
  shouldShowRemixButton,
} from '@/utils/remixUtils';

import { Tooltip } from '../tooltip/Tooltip';

type RemixOptionsProps = {
  className?: string;
  buttonClassName?: string;
  dropdownPosition?: 'top' | 'bottom';
  buttonVariant?: ButtonVariant;
  buttonSize?: ButtonSize;
  buttonShape?: ButtonShape;
  hideOnOwnSong?: boolean;
  showDropdownIcon?: boolean;
  buttonIconClassName?: string;
} & (
  | {
      clip: Clip;
      clipId?: string;
    }
  | {
      clip?: Clip;
      clipId: string;
    }
);

const RemixOptions = observer(
  ({
    clip: explicitClip,
    clipId,
    className,
    dropdownPosition = 'top',
    buttonVariant = ButtonVariant.Tertiary,
    buttonSize = ButtonSize.Medium,
    buttonShape = ButtonShape.Pill,
    hideOnOwnSong = false,
    showDropdownIcon = false,
    buttonClassName,
    buttonIconClassName,
  }: RemixOptionsProps) => {
    const { session, genForm, createV2, clips: clipsStore } = useStores();
    const [isRemixOptionsExpanded, setIsRemixOptionsExpanded] = useState(false);
    const remixOptionsRef = useRef<HTMLDivElement>(null);
    const pathname = usePathname();
    const router = useRouter();
    const clip = explicitClip ?? clipsStore.clipById[clipId || ''];

    useEffect(() => {
      const handleClickOutside = (event: MouseEvent) => {
        if (
          remixOptionsRef.current &&
          !remixOptionsRef.current.contains(event.target as Node)
        ) {
          setIsRemixOptionsExpanded(false);
        }
      };

      if (isRemixOptionsExpanded) {
        document.addEventListener('mousedown', handleClickOutside);
      }

      return () => {
        document.removeEventListener('mousedown', handleClickOutside);
      };
    }, [isRemixOptionsExpanded]);

    if (!clip || !shouldShowRemixButton({ clip, session, hideOnOwnSong })) {
      return null;
    }
    const isRemixDisabled =
      clip.metadata?.can_remix === false || clip.preview_seconds !== undefined;

    const remixOptions = [
      {
        id: 'cover',
        label: 'Cover',
        icon: CoverCreateIcon,
        onClick: () => {
          if (clip) {
            logWebUserEvent({
              actionName: 'RemixOptionsCoverClicked',
              context: {
                clipId: clip?.id,
              },
            });
            handleRemixCoverAction({
              clip,
              session,
              genForm,
              createV2,
              router,
              pathname,
            });
          }
        },
      },
      {
        id: 'extend',
        label: 'Extend',
        icon: ExtendRightIcon,
        onClick: () => {
          if (clip) {
            logWebUserEvent({
              actionName: 'RemixOptionsExtendClicked',
              context: {
                clipId: clip?.id,
              },
            });
            handleRemixExtendAction({
              clip,
              session,
              genForm,
              createV2,
              router,
              pathname,
            });
          }
        },
      },
      {
        id: 'use-style-lyrics',
        label: 'Reuse Prompt',
        icon: ReuseStylesLyricsIcon,
        onClick: () => {
          if (clip) {
            logWebUserEvent({
              actionName: 'RemixOptionsUseStylesLyricsClicked',
              context: {
                clipId: clip?.id,
              },
            });
            handleRemixUseStylesLyricsAction({
              clip,
              session,
              genForm,
              createV2,
              router,
              pathname,
            });
          }
        },
      },
      {
        id: 'adjust-speed',
        label: 'Adjust Speed',
        icon: SpeedIcon,
        disabled: false,
        onClick: () => {
          if (clip) {
            logWebUserEvent({
              actionName: 'RemixOptionsAdjustSpeedClicked',
              context: {
                clipId: clip?.id,
              },
            });
            handleAdjustSpeedAction({
              clip,
              session,
              genForm,
              createV2,
              router,
              pathname,
              showRemixCreate: true,
            });
          }
        },
      },
    ];

    return (
      <div
        ref={remixOptionsRef}
        className={twMerge('flex w-full flex-col gap-2', className)}
        onClick={(e) => e.stopPropagation()}
      >
        <div className='relative'>
          <div className='group relative'>
            {isRemixDisabled ? (
              <Tooltip
                label='Remixes are disabled for this song.'
                placement='top'
              >
                <span className='inline-block w-full'>
                  <Button
                    onClick={() => {}}
                    variant={buttonVariant}
                    size={buttonSize}
                    iconStart={RemixIcon}
                    shape={buttonShape}
                    iconClassName={buttonIconClassName}
                    className={twMerge(
                      `w-full cursor-not-allowed opacity-50 focus:outline-none focus-visible:ring-0`,
                      buttonClassName
                    )}
                    disabled={true}
                  >
                    Remix
                  </Button>
                </span>
              </Tooltip>
            ) : (
              <Button
                onClick={() =>
                  setIsRemixOptionsExpanded(!isRemixOptionsExpanded)
                }
                variant={buttonVariant}
                size={buttonSize}
                iconStart={RemixIcon}
                shape={buttonShape}
                iconClassName={buttonIconClassName}
                className={twMerge(
                  `focus:outline-none focus-visible:ring-0`,
                  buttonClassName
                )}
                iconEnd={
                  showDropdownIcon ? (
                    isRemixOptionsExpanded ? (
                      <ChevronUpIcon />
                    ) : (
                      <ChevronDownIcon />
                    )
                  ) : null
                }
              >
                Remix
              </Button>
            )}

            {isRemixOptionsExpanded && !isRemixDisabled && (
              <motion.div
                initial={{ height: 0, opacity: 0 }}
                animate={{ height: 'auto', opacity: 1 }}
                exit={{ height: 0, opacity: 0 }}
                transition={{ duration: 0.2 }}
                className={clsx(
                  'absolute left-0 z-60 w-max min-w-full overflow-hidden rounded-xl bg-background-secondary',
                  {
                    'bottom-full': dropdownPosition === 'top',
                    'mb-2': dropdownPosition === 'top',
                    'top-full': dropdownPosition === 'bottom',
                    'mt-0.5': dropdownPosition === 'bottom',
                  }
                )}
              >
                {remixOptions.map((option) => (
                  <Button
                    key={option.id}
                    onClick={option.onClick}
                    disabled={option.disabled}
                    variant={ButtonVariant.Tertiary}
                    size={ButtonSize.Small}
                    shape={ButtonShape.Rounded}
                    iconStart={option.icon}
                    className={clsx(
                      'flex w-full items-center text-left text-sm text-foreground-primary transition-colors',
                      {
                        'cursor-not-allowed opacity-50 hover:bg-transparent':
                          option.disabled,
                        'hover:bg-background-primary/10': !option.disabled,
                      }
                    )}
                  >
                    {option.label}
                  </Button>
                ))}
              </motion.div>
            )}
          </div>
        </div>
      </div>
    );
  }
);

export default RemixOptions;
