import React, {
  useEffect,
  useRef,
  useState,
} from 'react';

import {
  MdPauseCircle,
  MdPlayCircle,
} from 'react-icons/md';

interface AudioMessageProps {
  src: string;
  barsCount?: number;
  cacheKey?: string;
}

const barsCache = new Map<string, number[]>();

const generateBars = (barsCount: number) => {
  const bars: number[] = [];
  const baseHeight = 25;
  const variation = 10;

  let last = baseHeight;

  for (let i = 0; i < barsCount; i++) {
    const delta = (Math.random() - 0.5) * variation;
    const next = Math.max(10, Math.min(50, last + delta));

    bars.push(Math.round(next));
    last = next;
  }

  return bars;
};

const AudioMessage: React.FC<AudioMessageProps> = ({ src, barsCount = 30, cacheKey }) => {
  const audioRef = useRef<HTMLAudioElement>(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const [progress, setProgress] = useState(0);
  const [duration, setDuration] = useState(0);
  const [barHeights, setBarHeights] = useState<number[]>([]);


  useEffect(() => {
    const resolvedCacheKey = cacheKey ?? src;
    const cachedBars = barsCache.get(resolvedCacheKey);

    if (cachedBars && cachedBars.length === barsCount) {
      setBarHeights(cachedBars);
      return;
    }

    const nextBars = generateBars(barsCount);
    barsCache.set(resolvedCacheKey, nextBars);
    setBarHeights(nextBars);
  }, [barsCount, cacheKey, src]);

  useEffect(() => {
    const audio = audioRef.current;
    if (!audio) return;

    const updateProgress = () => {
      if (audio.duration) {
        setProgress((audio.currentTime / audio.duration) * 100);
      }
    };

    const setDur = () => {
      setDuration(audio.duration || 0);
    };

    audio.addEventListener('timeupdate', updateProgress);
    audio.addEventListener('loadedmetadata', setDur);
    audio.addEventListener('ended', () => setIsPlaying(false));

    return () => {
      audio.removeEventListener('timeupdate', updateProgress);
      audio.removeEventListener('loadedmetadata', setDur);
    };
  }, []);

  const togglePlay = () => {
    const audio = audioRef.current;
    if (!audio) return;

    if (isPlaying) {
      audio.pause();
    } else {
      audio.play();
    }

    setIsPlaying(!isPlaying);
  };

  const handleBarClick = (index: number) => {
    const audio = audioRef.current;
    if (!audio || !duration) return;

    const time = (index / barHeights.length) * duration;
    audio.currentTime = time;
  };

  const currentBar = Math.floor((progress / 100) * barHeights.length);

  return (
    <div className="flex items-end  mt-4" onClick={(e) => {
      e.preventDefault();
      e.stopPropagation();
    }}>
      <audio ref={audioRef} src={src} preload="metadata" />
      <div>
        <div onClick={(e) => {
          e.preventDefault();
          e.stopPropagation();
          togglePlay();
        }} className='mr-1' >
          {isPlaying ? <MdPauseCircle size={28} /> : <MdPlayCircle size={28} />}
        </div>
      </div>
      <div className="flex items-end space-x-1 flex-1  cursor-pointer overflow-hidden">
        {barHeights.map((height, i) => (
          <div
            key={i}
            onClick={(e) => {
              e.preventDefault();
              e.stopPropagation();
              handleBarClick(i);
            }}
            className={`w-[2px] rounded-sm transition-colors duration-200 bg-black dark:bg-white ${i <= currentBar ? 'opacity-100' : 'opacity-50'
              }`}
            style={{ height: `${height}px` }}
          />
        ))}
      </div>
    </div>
  );
};

export default AudioMessage;