import styled from '@emotion/styled';
import { observer } from 'mobx-react-lite';
import { usePathname } from 'next/navigation';
import { useCallback, useEffect, useRef, useState } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import CreateAudioDisplay from '@/app/(root)/create/createV2/componentsQ3/CreateAudioDisplay';
import {
  FALLBACK_SAMPLE_AUDIO,
  useUrlAudioSampler,
} from '@/app/(root)/create/createV2/componentsQ3/useUrlAudioSampler';
import Button, { ButtonShape, ButtonVariant } from '@/components/button/Button';
import useClipChanges from '@/components/clipBrowser/useClipChanges';
import {
  AutoClipPlaybackProvider,
  useClipPlaybackContext,
} from '@/components/clipBrowser/useClipPlayback';
import TimeReadout from '@/components/edit2025/TimeReadout';
import ImageWithFallback from '@/components/image/ImageWithFallback';
import Link from '@/components/link/Link';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import { Tooltip } from '@/components/tooltip/Tooltip';
import useClip from '@/hooks/useClip';
import { useSongRename } from '@/hooks/useSongRename';
import {
  CheckIcon,
  CloseIcon,
  EditIcon,
  PauseIcon,
  PlayIcon,
  RotateReverseIcon,
  ThumbsDownIcon,
  ThumbsUpIcon,
} from '@/icons';
import { withWebUserEvent } from '@/logging/logWebUserEvent';
import { Clip, isDisliked, isLiked } from '@/state/clipStore';
import { getClipTitle } from '@/utils/clip';
import { MAX_TITLE_CHARS, SMALL_IMAGE } from '@/utils/constants';

const SongArtworkContainer = styled.div`
  position: relative;
  width: 40px;
  height: 40px;
  cursor: pointer;

  img {
    opacity: 0.5;
  }
`;

const SongPlayIcon = styled.div`
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  width: 16px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
`;

const SongTitle = styled.div`
  font-size: 12px;
  color: var(--color-foreground-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
`;

const SongTimeReadout = styled.div`
  font-size: 12px;
  color: var(--color-foreground-inactive);
`;

const SongTextWrapper = styled.div`
  display: flex;
  flex-direction: column;
`;

const TitleEditWrapper = styled.div<{ editable?: boolean }>`
  display: flex;
  align-items: center;
  gap: 4px;
  border-radius: 6px;
  padding: 0;
  transition: background-color 0.15s ease;
  min-width: 0;
  flex-shrink: 1;

  ${({ editable }) =>
    editable &&
    `
      &:hover {
        background-color: var(--color-background-fog-thin);

        .edit-icon-wrapper {
          width: 20px;
          opacity: 1;
        }
      }
    `}
`;

const EditButton = styled.button`
  display: flex;
  align-items: center;
  justify-content: center;
  width: 0;
  height: 24px;
  border-radius: 4px;
  border: none;
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  opacity: 0;
  background-color: transparent;
  color: var(--color-foreground-primary);
  transition:
    width 0.15s ease,
    opacity 0.15s ease,
    background-color 0.15s ease;
  > * {
    opacity: 0.5;
  }
  &:hover {
    > * {
      opacity: 1;
    }
  }
`;

const TitleInput = styled.input`
  font-size: 12px;
  line-height: 14px;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--color-foreground-primary);
  border-radius: 0;
  padding: 2px 0;
  color: var(--color-foreground-primary);
  outline: none;
  min-width: 50px;

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
`;

const HiddenTextMeasure = styled.span`
  position: absolute;
  visibility: hidden;
  white-space: pre;
  font-size: 12px;
  line-height: 14px;
  padding: 2px 0;
  pointer-events: none;
`;

const EditActionButton = styled.button`
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 4px;
  border: none;
  cursor: pointer;
  transition: background-color 0.15s ease;
  background-color: var(--color-background-glass-thin);
  color: var(--color-foreground-primary);

  &:hover:not(:disabled) {
    background-color: var(--color-background-glass-thick);
  }

  &:active:not(:disabled) {
    background-color: var(--color-background-smoke-thick);
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
`;

