/* eslint jsx-a11y/no-static-element-interactions: warn */
import clsx from 'clsx';
import { observer } from 'mobx-react-lite';
import {
  RefObject,
  useCallback,
  useContext,
  useEffect,
  useRef,
  useState,
} from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import CloseButton from '@/components/button/CloseButton';
import ImageWithFallback from '@/components/image/ImageWithFallback';
import D3Waveform from '@/components/playbar/D3Waveform';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import ArtistTag from '@/components/tag/ArtistTag';
import useClip from '@/hooks/useClip';
import { PauseIcon, PlayIcon } from '@/icons';
import { Clip } from '@/state/clipStore';
import { AudioUploadStatus } from '@/state/createV2Store';
import { getClipTitle } from '@/utils/clip';
import { decodeTimeFormat, encodeTimeFormat } from '@/utils/utils';

import UploadStateContext from '../uploaderV2/UploadStateContext';
import CreateCard from './componentsQ3/CreateCard';

type Props = {
  clip: Clip;
  ref?: RefObject<any>;
  index?: number;
  feature?: 'extend' | 'cover' | 'reuse_prompt' | 'adjust_speed';
};

export const CreateAudioUpload = () => {
  const { uploadStatus, isUploadInProgress, setPendingClipContext } =
    useContext(UploadStateContext);

  return (
    <>
      {uploadStatus !== null &&
      uploadStatus !== AudioUploadStatus.CANCELLED &&
      !isUploadInProgress ? (
        <CreateCard>
          <AudioUpload onCancel={() => setPendingClipContext(null)} />
        </CreateCard>
      ) : null}
    </>
  );
};

export const AudioUpload = ({ onCancel }: { onCancel?: () => void }) => {
  const { uploadStatus, setUploadStatus, pendingClipContext } =
    useContext(UploadStateContext);
  const [progress, setProgress] = useState(0); // Use state, not ref
  const clearUploadStatusTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  const pendingClip = useClip(pendingClipContext?.clipId ?? '');

  useEffect(() => {
    const clearUploadStatus = () => setUploadStatus(null);

    if (
      uploadStatus &&
      [AudioUploadStatus.COMPLETE, AudioUploadStatus.INVALID_UPLOAD].includes(
        uploadStatus
      )
    ) {
      if (clearUploadStatusTimeoutRef.current) {
        clearTimeout(clearUploadStatusTimeoutRef.current);
      }

      clearUploadStatusTimeoutRef.current = setTimeout(clearUploadStatus, 500);
    }

    return () => {
      if (clearUploadStatusTimeoutRef.current) {
        clearTimeout(clearUploadStatusTimeoutRef.current);
      }
    };
  }, [uploadStatus, setUploadStatus]);

  useEffect(() => {
    if (
      [
        AudioUploadStatus.UPLOADING,
        AudioUploadStatus.INITIALIZING,
        AudioUploadStatus.COMPLETE,
      ].includes(uploadStatus as AudioUploadStatus)
    ) {
      const targetProgress =
        uploadStatus === AudioUploadStatus.UPLOADING
          ? 20
          : uploadStatus === AudioUploadStatus.INITIALIZING
            ? 75
            : 100;

      // Small delay to ensure smooth transitions
      const timer = setTimeout(() => {
        setProgress(targetProgress);
      }, 150);

      return () => clearTimeout(timer);
    }
  }, [uploadStatus]);

  return (
    <div className='w-full flex-1'>
      <div className='flex w-full flex-row items-center gap-2 rounded-[20px] p-4'>
        <div className='relative min-h-[60px] min-w-[60px] overflow-hidden rounded-lg'>
          {!!uploadStatus &&
          [
            AudioUploadStatus.UPLOADING,
            AudioUploadStatus.INITIALIZING,
          ].includes(uploadStatus) ? (
            <div className='absolute top-5 left-5'>
              <SpinnerSVG />
            </div>
          ) : null}
          <ImageWithFallback
            alt=''
            className='h-[60px] w-[60px] object-cover'
            src={pendingClip?.clip?.image_url}
          />
        </div>
        <div className='items-left flex w-full max-w-[100px] flex-col'>
          {!!pendingClipContext?.title ? (
            <span className='line-clamp-1 max-w-24 min-w-8 break-all'>
              {pendingClipContext?.title}
            </span>
          ) : null}
          <span className='text-sm text-foreground-secondary'>
            {uploadStatus === AudioUploadStatus.INVALID_UPLOAD
              ? 'Uploading Clip'
              : uploadStatus === AudioUploadStatus.COMPLETE
                ? 'Uploaded'
                : uploadStatus === AudioUploadStatus.INITIALIZING
                  ? 'Initializing'
                  : uploadStatus === AudioUploadStatus.UPLOADING
                    ? 'Uploading Clip'
                    : 'Uploaded'}
          </span>
        </div>
        <div className='h-4 w-full overflow-hidden rounded-full bg-background-fog-thick'>
          <div
            className={clsx(
              'h-full bg-accent-pink transition-all duration-1000 ease-out' // Changed from ease-in-out to ease-out
            )}
            style={{
              width: `${progress}%`,
            }}
          />
        </div>
        <Button
          variant={ButtonVariant.Standard}
          shape={ButtonShape.Pill}
          size={ButtonSize.Small}
          className='bg-background-fog-thin'
          onClick={() => {
            setUploadStatus(AudioUploadStatus.CANCELLED);
            if (!!onCancel) {
              onCancel();
            }
          }}
        >
          Cancel
        </Button>
      </div>
    </div>
  );
};

