import { lightLine } from '@/styles/colors';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import generateWaveform, { GenerateWaveformSettings, SymmetryMode, WaveformMode } from './generateWaveform';
import normalizeAudio from './normalizeAudio';

export const TRIM_SECTION_WAVEFORM_PRESET = {
  taper: 0,
  taperCurve: 0.5,
  trimStart: 0,
  trimEnd: 0,
  width: 800,
  height: 70,
  mode: WaveformMode.FullRes,
  barWidth: 1,
  barGap: 0,
  barRounding: 0,
  minThickness: 1,
  symmetryMode: SymmetryMode.Asymmetrical,
  backgroundColor: 'transparent',
  foregroundColor: lightLine,
};

export const presets = [
  {
    name: 'WavTool (DAW)',
    settings: {
      foregroundColor: '#B7C6EB',
      backgroundColor: '#49505E',
      taper: 0,
      taperCurve: 0.5,
      trimStart: 0,
      trimEnd: 0,
      width: 800,
      height: 80,
      mode: WaveformMode.FullRes,
      barWidth: 1,
      barGap: 0,
      barRounding: 0,
      minThickness: 1,
      symmetryMode: SymmetryMode.Asymmetrical,
    },
  },
  {
    name: 'WavTool (Player)',
    settings: {
      foregroundColor: '#17706C',
      backgroundColor: '#F1F1F1',
      taper: 0,
      taperCurve: 0.5,
      trimStart: 0,
      trimEnd: 0,
      width: 800,
      height: 250,
      mode: WaveformMode.Bars,
      barWidth: 2,
      barGap: 0,
      barRounding: 0,
      minThickness: 1,
      symmetryMode: SymmetryMode.Symmetrical,
    },
  },
  {
    name: 'Ableton',
    settings: {
      foregroundColor: '#231417',
      backgroundColor: '#B4B4B4',
      taper: 0,
      taperCurve: 0.5,
      trimStart: 0,
      trimEnd: 0,
      width: 800,
      height: 80,
      mode: WaveformMode.FullRes,
      barWidth: 1,
      barGap: 0,
      barRounding: 0,
      minThickness: 1,
      symmetryMode: SymmetryMode.Unlocked,
    },
  },
  {
    name: 'BandLab',
    settings: {
      backgroundColor: '#1A797F',
      foregroundColor: '#00C6D1',
      taper: 0,
      taperCurve: 0.5,
      trimStart: 0,
      trimEnd: 0,
      width: 600,
      height: 60,
      mode: WaveformMode.FullRes,
      barWidth: 1,
      barGap: 0,
      barRounding: 0,
      minThickness: 1,
      symmetryMode: SymmetryMode.Symmetrical,
    },
  },
  {
    name: 'SoundTrap',
    settings: {
      foregroundColor: '#B890BF',
      backgroundColor: '#6C2276',
      taper: 0,
      taperCurve: 0.5,
      trimStart: 0,
      trimEnd: 0,
      width: 500,
      height: 50,
      mode: WaveformMode.Bars,
      barWidth: 3,
      barGap: 3,
      barRounding: 1,
      minThickness: 1,
      symmetryMode: SymmetryMode.Symmetrical,
    },
  },
  {
    name: 'Voice Memos',
    settings: {
      foregroundColor: '#FA4334',
      backgroundColor: '#19191C',
      taper: 0,
      taperCurve: 0.5,
      trimStart: 0,
      trimEnd: 0,
      width: 500,
      height: 50,
      mode: WaveformMode.Bars,
      barWidth: 2,
      barGap: 6,
      barRounding: 1,
      minThickness: 1,
      symmetryMode: SymmetryMode.Symmetrical,
    },
  },
  {
    name: 'SoundCloud',
    settings: {
      foregroundColor: '#8C8C8C',
      backgroundColor: '#ffffff',
      taper: 0,
      taperCurve: 0.5,
      trimStart: 0,
      trimEnd: 0,
      width: 800,
      height: 70,
      mode: WaveformMode.Bars,
      barWidth: 3,
      barGap: 0.5,
      barRounding: 0,
      minThickness: 1,
      symmetryMode: SymmetryMode.OneHalf,
    },
  },
] as {
  name: string;
  settings: GenerateWaveformSettings;
}[];

const useWaveformStateManagement = (watermarked: boolean) => {
  const [audio, setAudio] = useState<AudioBuffer | null>(null);
  const [waveformSettings, setWaveformSettings] = useState(presets[0].settings);
  const hasSetInitialSizeRef = useRef(false);

  useEffect(() => {
    if (!hasSetInitialSizeRef.current) {
      hasSetInitialSizeRef.current = true;
      setWaveformSettings((prev) => ({
        ...prev,
        width: Math.min(window.innerWidth - 2, 800),
        height: window.innerHeight < 750 ? 100 : 200,
      }));
    }
  }, []);

  const loadPreset = useCallback((preset: GenerateWaveformSettings) => {
    setWaveformSettings((prev) => ({
      ...prev,
      mode: preset.mode,
      barWidth: preset.barWidth,
      barGap: preset.barGap,
      barRounding: preset.barRounding,
      minThickness: preset.minThickness,
      symmetryMode: preset.symmetryMode,
      foregroundColor: preset.foregroundColor,
      backgroundColor: preset.backgroundColor,
    }));
  }, []);

  const hasSetInitialPresetRef = useRef(false);
  useEffect(() => {
    if (!hasSetInitialPresetRef.current) {
      hasSetInitialPresetRef.current = true;
      loadPreset(presets[0].settings);
    }
  }, []);

  const firstChannelNormalized = useMemo(() => {
    if (!audio) return null;
    return normalizeAudio(audio.getChannelData(0));
  }, [audio]);

  const getSVG = useCallback(
    (skipBackground?: boolean) => {
      if (!firstChannelNormalized) return '';
      return generateWaveform(
        firstChannelNormalized,
        watermarked,
        skipBackground ? { ...waveformSettings, backgroundColor: 'transparent' } : waveformSettings
      )!;
    },
    [firstChannelNormalized, waveformSettings, watermarked]
  );

  const getPresetActive = useCallback(
    (preset: GenerateWaveformSettings) => {
      return (
        preset.mode === waveformSettings.mode &&
        preset.barWidth === waveformSettings.barWidth &&
        preset.barGap === waveformSettings.barGap &&
        preset.barRounding === waveformSettings.barRounding &&
        preset.minThickness === waveformSettings.minThickness &&
        preset.symmetryMode === waveformSettings.symmetryMode &&
        preset.foregroundColor === waveformSettings.foregroundColor &&
        preset.backgroundColor === waveformSettings.backgroundColor
      );
    },
    [waveformSettings]
  );

  return {
    getPresetActive,
    getSVG,
    waveformSettings,
    setWaveformSettings,
    audio,
    firstChannelNormalized,
    setAudio,
    loadPreset,
  };
};

export default useWaveformStateManagement;
