import styled from '@emotion/styled';
import { observer } from 'mobx-react-lite';
import { useCallback, useMemo, useRef } from 'react';

import Button, { ButtonShape, ButtonVariant } from '@/components/button/Button';
import { ClipContextProvider } from '@/components/clipBrowser/ClipContext';
import {
  AutoClipPlaybackProvider,
  useClipPlaybackContext,
} from '@/components/clipBrowser/useClipPlayback';
import useClip from '@/hooks/useClip';
import { useContextSelector } from '@/hooks/useContextSelector';
import { CloseIcon } from '@/icons';
import { Clip } from '@/state/clipStore';
import { getClipTitle } from '@/utils/clip';

import CreateFormContext from '../../v2/CreateFormContext';
import changeClipConditionType from '../../v2/actions/changeClipConditionType';
import {
  ClipConditionTypes,
  ConditionTypes,
  ReuseStylesLyricsCondition,
  TimedCondition,
  TimedConditionTypes,
} from '../../v2/types';
import { mapConditionTypeToAddConditionType } from '../../v2/utils/mapConditionType';
import { ClipConditionTypePicker } from './ClipConditionTypePicker';
import CreateAudioDisplay from './CreateAudioDisplay';
import CreateCard from './CreateCard';
import { SongMeta } from './common';
import { useUrlAudioSampler } from './useUrlAudioSampler';

const ContentWrapper = styled.div`
  padding: 0 16px 16px 16px;
`;

const ReuseStylesLyricsCard = ({
  clipTitle,
  clipArtworkUrl,
  clipDurationSeconds,
  isPlaying,
  play,
  pause,
  getCurrentProgress,
  setCurrentProgress,
  sampleAudio,
  frameCountRef,
  onClear,
  conditionType,
  changeConditionType,
}: {
  clipTitle: string;
  clipArtworkUrl: string;
  clipDurationSeconds: number;
  isPlaying: boolean;
  play: () => void;
  pause: () => void;
  getCurrentProgress: () => number;
  setCurrentProgress: (progress: number) => void;
  sampleAudio: (progress: number) => number;
  frameCountRef?: React.RefObject<number>;
  onClear: () => void;
  conditionType: ClipConditionTypes;
  changeConditionType: (type: ClipConditionTypes) => void;
}) => {
  const getPlaybackTime = useCallback(
    () => getCurrentProgress() * clipDurationSeconds,
    [getCurrentProgress, clipDurationSeconds]
  );

  return (
    <CreateCard
      title={
        <SongMeta
          title={clipTitle}
          artworkUrl={clipArtworkUrl}
          duration={clipDurationSeconds}
          getPlaybackTime={getPlaybackTime}
          isPlaying={isPlaying}
          play={play}
          pause={pause}
        />
      }
      headerContent={
        <>
          <ClipConditionTypePicker
            conditionType={conditionType}
            changeConditionType={changeConditionType}
          />

          <Button
            shape={ButtonShape.Pill}
            icon={<CloseIcon />}
            aria-label='Clear reuse styles and lyrics'
            variant={ButtonVariant.Tertiary}
            onClick={onClear}
          />
        </>
      }
    >
      <ContentWrapper>
        <CreateAudioDisplay
          isPlaying={isPlaying}
          sampleAudio={sampleAudio}
          getCurrentProgress={() => getCurrentProgress()}
          setCurrentProgress={(progress) => setCurrentProgress(progress)}
          frameCountRef={frameCountRef}
        />
      </ContentWrapper>
    </CreateCard>
  );
};

const PlayableReuseStylesLyricsCard = ({
  clip,
  conditionType,
  onClear,
}: {
  clip: Clip;
  conditionType: ClipConditionTypes;
  onClear: () => void;
}) => {
  const { isPlaying, onPlayClick, getCurrentProgress, setCurrentProgress } =
    useClipPlaybackContext();
  const sampleAudio = useUrlAudioSampler(clip?.id, clip?.status);
  const frameCountRef = useRef<number>(0);
  const setState = useContextSelector(
    CreateFormContext,
    (context) => context.setState
  );

  const addCondition = useContextSelector(
    CreateFormContext,
    (context) => context.addCondition
  );

  const changeConditionType = useCallback(
    (newType: ClipConditionTypes) => {
      const addConditionType = mapConditionTypeToAddConditionType(newType);

      if (addConditionType) {
        // Use unified addCondition with replacement
        addCondition(clip.id, addConditionType, conditionType);
      } else {
        // Fall back to old method for unsupported types
        setState(changeClipConditionType(conditionType, newType, clip));
      }
    },
    [setState, clip, conditionType, addCondition]
  );

  return (
    <ReuseStylesLyricsCard
      clipTitle={getClipTitle(clip)}
      clipArtworkUrl={clip.image_url ?? ''}
      clipDurationSeconds={clip.metadata?.duration ?? 0}
      isPlaying={isPlaying}
      play={onPlayClick}
      pause={onPlayClick}
      getCurrentProgress={getCurrentProgress}
      setCurrentProgress={setCurrentProgress}
      sampleAudio={sampleAudio}
      frameCountRef={frameCountRef}
      onClear={onClear}
      conditionType={conditionType}
      changeConditionType={changeConditionType}
    />
  );
};

const CreateReuseStylesLyricsCard = observer(() => {
  const [timedCondition, setTimedCondition] = useContextSelector(
    CreateFormContext,
    (context) => {
      return context.selectState<TimedCondition<TimedConditionTypes> | null>([
        'global',
        'timedCondition',
      ]);
    }
  );

  const reuseStylesLyricsCondition = useMemo(() => {
    return timedCondition?.type === ConditionTypes.REUSE_STYLES_LYRICS
      ? (timedCondition.condition as ReuseStylesLyricsCondition)
      : null;
  }, [timedCondition]);

  const { clip } = useClip(reuseStylesLyricsCondition?.clipId);

  const handleClear = useCallback(() => {
    setTimedCondition(null);
  }, [setTimedCondition]);

  return (
    reuseStylesLyricsCondition &&
    clip && (
      <AutoClipPlaybackProvider clip={clip} studioPreviewsWithContextWindow>
        <ClipContextProvider clip={clip}>
          <PlayableReuseStylesLyricsCard
            clip={clip}
            conditionType={ConditionTypes.REUSE_STYLES_LYRICS}
            onClear={handleClear}
          />
        </ClipContextProvider>
      </AutoClipPlaybackProvider>
    )
  );
});

export default CreateReuseStylesLyricsCard;
