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

import { useStores } from '@/app/(root)/AppProviders';
import { toast } from '@/components/toast/Toast';
import snap from '@/utils/snap';
import { sleep } from '@/utils/utils';

import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '../button/Button';
import SwitchButton from '../button/SwitchButton';
import EditModeContext from './EditModeContext';
import HorizontalFader from './HorizontalFader';
import PreviewClipContext from './PreviewClipContext';
import SelectionContext from './SelectionContext';

const MultiplierReadout = styled.h4`
  font-family:
    'PP Editorial New', 'Editorial New', ui-serif, Georgia, Cambria,
    'Times New Roman';
  font-weight: 400;
  font-size: 60px;
`;

const FaderWrapper = styled.div`
  width: 300px;
  height: 40px;
`;

const Wrapper = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 100%;
`;

const ButtonWrapper = styled.div`
  display: flex;
  flex-direction: row;
  gap: 10px;
`;

export default observer(function EditSpeed({ clipId }: { clipId: string }) {
  const minExp = -2;
  const maxExp = 2;
  const { edit } = useStores();
  const [keepPitch, setKeepPitch] = useState(false);
  const [currentMultiplier, setCurrentMultiplier] = useState(1);
  const { selectionStartSeconds, selectionEndSeconds } =
    useContext(SelectionContext);

  const { setLastAppliedEditType } = useContext(EditModeContext);
  const { applying, setApplying } = useContext(PreviewClipContext);

  const handleApplySpeed = useCallback(async () => {
    setLastAppliedEditType('speed');
    setApplying(true);
    try {
      const response = await edit.apiClient.POST('/api/edit/speed/{clip_id}/', {
        params: {
          path: {
            clip_id: clipId,
          },
        },
        body: {
          speed_factor: currentMultiplier,
          tempo_only: keepPitch,
          change_speed_start_time: selectionStartSeconds,
          change_speed_end_time: selectionEndSeconds,
          edit_session_id: edit.editSessionId,
        },
      });

      if (response.data?.action_clip_id) {
        await sleep(6000);
        window.history.pushState(
          {},
          '',
          `/edit-legacy/${response.data.action_clip_id}`
        );
      } else {
        throw new Error('No action clip ID returned');
      }
    } catch (e) {
      toast({
        title: 'Speed Error',
        description: `Please try again later, or contact us if this problem persists.`,
        status: 'error',
        duration: 5000,
        isClosable: true,
      });
    } finally {
      setApplying(false);
    }
  }, [
    keepPitch,
    currentMultiplier,
    setApplying,
    selectionStartSeconds,
    selectionEndSeconds,
    edit.editSessionId,
    setLastAppliedEditType,
  ]);

  return (
    <Wrapper>
      <MultiplierReadout>{currentMultiplier.toFixed(2)}x</MultiplierReadout>
      <FaderWrapper>
        <HorizontalFader
          value={(Math.log2(currentMultiplier) - minExp) / (maxExp - minExp)}
          anchorValue={0.5}
          onChange={(value) =>
            setCurrentMultiplier(
              snap(Math.pow(2, minExp + value * (maxExp - minExp)), 0.05)
            )
          }
          onCommit={() => {}}
        />
      </FaderWrapper>
      <ButtonWrapper>
        <Button
          className='w-10 px-0'
          onClick={() => setCurrentMultiplier(0.25)}
          variant={ButtonVariant.Secondary}
          shape={ButtonShape.Pill}
        >
          .25
        </Button>
        <Button
          className='w-10 px-0'
          onClick={() => setCurrentMultiplier(0.5)}
          variant={ButtonVariant.Secondary}
          shape={ButtonShape.Pill}
        >
          .5
        </Button>
        <Button
          className='w-10 px-0'
          onClick={() => setCurrentMultiplier(0.75)}
          variant={ButtonVariant.Secondary}
          shape={ButtonShape.Pill}
        >
          .75
        </Button>
        <Button
          className='w-10 px-0'
          onClick={() => setCurrentMultiplier(1)}
          variant={ButtonVariant.Secondary}
          shape={ButtonShape.Pill}
        >
          1
        </Button>
        <Button
          className='w-10 px-0'
          onClick={() => setCurrentMultiplier(1.5)}
          variant={ButtonVariant.Secondary}
          shape={ButtonShape.Pill}
        >
          1.5
        </Button>
        <Button
          className='w-10 px-0'
          onClick={() => setCurrentMultiplier(2)}
          variant={ButtonVariant.Secondary}
          shape={ButtonShape.Pill}
        >
          2
        </Button>
        <Button
          className='w-10 px-0'
          onClick={() => setCurrentMultiplier(4)}
          variant={ButtonVariant.Secondary}
          shape={ButtonShape.Pill}
        >
          4
        </Button>
      </ButtonWrapper>
      <SwitchButton
        buttonText='Keep Pitch'
        onChange={() => setKeepPitch(!keepPitch)}
        checked={keepPitch}
      />
      <Button
        disabled={applying}
        variant={ButtonVariant.Aura}
        size={ButtonSize.Large}
        className='mt-8 w-[350px]'
        onClick={() => handleApplySpeed()}
      >
        Apply
      </Button>
    </Wrapper>
  );
});
