'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import { alpha, useThemeColor } from '@djangocfg/ui-core/styles/palette';
import { usePlayerAudio, usePlayerControls } from '../../context/selectors';
import { useElementWidth } from '../../hooks/useResizeObserver';
import { usePlayheadLoop } from '../../hooks/usePlayheadLoop';
import { useThemeWatcher } from '../../hooks/useThemeWatcher';
import { attachHover, attachSeek } from './waveformInteraction';
import { paintPeaks } from './waveformRenderer';

type Props = {
  peaks: Float32Array;
  height: number;
  barWidth: number;
  barGap: number;
  seekStartsPlayback?: boolean;
};

export function PeaksWaveform({ peaks, height, barWidth, barGap, seekStartsPlayback }: Props) {
  const audio = usePlayerAudio();
  const controls = usePlayerControls();
  // State-backed ref so child hooks re-run once the DOM node attaches.
  const [container, setContainer] = useState<HTMLDivElement | null>(null);
  const bgCanvasRef = useRef<HTMLCanvasElement | null>(null);
  const fgCanvasRef = useRef<HTMLCanvasElement | null>(null);
  const width = useElementWidth(container);

  const fgHex = useThemeColor('primary');
  const mutedHex = useThemeColor('muted-foreground');

  const repaint = useCallback(() => {
    const bg = bgCanvasRef.current;
    const fg = fgCanvasRef.current;
    if (!bg || !fg) return;
    paintPeaks(bg, peaks, { color: alpha(mutedHex, 0.4), barWidth, barGap, minBarHeight: 1 });
    paintPeaks(fg, peaks, { color: fgHex, barWidth, barGap, minBarHeight: 1 });
  }, [peaks, barWidth, barGap, fgHex, mutedHex]);

  useEffect(repaint, [repaint, width]);
  useThemeWatcher(repaint);

  usePlayheadLoop(audio, container, true);

  useEffect(() => {
    if (!container) return;
    const detachSeek = attachSeek(container, audio, {
      startsPlayback: seekStartsPlayback,
      onPlayRequest: () => void controls.play(),
    });
    const detachHover = attachHover(container, audio);
    return () => {
      detachSeek();
      detachHover();
    };
  }, [audio, container, controls, seekStartsPlayback]);

  return (
    <div
      ref={setContainer}
      className="audioplayer-waveform relative w-full select-none cursor-pointer"
      style={{ height, ['--p' as string]: '0%' }}
      data-mode="peaks"
    >
      <canvas ref={bgCanvasRef} className="absolute inset-0 h-full w-full" aria-hidden="true" />
      <div
        className="audioplayer-fg-clip absolute inset-0"
        style={{
          clipPath: 'polygon(0 0, var(--p) 0, var(--p) 100%, 0 100%)',
          willChange: 'clip-path',
        }}
      >
        <canvas ref={fgCanvasRef} className="absolute inset-0 h-full w-full" aria-hidden="true" />
      </div>
      <div
        className="audioplayer-cursor pointer-events-none absolute top-0 bottom-0 w-px"
        style={{ left: 'var(--p)', backgroundColor: alpha(fgHex, 0.7) }}
        aria-hidden="true"
      />
      <div
        className="audioplayer-hover pointer-events-none absolute top-0 bottom-0 w-px transition-opacity"
        style={{
          left: 'var(--hp, -10px)',
          opacity: 'var(--ho, 0)',
          backgroundColor: alpha(mutedHex, 0.5),
        }}
        aria-hidden="true"
      />
      <div
        data-audioplayer-time-tip
        className="audioplayer-tip pointer-events-none absolute -top-7 -translate-x-1/2 rounded bg-foreground px-1.5 py-0.5 text-[10px] tabular-nums text-background transition-opacity"
        style={{
          left: 'var(--hp, -100px)',
          opacity: 'var(--ht, 0)',
        }}
        aria-hidden="true"
      />
    </div>
  );
}
