import type { Meta, StoryObj } from '@storybook/react';
import { useCallback, useRef, useState } from 'react';

import usePolledValue from '@/hooks/usePolledValue';

import PlaybackProgress, { PlaybackProgressProps } from './PlaybackProgress';

type PagePropsAndCustomArgs = PlaybackProgressProps & {
  startTime?: number;
  isPlaying?: boolean;
};

const meta: Meta<PagePropsAndCustomArgs> = {
  title: 'components/PlaybackProgress',
  component: PlaybackProgress,
};

export default meta;
type Story = StoryObj<PagePropsAndCustomArgs>;

const PlaybackProgressTest = (
  props: PlaybackProgressProps & { startTime?: number; isPlaying?: boolean }
) => {
  const {
    isPlaying = true,
    startTime = 0,
    duration = 60,
    ...restProps
  } = props;

  const [isSeeking, setIsSeeking] = useState(false);
  const stateRef = useRef({
    startTime,
    duration,
  });

  const getCurrentProgress = useCallback(() => {
    const time = (performance.now() - stateRef.current.startTime) / 1000;
    if (time >= duration) {
      stateRef.current.startTime = performance.now();
      return 0;
    }
    return time;
  }, [duration]);

  const [currentTime, updateCurrentProgress] = usePolledValue(
    getCurrentProgress,
    {
      enabled: isPlaying && !isSeeking,
      pollingInterval: 16,
    }
  );

  const handleSeekStart = useCallback(() => {
    setIsSeeking(true);
  }, []);
  const handleSeekEnd = useCallback(() => {
    setIsSeeking(false);
  }, []);
  const handleSeekTo = useCallback(
    (time: number | null) => {
      if (time != null) {
        stateRef.current.startTime = performance.now() - time * 1000;
        updateCurrentProgress();
      }
    },
    [updateCurrentProgress]
  );

  return (
    <div className='fixed inset-0 flex flex-col items-stretch justify-center'>
      <PlaybackProgress
        className='w-full'
        currentTime={currentTime}
        duration={duration}
        onSeekStart={handleSeekStart}
        onSeekEnd={handleSeekEnd}
        onSeekMove={handleSeekTo}
        onSeekTo={handleSeekTo}
        {...restProps}
      />
    </div>
  );
};

export const Default: Story = {
  render: (args) => {
    return <PlaybackProgressTest {...args} />;
  },
  args: {
    isPlaying: false,
    startTime: 50,
    duration: 150,
  },
};

export const Subtle: Story = {
  render: (args) => {
    return <PlaybackProgressTest {...args} />;
  },
  args: {
    className: '[--button-width:0px] [--track-width:2px]',
    isPlaying: false,
    startTime: 50,
    duration: 150,
    showTime: false,
  },
};
