import { observer } from 'mobx-react-lite';
import { useEffect, useState } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import Button, { ButtonShape, ButtonVariant } from '@/components/button/Button';
import HorizontalFader from '@/components/edit2025/HorizontalFader';
import { EditUndoIcon } from '@/icons';

import { CreateV2Switch } from './CreateV2Switch';

const SEMITONE_STEPS = [
  0.25, 0.2649, 0.2806, 0.2973, 0.315, 0.3337, 0.3536, 0.3746, 0.3969, 0.4204,
  0.4454, 0.4719, 0.5, 0.5297, 0.5612, 0.5946, 0.63, 0.6674, 0.7071, 0.7492,
  0.7937, 0.8409, 0.8909, 0.9439, 1.0, 1.0595, 1.1225, 1.1892, 1.2599, 1.3348,
  1.4142, 1.4983, 1.5874, 1.6818, 1.7818, 1.8877, 2.0, 2.1189, 2.2449, 2.3784,
  2.5198, 2.6697, 2.8284, 2.9966, 3.1748, 3.3636, 3.5636, 3.7755, 4.0,
];

export default observer(function RemixAdjustSpeed() {
  const { createV2 } = useStores();
  const minMultiplier = 0.25;
  const maxMultiplier = 4.0;

  const [keepPitch, setKeepPitch] = useState(false);
  const [currentMultiplier, setCurrentMultiplier] = useState(1);

  const formatMultiplier = (value: number) => {
    return value.toFixed(2) + 'x';
  };

  const findClosestSemitoneStep = (value: number) => {
    return SEMITONE_STEPS.reduce((prev, curr) => {
      return Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev;
    });
  };

  useEffect(() => {
    createV2.setSpeedMultiplier(currentMultiplier);
    createV2.setKeepPitch(keepPitch);
  }, [currentMultiplier, keepPitch, createV2]);

  const handleReset = () => {
    setCurrentMultiplier(1);
  };

  return (
    <div className='mb-4 flex h-full w-full flex-col'>
      <div className='flex flex-col items-center justify-center gap-2 rounded-2xl bg-tertiary p-5'>
        <div className='rounded-full p-4 font-mono text-2xl font-medium text-foreground-primary'>
          {formatMultiplier(currentMultiplier)}
        </div>

        <div className='h-[40px] w-full'>
          <HorizontalFader
            value={
              currentMultiplier < 1
                ? ((currentMultiplier - minMultiplier) / (1 - minMultiplier)) *
                  0.5
                : 0.5 + ((currentMultiplier - 1) / (maxMultiplier - 1)) * 0.5
            }
            anchorValue={0.5}
            onChange={(value) => {
              value = Math.max(0, Math.min(1, value));

              let newMultiplier;
              if (value < 0.5) {
                newMultiplier =
                  minMultiplier + (value / 0.5) * (1 - minMultiplier);
              } else {
                newMultiplier = 1 + ((value - 0.5) / 0.5) * (maxMultiplier - 1);
              }

              // If Keep Pitch is off, snap to semitone increments
              if (!keepPitch) {
                newMultiplier = findClosestSemitoneStep(newMultiplier);
              } else {
                newMultiplier = Math.round(newMultiplier * 100) / 100;
              }

              newMultiplier = Math.max(
                minMultiplier,
                Math.min(maxMultiplier, newMultiplier)
              );

              setCurrentMultiplier(newMultiplier);
            }}
            onCommit={() => {}}
          />
        </div>

        <div className='flex w-full flex-row justify-between text-sm text-gray-400'>
          <span>{formatMultiplier(minMultiplier)}</span>
          <span>{formatMultiplier(maxMultiplier)}</span>
        </div>

        <div className='mt-4 flex w-full items-center justify-between'>
          <CreateV2Switch
            label='Keep Pitch'
            checked={keepPitch}
            onChange={(checked: boolean) => setKeepPitch(checked)}
          />
          {currentMultiplier !== 1 && (
            <Button
              onClick={handleReset}
              variant={ButtonVariant.Glass}
              shape={ButtonShape.Pill}
              className='py-1.5 text-sm'
              icon={<EditUndoIcon className='h-4 w-4' />}
            >
              Reset
            </Button>
          )}
        </div>
      </div>
    </div>
  );
});
