import styled from '@emotion/styled';
import {
  getWarpBeatsFromSeconds,
  getWarpSecondsFromBeats,
} from '@suno/studiokit/warpUtils';
import { useAnimationFrame } from 'framer-motion';
import { useCallback, useMemo, useRef } from 'react';

import CreateAudioDisplay from '@/app/(root)/create/createV2/componentsQ3/CreateAudioDisplay';
import { useUrlAudioSampler } from '@/app/(root)/create/createV2/componentsQ3/useUrlAudioSampler';
import useClip from '@/hooks/useClip';
import { useContextSelector } from '@/hooks/useContextSelector';
import { PauseIcon, PlayIcon } from '@/icons';
import { getClipTitle } from '@/utils/clip';

import Button, { ButtonShape } from '../button/Button';
import { useStudioClipPlayback } from '../clipBrowser/useClipPlayback';
import TimeReadout from '../edit2025/TimeReadout';
import ImageWithFallback from '../image/ImageWithFallback';
import StudioContext from './StudioContext';
import StudioSongRowWrapper from './StudioSongRowWrapper';
import describeClipAdjustments from './describeClipAdjustments';
import { getDerivedTiming, getFocusedStudioClip } from './selectors';
import { getMaximumKnownClipDuration } from './useFfmpegBufferCache';

const Wrapper = styled.div<{ dark?: boolean }>`
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: stretch;
  background-color: ${({ dark }) =>
    dark
      ? 'var(--color-background-primary)'
      : 'var(--color-background-secondary)'};
  height: 106px;
  border-radius: ${({ dark }) => (dark ? '0' : '8px')};
  border-top: ${({ dark }) =>
    dark ? '1px solid var(--color-border-primary)' : 'none'};
`;

const ClipInfoWrapper = styled.div`
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  border-radius: 16px;
  padding: 8px;
  margin: 2px 2px 0 2px;
  &:hover {
    background-color: var(--color-background-glass-thin);
  }
`;
const ClipPlaybackWrapper = styled.div`
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  padding: 8px;
`;
const ClipTitle = styled.div`
  font-size: 14px;
  color: var(--color-foreground-primary);
`;
const TimeReadoutWrapper = styled.div`
  font-size: 14px;
  opacity: 0.5;
`;
const CanvasWrapper = styled.div`
  width: 100%;
  height: 35px;
  position: relative;
  overflow: hidden;
`;

const FocusOverlay = styled.div`
  position: absolute;
  top: 1px;
  bottom: 1px;
  pointer-events: none;

  &:before {
    content: '';
    position: absolute;
    top: 0;
    left: 100%;
    width: 10000px;
    height: 100%;
    background-color: var(--color-background-primary);
    opacity: 0.5;
  }
  &:after {
    content: '';
    position: absolute;
    top: 0;
    right: 100%;
    width: 10000px;
    height: 100%;
    background-color: var(--color-background-primary);
    opacity: 0.5;
  }
`;

export default function NowPlayingSection({ dark }: { dark?: boolean }) {
  const focusedStudioClip = useContextSelector(StudioContext, (ctx) =>
    getFocusedStudioClip(ctx.heardState)
  );
  const timing = useContextSelector(StudioContext, (ctx) =>
    getDerivedTiming(ctx.heardState)
  );
  const { clip: focusedClip } = useClip(focusedStudioClip?.clipId ?? undefined);
  const { isPlaying, onPlayClick, getCurrentProgress, setCurrentProgress } =
    useStudioClipPlayback(focusedClip ?? null);

  const getFocusedClipCurrentTime = useCallback(() => {
    if (!focusedStudioClip) return 0;
    const currentProgress = getCurrentProgress();
    const contentStartBeats = getWarpBeatsFromSeconds(
      focusedStudioClip.warp,
      0
    );
    const contentEndBeats = getWarpBeatsFromSeconds(
      focusedStudioClip.warp,
      focusedClip ? getMaximumKnownClipDuration(focusedClip) : 0
    );
    const currentBeats =
      contentStartBeats +
      currentProgress * (contentEndBeats - contentStartBeats);
    return getWarpSecondsFromBeats(focusedStudioClip.warp, currentBeats);
  }, [focusedStudioClip, getCurrentProgress]);

  const playheadRef = useRef<HTMLDivElement>(null);

  const adjustments = useMemo(
    () =>
      focusedStudioClip && focusedClip && focusedClip.metadata.duration
        ? describeClipAdjustments(timing, focusedStudioClip, focusedClip)
        : null,
    [focusedStudioClip, focusedClip, timing]
  );

  useAnimationFrame(() => {
    if (playheadRef.current) {
      playheadRef.current.style.left = `${100 * getCurrentProgress()}%`;
    }
  });

  const sampleAudio = useUrlAudioSampler(focusedClip?.id, focusedClip?.status);

  return (
    <Wrapper dark={dark}>
      {focusedClip && focusedStudioClip ? (
        <>
          <StudioSongRowWrapper
            clipId={focusedClip.id}
            bypassIntersectionCheck
            bypassPlaybackAutoScroll
          >
            <ClipInfoWrapper>
              <ImageWithFallback
                src={focusedClip.image_url}
                alt='Song Image'
                style={{
                  height: 40,
                  width: 32,
                  borderRadius: 4,
                  objectFit: 'cover',
                }}
              />
              <div>
                <ClipTitle>{getClipTitle(focusedClip)}</ClipTitle>
                <TimeReadoutWrapper>
                  <TimeReadout
                    songEndSeconds={focusedClip.metadata.duration ?? undefined}
                    getCurrentTime={getFocusedClipCurrentTime}
                  />
                </TimeReadoutWrapper>
              </div>
            </ClipInfoWrapper>
          </StudioSongRowWrapper>
          <ClipPlaybackWrapper>
            <Button
              onClick={onPlayClick}
              shape={ButtonShape.Pill}
              icon={isPlaying ? <PauseIcon /> : <PlayIcon />}
            />
            <CanvasWrapper
              onMouseDown={(e) => {
                e.preventDefault();
                const x =
                  e.clientX - e.currentTarget.getBoundingClientRect().left;
                const width = e.currentTarget.clientWidth;
                const relativeX = x / width;
                setCurrentProgress(relativeX);
              }}
            >
              {sampleAudio && (
                <CreateAudioDisplay
                  height={35}
                  isPlaying={isPlaying}
                  sampleAudio={sampleAudio}
                  getCurrentProgress={getCurrentProgress}
                  setCurrentProgress={setCurrentProgress}
                />
              )}
              {adjustments && focusedClip.metadata.duration && (
                <FocusOverlay
                  style={{
                    left: `${100 * (adjustments.arrangedStartSeconds / focusedClip.metadata.duration)}%`,
                    width: `${100 * (adjustments.arrangementDurationSeconds / focusedClip.metadata.duration)}%`,
                  }}
                />
              )}
            </CanvasWrapper>
          </ClipPlaybackWrapper>
        </>
      ) : (
        <div className='flex h-full items-center justify-center text-center text-foreground-primary opacity-25'>
          Nothing is previewing
        </div>
      )}
    </Wrapper>
  );
}
