import { useCallback, useMemo, useState } from 'react';

import { useServiceContext } from '@/service/ServiceContext';
import { TrackServiceProps } from './Track';
import { Track } from '@/back-api';

export type PlaylistElement = {
  trackId: number;
};

export type ActivePlaylistServiceProps = {
  playTrackList: number[];
  trackOffset?: number;
  trackActive?: Track;
  setNewPlaylist: (listIds: number[]) => void;
  setNewPlaylistShuffle: (listIds: number[]) => void;
  playInList: (id: number, listIds: number[]) => void;
  play: (id: number) => void;
  previous: () => void;
  next: () => void;
  first: () => void;
};

export const useActivePlaylistService = (): ActivePlaylistServiceProps => {
  const { activePlaylist } = useServiceContext();
  return activePlaylist;
};

export function localShuffle<T>(array: T[]): T[] {
  let currentIndex = array.length,
    randomIndex;
  // While there remain elements to shuffle.
  while (currentIndex != 0) {
    // Pick a remaining element.
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex--;
    // And swap it with the current element.
    [array[currentIndex], array[randomIndex]] = [
      array[randomIndex],
      array[currentIndex],
    ];
  }
  return array;
}

export const useActivePlaylistServiceWrapped = (
  track: TrackServiceProps
): ActivePlaylistServiceProps => {
  const [playTrackList, setPlayTrackList] = useState<number[]>([]);
  const [trackOffset, setTrackOffset] = useState<number | undefined>();
  const trackActive = useMemo(() => {
    return track.store.get(trackOffset !== undefined ? playTrackList[trackOffset] : undefined);
  }, [track.store.data, playTrackList, trackOffset]);

  const clear = useCallback(() => {
    setPlayTrackList([]);
    setTrackOffset(undefined);
  }, [setPlayTrackList, setTrackOffset]);

  const play = useCallback(
    (id: number) => {
      setPlayTrackList([id]);
      setTrackOffset(0);
    },
    [setPlayTrackList, setTrackOffset]
  );
  const playInList = useCallback(
    (id: number, listIds: number[]) => {
      console.log(`Request paly in list: ${id} in ${listIds}`);
      setPlayTrackList(listIds);
      setTrackOffset(id);
    },
    [setPlayTrackList, setTrackOffset]
  );

  const setNewPlaylist = useCallback(
    (listIds: number[]) => {
      if (listIds.length == 0) {
        clear();
        return;
      }
      setPlayTrackList(listIds);
      setTrackOffset(0);
    },
    [setPlayTrackList, setTrackOffset, clear]
  );

  const setNewPlaylistShuffle = useCallback(
    (listIds: number[]) => {
      if (listIds.length == 0) {
        clear();
        return;
      }
      const newList = localShuffle(listIds);
      setPlayTrackList(newList);
      setTrackOffset(0);
    },
    [setPlayTrackList, setTrackOffset, clear]
  );
  const previous = useCallback(() => {
    setTrackOffset((previous) => {
      if (previous === undefined) {
        return previous;
      }
      if (previous === 0) {
        return previous;
      }
      return previous - 1;
    });
  }, [setTrackOffset]);
  const next = useCallback(() => {
    setTrackOffset((previous) => {
      if (previous === undefined || playTrackList.length === 0) {
        return previous;
      }
      if (previous >= playTrackList.length - 1) {
        return previous;
      }
      return previous + 1;
    });
  }, [playTrackList, setTrackOffset]);
  const first = useCallback(() => {
    setTrackOffset((previous) => {
      if (previous === undefined || playTrackList.length === 0) {
        return previous;
      }
      return 0;
    });
  }, [playTrackList, setTrackOffset]);


  return {
    playTrackList,
    trackOffset,
    setNewPlaylist,
    setNewPlaylistShuffle,
    playInList,
    play,
    previous,
    next,
    trackActive,
    first,
  };
};
