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

import { FocusedObjectContext } from '@/app/(root)/create/v2/useFocusedObject';
// TODO: re-enable drag and drop when we figure out the right UX
// import Draggable, {
//   useClipDraggedObject,
// } from '@/app/(root)/dragAndDrop/Draggable';
import useClip from '@/hooks/useClip';
import { useContextSelector } from '@/hooks/useContextSelector';
import { MoreHorizontalIcon, TriangleDownIcon } from '@/icons';

import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '../button/Button';
import {
  ContextMenuTrigger,
  RightClickMenuTrigger,
} from '../contextMenu/ContextMenu';
import {
  ClipContextProvider,
  NullableClipContextProvider,
} from './ClipContext';
import {
  ClipDetailsWrapper,
  ClipDotAndCheckbox,
  ClipExactTags,
  ClipImage,
  ClipRowGroup,
  ClipRowWrapper,
  ClipTitle,
  LibraryClipInteractions,
} from './ClipElements';
import { MoreMenuContents, RemixEditMenuContents } from './ClipMenus';
import MultiSelectContext from './MultiSelectContext';
import { ClipBrowserContext } from './useClipBrowser';
import useClipPlayback, { ClipPlaybackProvider } from './useClipPlayback';
import { useClipPreviewUpsell } from './useClipPreviewUpsell';
import virtualizeClipRow from './virtualizeClipRow';