export const ReferenceSong = observer(
  ({ clip, ref }: Pick<Props, 'clip' | 'ref'>) => {
    const { genForm, createV2, session } = useStores();
    if (!clip) {
      return null;
    }
    return (
      <div className='flex w-full flex-1 flex-col' ref={ref}>
        <div className='h-auto w-auto rounded-[20px] bg-background-secondary p-4 py-2'>
          <div className='flex w-full flex-col gap-2'>
            <div className='flex w-full flex-row items-center'>
              <span className=''>Cover Song</span>
              <div className='flex flex-1 flex-row-reverse'>
                <CloseButton
                  variant={ButtonVariant.Glass}
                  size={ButtonSize.Small}
                  shape={ButtonShape.Rounded}
                  iconClassName='w-5 h-5'
                  className={'bg-transparent'}
                  onClick={() => {
                    if (createV2.coverExtendMode === 'cover_extend') {
                      createV2.setCoverExtendMode('extend');
                      genForm.resetCoverClip();
                    } else {
                      genForm.resetRemixClipConditions();
                      genForm.setIsRemixCreate(false);
                    }
                    if (createV2.activeTitle.endsWith(' (Cover)')) {
                      createV2.setActiveTitle(
                        createV2.activeTitle.replace(' (Cover)', '')
                      );
                    }
                  }}
                />
              </div>
            </div>
            <div className='flex flex-row items-center gap-2'>
              <ImageWithFallback
                src={clip?.image_url}
                className='h-[77px] w-[56px] rounded-[20px] object-cover'
                alt={`Image for ${getClipTitle(clip)}`}
              />
              <div className='flex flex-1 flex-col'>
                <span className='ml-2 line-clamp-1 flex-1 text-xl'>
                  {getClipTitle(clip)}
                </span>
                <div className='ml-1'>
                  {session.userId === clip.user_id ? (
                    <span className='ml-1 line-clamp-1 text-sm text-foreground-secondary-on-light'>
                      {clip.metadata?.tags || '(no style)'}
                    </span>
                  ) : (
                    <ArtistTag
                      handle={clip.handle || ''}
                      displayName={clip.display_name}
                    />
                  )}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
);

export const AudioSection = observer(({ clip, ref, index, feature }: Props) => {
  const { clips, genForm, createV2, playbar, session } = useStores();
  const continueClipContainerRef = useRef<any>(null);
  const [width, setWidth] = useState<number | null>(null);

  const updateContinueAt = useCallback(
    (continueAt: number) => {
      if (
        clip &&
        genForm.continueClipDuration &&
        continueAt > 1 &&
        continueAt <= genForm.continueClipDuration
      ) {
        genForm.setContinueAtSeconds(continueAt);
        createV2.setActiveContinueAtSeconds(encodeTimeFormat(continueAt));
      }
    },
    [clip, createV2, genForm]
  );

  useEffect(() => {
    if (!continueClipContainerRef.current) return;
    const resizeObserver = new ResizeObserver(() => {
      setWidth(continueClipContainerRef.current.getBoundingClientRect().width);
    });
    resizeObserver.observe(continueClipContainerRef.current);
    return () => {
      resizeObserver.disconnect();
    };
  }, [continueClipContainerRef]);

  if (!clip) {
    return null;
  }

  return (
    <div className='flex w-full flex-1 flex-col' ref={ref}>
      <div className='mb-4 h-auto min-h-[160px] w-auto rounded-[20px] bg-background-secondary p-4'>
        <div className='flex w-full flex-col gap-2'>
          <div className='flex flex-row items-center gap-2'>
            <ImageWithFallback
              src={clip?.image_url}
              className='object-fit h-[77px] w-[56px] rounded-xl'
              alt={`Image for ${getClipTitle(clip)}`}
            />
            <div className='flex flex-1 flex-col'>
              <span className='ml-2 line-clamp-1 flex-1 text-xl'>
                {getClipTitle(clip)}
              </span>
              <div className='ml-1'>
                {session.userId === clip.user_id ? (
                  <span className='ml-1 line-clamp-1 text-sm text-foreground-secondary-on-light'>
                    {clip.metadata?.tags || '(no style)'}
                  </span>
                ) : (
                  <ArtistTag
                    handle={clip.handle || ''}
                    displayName={clip.display_name}
                  />
                )}
              </div>
            </div>

            <div className='flex h-[60px] flex-col justify-start'>
              <CloseButton
                variant={ButtonVariant.Glass}
                size={ButtonSize.Small}
                shape={ButtonShape.Rounded}
                iconClassName='w-5 h-5'
                className={'bg-transparent'}
                onClick={() => {
                  if (createV2.coverExtendMode === 'cover_extend') {
                    if (feature === 'extend') {
                      createV2.setCoverExtendMode('cover');
                      genForm.resetContinueClip();
                    } else {
                      createV2.setCoverExtendMode('extend');
                      genForm.resetCoverClip();
                    }
                  } else {
                    genForm.resetRemixClipConditions();
                    genForm.setIsRemixCreate(false);
                  }
                  if (
                    feature === 'cover' &&
                    createV2.activeTitle.endsWith(' (Cover)')
                  ) {
                    createV2.setActiveTitle(
                      createV2.activeTitle.replace(' (Cover)', '')
                    );
                  }
                }}
              />
            </div>
          </div>
          {feature === 'extend' ? (
            <div className='flex flex-row items-center'>
              <span className='flex-1'>
                Select time to extend your clip from
              </span>
              <input
                className={clsx(
                  'h-8 w-20 rounded-md border border-white/10 bg-transparent py-[20px] pl-2 outline-none'
                )}
                value={
                  createV2.activeContinueAtSeconds !== null &&
                  createV2.activeContinueAtSeconds !== ''
                    ? createV2.activeContinueAtSeconds
                    : encodeTimeFormat(genForm.continueClipDuration) || ''
                }
                type='text'
                onKeyDown={(e) => {
                  if (e.key === 'Enter') {
                    const decodedTime = decodeTimeFormat(
                      createV2.activeContinueAtSeconds || ''
                    );
                    if (
                      decodedTime !== null &&
                      decodedTime > 0 &&
                      decodedTime <= (genForm.continueClipDuration || 0)
                    ) {
                      genForm.setContinueAtSeconds(decodedTime);
                    } else {
                      createV2.setActiveContinueAtSeconds(
                        encodeTimeFormat(genForm.continueClipDuration)
                      );
                    }
                  }
                }}
                onBlur={() => {
                  const decodedTime = decodeTimeFormat(
                    createV2.activeContinueAtSeconds || ''
                  );
                  if (
                    decodedTime !== null &&
                    decodedTime > 0 &&
                    decodedTime <= (genForm.continueClipDuration || 0)
                  ) {
                    updateContinueAt(decodedTime);
                  } else {
                    createV2.setActiveContinueAtSeconds(
                      encodeTimeFormat(genForm.continueClipDuration)
                    );
                  }
                }}
                onChange={(e) => {
                  createV2.setActiveContinueAtSeconds(e.target.value);
                }}
              ></input>
            </div>
          ) : null}

          <div className='flex flex-row items-center'>
            <div className='relative h-[60px] w-[60px]'>
              {/* <ImageWithFallback
                  src={clip?.image_url}
                  width={80}
                  className='rounded-lg absolute top-0 left-0 brightness-50 h-full'
                  alt={`Image for ${getClipTitle(clip)}`}
                /> */}
              <Button
                className='absolute top-0 left-0 border-0 bg-background-fog-thin before:border-0'
                shape={ButtonShape.Rounded}
                size={ButtonSize.Medium}
                iconClassName='w-8 h-8'
                icon={
                  playbar.clip?.id === clip?.id && playbar.isPlaying
                    ? PauseIcon
                    : PlayIcon
                }
                variant={ButtonVariant.Standard}
                onClick={() => {
                  if (playbar.clip?.id === clip?.id) {
                    playbar.togglePlay();
                  } else {
                    playbar.playClip(clip);
                  }
                }}
              />
            </div>
            <div
              className='relative ml-4 h-[60px] flex-1 overflow-hidden rounded-xl border border-white/5 bg-white/5 py-1'
              ref={continueClipContainerRef}
            >
              {!!clip ? (
                <>
                  <D3Waveform
                    index={index}
                    height={50}
                    fillColor={'rgba(255,255,255,0.6)'}
                    strokeColor={'rgba(0,0,0,0.1)'}
                    className='py-0'
                    clip={clip}
                    setWaveformStartInput={() => {}}
                    setWaveformEndInput={() => {}}
                    startPosition={parseInt(
                      createV2.activeContinueAtSeconds || '0'
                    )}
                    endPosition={null}
                    setStartPosition={(position: number | null) => {
                      if (position === null) {
                        return;
                      }
                      createV2.setActiveContinueAtSeconds(
                        position?.toString() || null
                      );
                    }}
                    setEndPosition={() => {}}
                  />
                </>
              ) : null}
              {!!clips.pregenWaveformByClipId[clip.id] ? (
                <>
                  <div
                    onMouseDown={(e) => {
                      e.stopPropagation();
                      if (!continueClipContainerRef.current) {
                        return;
                      }
                      if (feature === 'extend') {
                        createV2.setIsDraggingContinueAtSeconds(true);
                        createV2.setDraggingContinueAtSecondsStartPosition(
                          e.clientX
                        );
                      }
                    }}
                    onMouseUp={(e) => {
                      if (
                        !createV2.hasDraggedContinueAtSeconds ||
                        feature !== 'extend'
                      ) {
                        const percent =
                          (e.clientX -
                            continueClipContainerRef.current.getBoundingClientRect()
                              .left) /
                          (width ||
                            continueClipContainerRef.current.getBoundingClientRect()
                              .width);
                        if (playbar.clip?.id === clip?.id) {
                          playbar.userSetCurrentProgress(percent * 100);
                        } else {
                          playbar.playClip(
                            clip,
                            undefined,
                            undefined,
                            false,
                            (clip?.metadata?.duration || 0) * percent
                          );
                        }
                      }
                      createV2.setIsDraggingContinueAtSeconds(false);
                      createV2.setHasDraggedContinueAtSeconds(false);
                      createV2.setDraggingContinueAtSecondsStartPosition(null);
                      e.stopPropagation();
                    }}
                    onMouseLeave={() => {
                      createV2.setIsDraggingContinueAtSeconds(false);
                    }}
                    onMouseMove={(e) => {
                      e.stopPropagation();
                      if (!continueClipContainerRef.current) {
                        return;
                      }
                      if (
                        createV2.isDraggingContinueAtSeconds &&
                        (Math.abs(
                          e.clientX -
                            (createV2.draggingContinueAtSecondsStartPosition ||
                              0)
                        ) > 10 ||
                          createV2.hasDraggedContinueAtSeconds)
                      ) {
                        createV2.setHasDraggedContinueAtSeconds(true);
                        const percent =
                          (e.clientX -
                            continueClipContainerRef.current.getBoundingClientRect()
                              .left) /
                          (width ||
                            continueClipContainerRef.current.getBoundingClientRect()
                              .width);
                        const continueTimeSecs =
                          (clip?.metadata?.duration || 0) * percent;
                        updateContinueAt(continueTimeSecs);
                      }
                    }}
                    className={clsx(
                      'absolute top-0 left-0 z-80 h-full w-full cursor-e-resize border-primary'
                    )}
                  />
                  <div
                    className='absolute top-0 flex h-full w-[2px] flex-col items-center justify-center bg-white'
                    style={{
                      right:
                        (clip?.metadata?.duration || 0) > 0 &&
                        !!continueClipContainerRef.current
                          ? `${(1.0 - (genForm.continueAtSeconds || 0) / (clip?.metadata?.duration || 0)) * (width || continueClipContainerRef.current.getBoundingClientRect().width)}px`
                          : '0px',
                    }}
                  >
                    <PlayIcon className='relative z-10 ml-2' />
                  </div>
                  <div
                    className={clsx(
                      'pointer-events-none absolute top-0 right-0 h-full bg-[rgba(56,52,53,0.6)]',
                      {
                        hidden: feature !== 'extend',
                      }
                    )}
                    style={{
                      width:
                        (clip?.metadata?.duration || 0) > 0 &&
                        !!continueClipContainerRef.current
                          ? `${(1.0 - (genForm.continueAtSeconds || 0) / (clip?.metadata?.duration || 0)) * (width || continueClipContainerRef.current.getBoundingClientRect().width)}px`
                          : '0px',
                    }}
                  ></div>
                </>
              ) : null}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
});
