import React from 'react';
import {useEvent} from '@hooks/useEvent';
import {AudioAsset, HuDataMember} from '@modules/chats/interfaces';
import {useAudioTrackPlayer} from '@modules/chats/contexts/AudioPlayerContext';
import {useChatFile} from '@modules/chats/hooks';
import {AudioPlayer, MessageItem} from '@modules/chats/components';
import {useCurrentTrack} from '@modules/chats/store/zustand/useTrackStateStore';
import {getUserAvatar} from '@modules/chats/utils';
import {persistedUserId} from '@services/localStorage';

interface Props {
  attachment: AudioAsset;
  preparePlaylist?: (onReady?: () => void) => void;
  messageId: string;
  channel: string;
  senderData: HuDataMember;
}

export function VoiceMessage({
  attachment,
  preparePlaylist,
  messageId,
  channel,
  senderData,
}: Props) {
  const audioPlayerContext = useAudioTrackPlayer();
  const trackId = messageId;
  const currentTrack = useCurrentTrack(trackId);
  const durationInSeconds = attachment.audio_duration_ms
    ? attachment.audio_duration_ms / 1000
    : 0;
  const duration = durationInSeconds || currentTrack.duration;
  const progress = duration ? currentTrack.position / duration : 0;
  const avatar = senderData ? getUserAvatar(senderData) : undefined;

  // Handle case when component is rendered outside AudioPlayerProvider
  const isProviderAvailable =
    audioPlayerContext &&
    typeof audioPlayerContext.initializePlaylist === 'function';

  const {
    currentId = '',
    toggleRate = () => {},
    play = async () => {},
    pause = () => {},
    seekTo = () => {},
    rate = 1,
    state = {isPlaying: false, isLoading: false, isPaused: false},
  } = audioPlayerContext || {};

  const {url, isLoading: isFileLoading} = useChatFile({
    assetId: attachment.id,
    messageId,
    channel,
  });

  const onPlay = () => {
    if (!preparePlaylist) {
      return;
    }
    preparePlaylist(() => {
      play({id: trackId, uri: url});
    });
  };

  // Important!!! use seekTo with these params to prevent multiple tracks dragging the progress
  const onSeek = useEvent((position: number) => {
    seekTo(position, {
      id: trackId,
      duration: duration,
    });
  });

  const isTrackActive = isProviderAvailable ? currentId === trackId : false;
  const isPlaying = isTrackActive && state.isPlaying;
  const isPaused = isTrackActive && state.isPaused;
  const isLoading = isFileLoading || (state.isLoading ?? false);

  return (
    <AudioPlayer
      isPlaying={isPlaying}
      isLoading={isLoading}
      isPaused={isPaused}
      avatar={avatar}
      rate={rate}
      duration={duration}
      progress={progress}
      onToggleRate={toggleRate}
      onPause={pause}
      onPlay={onPlay}
      onSeek={onSeek}
      // If the sender isn't the current user, show the avatar on the right side
      rowReverse={senderData.id !== persistedUserId}>
      <MessageItem.Footer />
    </AudioPlayer>
  );
}
