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

import { Media } from '@/back-api';
import { useServiceContext } from '@/service/ServiceContext';
import { MediaServiceProps } from './Media';

export type PlaylistElement = {
  MediaId: number;
};

export type ActivePlaylistServiceProps = {
  playMediaList: number[];
  MediaOffset?: number;
  MediaActive?: Media;
  setNewPlaylist: (listIds: number[]) => void;
  setNewPlaylistShuffle: (listIds: number[]) => void;
  playInList: (id: number | undefined, listIds: number[]) => void;
  play: (id: number) => void;
  previous: () => void;
  next: () => void;
  first: () => void;
  clear: () => 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 = (
  Media: MediaServiceProps
): ActivePlaylistServiceProps => {
  const [playMediaList, setPlayMediaList] = useState<number[]>([]);
  const [MediaOffset, setMediaOffset] = useState<number | undefined>();
  const MediaActive = useMemo(() => {
    return Media.store.get(MediaOffset !== undefined ? playMediaList[MediaOffset] : undefined);
  }, [Media.store.data, playMediaList, MediaOffset]);

  const clear = useCallback(() => {
    setPlayMediaList([]);
    setMediaOffset(undefined);
  }, [setPlayMediaList, setMediaOffset]);

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

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

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


  return {
    playMediaList,
    MediaOffset,
    setNewPlaylist,
    setNewPlaylistShuffle,
    playInList,
    play,
    previous,
    next,
    MediaActive,
    first,
    clear,
  };
};