export const LibraryClipRow = virtualizeClipRow(
  observer(({ clipId }: { clipId: string }) => {
    const { clip } = useClip(clipId);
    const clipPlayback = useClipPlayback(clip);

    const [isRemixEditMenuOpen, setIsRemixEditMenuOpen] = useState(false);
    const [isMoreMenuOpen, setIsMoreMenuOpen] = useState(false);
    const {
      previewClipType,
      previewUnlocking,
      manualUnlock,
      enableManualUnlock,
      isUnlocking,
      handleToggle,
      handleUnlockPreview,
    } = useClipPreviewUpsell(clip);

    const isMultiSelected = useContextSelector(MultiSelectContext, (ctx) =>
      ctx.selectedClipIds.includes(clip?.id || '')
    );
    const toggleMultiSelectClip = useContextSelector(
      MultiSelectContext,
      (ctx) => ctx.toggleClip
    );
    const clearMultiSelect = useContextSelector(
      MultiSelectContext,
      (ctx) => ctx.clear
    );
    const isMultiSelecting = useContextSelector(
      MultiSelectContext,
      (ctx) => ctx.selectedClipIds.length > 0
    );
    const setFocusedObject = useContextSelector(
      FocusedObjectContext,
      ({ setFocusedObject }) => setFocusedObject
    );
    const selectRangeMultiSelect = useContextSelector(
      MultiSelectContext,
      (ctx) => ctx.selectRange
    );
    const setLastSelectedClip = useContextSelector(
      MultiSelectContext,
      (ctx) => ctx.setLastSelected
    );
    const allClipIds = useContextSelector(
      ClipBrowserContext,
      (context) => context.clips
    );

    const keepHovering =
      isMultiSelected || isRemixEditMenuOpen || isMoreMenuOpen;

    const handleMouseDown = useCallback((e: React.MouseEvent) => {
      // Prevent text selection during multi-select operations
      if (e.shiftKey || e.ctrlKey || e.metaKey) {
        e.preventDefault();
      }
    }, []);

    const handleRowClick = useCallback(
      (e: React.MouseEvent) => {
        const isInteractiveElement =
          !isMultiSelected &&
          (e.target instanceof HTMLElement || e.target instanceof SVGElement) &&
          e.target.matches(
            '.multi-select-button, .multi-select-button *, .clip-interaction-button, .clip-interaction-button *, .context-menu-button, .context-menu-button *'
          );

        if (isInteractiveElement || e.button !== 0) {
          return;
        }

        if (e.shiftKey) {
          selectRangeMultiSelect(clipId, allClipIds);
        } else if (e.ctrlKey || e.metaKey) {
          toggleMultiSelectClip(clipId);
        } else {
          setFocusedObject({ type: 'clip', clipId });
          setLastSelectedClip(clipId);
          if (!isMultiSelected) clearMultiSelect();
        }
      },
      [
        clipId,
        clearMultiSelect,
        setFocusedObject,
        isMultiSelected,
        toggleMultiSelectClip,
        selectRangeMultiSelect,
        allClipIds,
        setLastSelectedClip,
      ]
    );

    // const draggedObject = useClipDraggedObject(clipId);

    const renderActionButtons = useCallback(() => {
      if (!clip) return null;

      // Show unlock UI for preview clips that are being unlocked
      if (previewUnlocking) {
        if (manualUnlock && enableManualUnlock) {
          return (
            <Button
              onClick={handleUnlockPreview}
              variant={ButtonVariant.Primary}
              size={ButtonSize.Small}
              shape={ButtonShape.Rounded}
              className='rounded-full text-xs lg:text-sm'
              disabled={isUnlocking}
            >
              {isUnlocking ? 'Unlocking...' : 'Unlock song'}
            </Button>
          );
        }
        return (
          <span className='animate-pulse text-xs text-foreground-primary lg:text-sm'>
            Unlocking song...
          </span>
        );
      }

      // Show upgrade button for preview clips
      if (previewClipType) {
        return (
          <Button
            onClick={handleToggle}
            variant={ButtonVariant.Primary}
            size={ButtonSize.Small}
            shape={ButtonShape.Rounded}
            className='rounded-full text-xs lg:text-sm'
          >
            Upgrade for full song
          </Button>
        );
      }

      // Show default buttons for non-preview clips
      return (
        <>
          {!clip.is_trashed && !isMultiSelecting && (
            <ContextMenuTrigger
              onOpenChange={setIsRemixEditMenuOpen}
              ButtonComponent={(props) => (
                <Button
                  className='hover-only remix-menu-trigger context-menu-button px-4 py-2.5 text-xs'
                  shape={ButtonShape.Pill}
                  {...props}
                >
                  Remix/Edit <TriangleDownIcon className='h-5 w-5' />
                </Button>
              )}
              ContentsComponent={RemixEditMenuContents}
            />
          )}
          <ContextMenuTrigger
            onOpenChange={setIsMoreMenuOpen}
            ButtonComponent={(props) => (
              <Button
                className='hover-fade-in context-menu-button p-3'
                shape={ButtonShape.Pill}
                icon={<MoreHorizontalIcon className='h-4 w-4' />}
                {...props}
              />
            )}
            ContentsComponent={MoreMenuContents}
          />
        </>
      );
    }, [
      clip,
      previewUnlocking,
      manualUnlock,
      enableManualUnlock,
      isUnlocking,
      handleUnlockPreview,
      previewClipType,
      handleToggle,
      isMultiSelecting,
    ]);

    if (!clip) {
      return (
        <ClipPlaybackProvider value={clipPlayback}>
          <NullableClipContextProvider clip={null}>
            <ClipRowWrapper>
              <ClipRowGroup>
                <ClipImage />
                <ClipDetailsWrapper>
                  <ClipTitle />
                  <ClipExactTags />
                </ClipDetailsWrapper>
              </ClipRowGroup>
            </ClipRowWrapper>
          </NullableClipContextProvider>
        </ClipPlaybackProvider>
      );
    }

    return (
      <ClipPlaybackProvider value={clipPlayback}>
        <NullableClipContextProvider clip={clip}>
          {/* <Draggable draggedObject={draggedObject}> */}
          <RightClickMenuTrigger ContentsComponent={MoreMenuContents}>
            <ClipRowWrapper
              className='clip-row'
              keepHovering={keepHovering}
              onMouseDown={handleMouseDown}
              onClick={handleRowClick}
            >
              <ClipRowGroup>
                <ClipDotAndCheckbox />
                <ClipImage />
                <ClipDetailsWrapper>
                  <ClipTitle />
                  <ClipExactTags />
                  <LibraryClipInteractions />
                </ClipDetailsWrapper>
              </ClipRowGroup>
              <ClipRowGroup className='block-clip-focus flex-shrink-0'>
                {clip && (
                  <ClipContextProvider clip={clip}>
                    {renderActionButtons()}
                  </ClipContextProvider>
                )}
              </ClipRowGroup>
            </ClipRowWrapper>
          </RightClickMenuTrigger>
          {/* </Draggable> */}
        </NullableClipContextProvider>
      </ClipPlaybackProvider>
    );
  })
);