const RemasterItemPlayback = observer(
  ({
    clip,
    sharedTimestampRef,
  }: {
    clip: Clip;
    sharedTimestampRef: React.MutableRefObject<number>;
  }) => {
    const {
      isLoadedIntoPlayer,
      isPlaying,
      onPlayClick,
      getCurrentProgress,
      setCurrentProgress,
    } = useClipPlaybackContext();
    const sampleAudio = useUrlAudioSampler(clip?.id, clip?.status);
    const frameCountRef = useRef<number>(0);
    const { setClipLiked, setClipDisliked } = useClipChanges();
    const pathname = usePathname();
    const [isExpanded, setIsExpanded] = useState(false);
    const { session } = useStores();
    const isOwnClip = clip && clip.user_id === session.user?.id;
    const editable = Boolean(isOwnClip);

    // Use the custom rename hook
    const {
      isEditing,
      editedTitle,
      isSaving,
      inputRef,
      measureRef,
      handleEditClick,
      handleSave,
      handleCancel,
      handleInputChange,
      handleInputKeyDown,
    } = useSongRename({ clip, editable, source: 'remasterItem' });

    const getPlaybackTime = useCallback(() => {
      return getCurrentProgress() * (clip.metadata?.duration ?? 0);
    }, [getCurrentProgress, clip.metadata?.duration]);

    const setPlaybackTime = useCallback(
      (time: number) => {
        setCurrentProgress(
          (clip.metadata?.duration ?? 0) > 0
            ? Math.max(0, Math.min(1, time / (clip.metadata?.duration ?? 0)))
            : 0
        );
      },
      [setCurrentProgress, clip.metadata?.duration]
    );

    // Store current timestamp when playing
    useEffect(() => {
      if (isPlaying) {
        const interval = setInterval(() => {
          sharedTimestampRef.current = getPlaybackTime();
        }, 100);
        return () => clearInterval(interval);
      }
    }, [isPlaying, getPlaybackTime, sharedTimestampRef]);

    // Restore timestamp when clip changes
    useEffect(() => {
      if (sharedTimestampRef.current > 0 && clip.metadata?.duration) {
        setPlaybackTime(sharedTimestampRef.current);
      }
    }, [clip.id, setPlaybackTime, clip.metadata?.duration, sharedTimestampRef]);

    const handleToggle = useCallback(() => {
      if (isPlaying) {
        onPlayClick();
      } else {
        onPlayClick();
      }
    }, [isPlaying, onPlayClick]);

    const handleKeyDown = useCallback(
      (e: React.KeyboardEvent) => {
        if (e.key === 'Enter' || e.key === ' ') {
          e.preventDefault();
          handleToggle();
        }
      },
      [handleToggle]
    );

    const handleExpandKeyDown = useCallback(
      (e: React.KeyboardEvent) => {
        // Don't handle keyboard events when editing
        if (isEditing) return;

        if (e.key === 'Enter' || e.key === ' ') {
          e.preventDefault();
          setIsExpanded(!isExpanded);
        }
      },
      [isExpanded, isEditing]
    );

    const handleRowClick = useCallback(() => {
      // Don't expand/collapse when editing
      if (isEditing) return;
      setIsExpanded(!isExpanded);
    }, [isExpanded, isEditing]);

    return (
      <div className='flex flex-col gap-2'>
        <div
          className='flex cursor-pointer items-center gap-3 rounded-lg bg-background-fog-thin p-3 transition-colors hover:bg-background-fog-thick'
          onClick={handleRowClick}
          onKeyDown={handleExpandKeyDown}
          role='button'
          tabIndex={0}
          aria-label={
            isExpanded ? 'Collapse audio display' : 'Expand audio display'
          }
        >
          <div className='flex flex-1 items-center gap-3'>
            <SongArtworkContainer
              onClick={(e) => {
                e.stopPropagation();
                handleToggle();
              }}
              onKeyDown={handleKeyDown}
              role='button'
              tabIndex={0}
              aria-label={isPlaying ? 'Pause audio' : 'Play audio'}
            >
              <ImageWithFallback
                src={clip.image_url ?? ''}
                alt={getClipTitle(clip)}
                imageSize={SMALL_IMAGE}
                className='h-full w-full bg-background-primary object-cover'
                style={{ borderRadius: 'var(--border-radius)' }}
              />
              <SongPlayIcon>
                {['streaming', 'complete'].includes(clip?.status ?? '') ? (
                  isPlaying ? (
                    <PauseIcon />
                  ) : (
                    <PlayIcon />
                  )
                ) : (
                  <SpinnerSVG className='h-3 w-3' />
                )}
              </SongPlayIcon>
            </SongArtworkContainer>
            <SongTextWrapper>
              {isEditing && (
                <HiddenTextMeasure ref={measureRef}>
                  {editedTitle}
                </HiddenTextMeasure>
              )}
              {isEditing ? (
                <div className='flex items-center gap-[1px]'>
                  <TitleInput
                    ref={inputRef}
                    value={editedTitle}
                    onChange={handleInputChange}
                    onKeyDown={handleInputKeyDown}
                    onClick={(e) => e.stopPropagation()}
                    onMouseDown={(e) => e.stopPropagation()}
                    maxLength={MAX_TITLE_CHARS}
                    disabled={isSaving}
                  />
                  <EditActionButton
                    type='button'
                    onClick={handleSave}
                    onMouseDown={(e) => e.stopPropagation()}
                    aria-label='Save title'
                    disabled={isSaving}
                  >
                    {isSaving ? (
                      <SpinnerSVG className='h-3 w-3' />
                    ) : (
                      <CheckIcon className='h-3 w-3' />
                    )}
                  </EditActionButton>
                  <EditActionButton
                    type='button'
                    onClick={handleCancel}
                    onMouseDown={(e) => e.stopPropagation()}
                    aria-label='Cancel editing'
                    disabled={isSaving}
                  >
                    <CloseIcon className='h-3 w-3' />
                  </EditActionButton>
                </div>
              ) : (
                <TitleEditWrapper editable={editable}>
                  <SongTitle>
                    <Link
                      href={`/song/${clip.id}`}
                      target={pathname === '/studio' ? '_blank' : undefined}
                      onClick={(e) => e.stopPropagation()}
                      className='hover:underline'
                    >
                      {getClipTitle(clip)}
                    </Link>
                  </SongTitle>
                  {editable && (
                    <Tooltip label='Edit title'>
                      <EditButton
                        type='button'
                        className='edit-icon-wrapper'
                        onClick={handleEditClick}
                        onMouseDown={(e) => e.stopPropagation()}
                        aria-label='Edit title'
                      >
                        <EditIcon className='h-4 w-4' />
                      </EditButton>
                    </Tooltip>
                  )}
                </TitleEditWrapper>
              )}
              <SongTimeReadout>
                <TimeReadout
                  leftAlign
                  getCurrentTime={getPlaybackTime}
                  songEndSeconds={clip.metadata?.duration ?? 0}
                />
              </SongTimeReadout>
              {/* Model and variation info */}
              {(clip.model_name || clip.metadata?.variation_category) && (
                <div className='mt-1 flex items-center gap-2 text-xs text-foreground-tertiary'>
                  {clip.model_name && (
                    <span className='rounded-md bg-background-fog-thick px-2 py-0.5'>
                      {clip.model_name}
                      {clip.major_model_version &&
                        ` ${clip.major_model_version}`}
                    </span>
                  )}
                  {clip.metadata?.variation_category && (
                    <span className='rounded-md bg-background-fog-thick px-2 py-0.5'>
                      {clip.metadata.variation_category
                        .charAt(0)
                        .toUpperCase() +
                        clip.metadata.variation_category.slice(1)}{' '}
                      Strength
                    </span>
                  )}
                </div>
              )}
            </SongTextWrapper>
          </div>
          <div className='flex items-center gap-2'>
            <Button
              disabled={!clip?.audio_url}
              shape={ButtonShape.Pill}
              icon={<ThumbsUpIcon className='h-4 w-4' />}
              className={`${
                isLiked(clip) ? 'animate-[small-bounce_0.25s_ease-in-out]' : ''
              }`}
              onClick={(e) => {
                e.stopPropagation();
                withWebUserEvent(
                  {
                    actionName: 'RemasterLikeClicked',
                    principalObjectValue: clip?.id || '',
                    principalObjectType: 'song',
                    context: {
                      likeStatus: !isLiked(clip),
                    },
                  },
                  () => setClipLiked(clip.id, !isLiked(clip))
                )(e);
              }}
              variant={
                isLiked(clip) ? ButtonVariant.Primary : ButtonVariant.Standard
              }
              aria-label='Like clip'
            />
            <Button
              disabled={!clip?.audio_url}
              shape={ButtonShape.Pill}
              icon={<ThumbsDownIcon className='h-4 w-4' />}
              onClick={(e) => {
                e.stopPropagation();
                withWebUserEvent(
                  {
                    actionName: 'RemasterDislikeClicked',
                    principalObjectValue: clip?.id || '',
                    principalObjectType: 'song',
                    context: {
                      dislikeStatus: !isDisliked(clip),
                    },
                  },
                  () => setClipDisliked(clip.id, !isDisliked(clip))
                )(e);
              }}
              variant={
                isDisliked(clip)
                  ? ButtonVariant.Primary
                  : ButtonVariant.Standard
              }
              aria-label='Dislike clip'
            />
          </div>
        </div>

        <div
          className='relative overflow-hidden transition-all duration-300 ease-in-out'
          style={{
            maxHeight: isExpanded ? '80px' : '0px',
            opacity: isExpanded ? 1 : 0,
          }}
        >
          {!isLoadedIntoPlayer && sampleAudio !== FALLBACK_SAMPLE_AUDIO && (
            <Button
              onClick={() => onPlayClick()}
              className='absolute top-0 left-0 z-10 flex h-full w-full items-center justify-center bg-background-primary/50'
              icon={<RotateReverseIcon />}
            >
              Listen
            </Button>
          )}
          <CreateAudioDisplay
            isPlaying={isPlaying}
            sampleAudio={sampleAudio}
            getCurrentProgress={() =>
              getPlaybackTime() / (clip.metadata?.duration ?? 1)
            }
            setCurrentProgress={async (progress: number) => {
              setPlaybackTime(progress * (clip.metadata?.duration ?? 0));
            }}
            frameCountRef={frameCountRef}
            height={60}
          />
        </div>
      </div>
    );
  }
);

interface RemasterItemProps {
  clipId: string;
  sharedTimestampRef: React.MutableRefObject<number>;
}

const RemasterItem = observer(
  ({ clipId, sharedTimestampRef }: RemasterItemProps) => {
    const { clip } = useClip(clipId);

    if (!clip) {
      return null;
    }

    return (
      <AutoClipPlaybackProvider clip={clip}>
        <RemasterItemPlayback
          clip={clip}
          sharedTimestampRef={sharedTimestampRef}
        />
      </AutoClipPlaybackProvider>
    );
  }
);

export default RemasterItem;
