import type { Meta, StoryObj } from '@storybook/react';
import { clamp } from 'lodash-es';
import { useCallback, useState } from 'react';

import PlaybackProgressHoverOverlay from '../mediaPlayback/PlaybackProgressHoverOverlay';
import Filmstrip from './Filmstrip';
import LinesWaveform from './LinesWaveform';
import Trimmer, { TrimmerProps } from './Trimmer';

type PagePropsAndCustomArgs = TrimmerProps;

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

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

function useTrimmerState(
  initialState: Pick<
    TrimmerProps,
    'start' | 'end' | 'duration' | 'viewportStart' | 'viewportEnd' | 'current'
  >
) {
  const [state, setState] = useState(initialState);
  const handleRangeSet = useCallback(
    (start: number, end: number) => {
      setState((prevState) => ({
        ...prevState,
        start: clamp(start, 0, state.duration ?? Infinity),
        end: clamp(end, 0, state.duration ?? Infinity),
      }));
    },
    [state.duration]
  );
  const handleViewportSet = useCallback(
    (viewportStart: number, viewportEnd: number) => {
      setState((prevState) => ({
        ...prevState,
        viewportStart,
        viewportEnd,
      }));
    },
    []
  );
  const handleCurrentTimeSet = useCallback(
    (value: number) => {
      setState((prevState) => ({
        ...prevState,
        current: Math.max(0, Math.min(value, state.duration ?? Infinity)),
      }));
    },
    [state.duration]
  );
  return {
    ...state,
    onRangeSet: handleRangeSet,
    onViewportSet: handleViewportSet,
    onCurrentTimeSet: handleCurrentTimeSet,
  };
}

function RangeTrimmerDemo(props: TrimmerProps) {
  const {
    start,
    end,
    duration,
    viewportStart,
    viewportEnd,
    current,
    ...restProps
  } = props;

  const { onViewportSet, ...trimmerProps } = useTrimmerState({
    start,
    end,
    duration,
    viewportStart,
    viewportEnd,
    current,
  });

  return (
    <Trimmer {...trimmerProps} {...restProps}>
      <Filmstrip
        className='absolute inset-0'
        src='/filmstrip-test.png'
        thumbnailColumns={5}
        thumbnailWidth={1000 / 5}
        thumbnailHeight={600 / 2}
        thumbnailCount={9}
      />
    </Trimmer>
  );
}

export const RangeTrimmer: Story = {
  render: (args) => <RangeTrimmerDemo {...args} />,
  args: {
    contentClassName: 'bg-background-secondary',
    start: 40,
    end: 60,
    duration: 100,
  },
};

function DragContentDemo(props: TrimmerProps) {
  const {
    start,
    end,
    duration,
    viewportStart,
    viewportEnd,
    current,
    ...restProps
  } = props;

  const trimmerProps = useTrimmerState({
    start,
    end,
    duration,
    viewportStart,
    viewportEnd,
    current,
  });

  return (
    <Trimmer {...trimmerProps} {...restProps}>
      <LinesWaveform
        className='absolute inset-0 mask-(--trimmer-mask)'
        src='https://cdn1.suno.ai/ee0ed97e-0c06-4f6d-9ef0-bc3d5f2e9c02.mp3'
      />
    </Trimmer>
  );
}

export const DragContent: Story = {
  render: (args) => <DragContentDemo {...args} />,
  args: {
    disableHandles: true,
    className: '[--trimmer-padding:2rem] absolute inset-x-0 top-4',
    contentWrapperClassName: 'rounded-none',
    contentClassName: 'bg-background-secondary',
    start: 40,
    end: 60,
    duration: 100,
    viewportStart: 25,
    viewportEnd: 75,
  },
};

function PlayheadDemo(props: TrimmerProps) {
  const {
    start,
    end,
    duration,
    viewportStart,
    viewportEnd,
    current,
    ...restProps
  } = props;

  const trimmerProps = useTrimmerState({
    start,
    end,
    duration,
    viewportStart,
    viewportEnd,
    current,
  });

  return (
    <Trimmer {...trimmerProps} {...restProps}>
      <LinesWaveform
        className='absolute inset-0 mask-(--trimmer-mask)'
        src='https://cdn1.suno.ai/ee0ed97e-0c06-4f6d-9ef0-bc3d5f2e9c02.mp3'
      />
    </Trimmer>
  );
}

export const Playhead: Story = {
  render: (args) => <PlayheadDemo {...args} />,
  args: {
    disableHandles: true,
    // disableRange: true,
    clampPlayheadToRange: true,
    contentClassName: 'bg-background-secondary',
    start: 25,
    end: 75,
    current: 50,
    duration: 100,
  },
};

function RangeTrimmerWithTooltipDemo(props: TrimmerProps) {
  const {
    start,
    end,
    duration,
    viewportStart,
    viewportEnd,
    current,
    ...restProps
  } = props;

  const { onViewportSet, ...trimmerProps } = useTrimmerState({
    start,
    end,
    duration,
    viewportStart,
    viewportEnd,
    current,
  });

  return (
    <Trimmer
      {...trimmerProps}
      renderTooltip={PlaybackProgressHoverOverlay}
      {...restProps}
    >
      <Filmstrip
        className='absolute inset-0'
        src='/filmstrip-test.png'
        thumbnailColumns={5}
        thumbnailWidth={1000 / 5}
        thumbnailHeight={600 / 2}
        thumbnailCount={9}
      />
    </Trimmer>
  );
}

export const RangeTrimmerWithTooltip: Story = {
  render: (args) => <RangeTrimmerWithTooltipDemo {...args} />,
  args: {
    clampPlayheadToRange: true,
    contentClassName: 'bg-background-secondary',
    tooltipClassName: 'bottom-auto top-[calc(1rem+100%)]',
    start: 40,
    end: 60,
    current: 50,
    duration: 100,
  },
};
