import { ReactNode, createContext, useContext, useMemo } from 'react';

import {
  ActivePlaylistServiceProps,
  useActivePlaylistServiceWrapped,
} from '@/service/ActivePlaylist';
import { AlbumServiceProps, useAlbumServiceWrapped } from '@/service/Album';
import { ArtistServiceProps, useArtistServiceWrapped } from '@/service/Artist';
import { useGenderServiceWrapped } from '@/service/Gender';
import { SessionState } from '@/service/SessionState';
import { TrackServiceProps, useTrackServiceWrapped } from '@/service/Track';
import {
  RightPart,
  SessionServiceProps,
  getRestConfig,
  useSessionServiceWrapped,
} from '@/service/session';

export type ServiceContextType = {
  session: SessionServiceProps;
  track: TrackServiceProps;
  artist: ArtistServiceProps;
  album: AlbumServiceProps;
  gender: AlbumServiceProps;
  activePlaylist: ActivePlaylistServiceProps;
};


const emptyStore = {
  data: [],
  isLoading: true,
  get: (_value, _key) => {
    console.error('!!! WTF !!!');
    return undefined;
  },
  gets: (_value, _key) => {
    console.error('!!! WTF !!!');
    return [];
  },
  error: undefined,
  update: (request: Promise<{ id: number; artists: number[]; track?: number | undefined; createdAt?: string | undefined; updatedAt?: string | undefined; deleted?: boolean | undefined; name?: string | undefined; description?: string | undefined; covers?: string[] | undefined; genderId?: number | undefined; albumId?: number | undefined; dataId?: string | undefined; }>, key?: string): void => {
    console.error('!!! WTF !!!');
  },
  remove: (id: number | string, request: Promise<void>, key?: string): void => {
    console.error('!!! WTF !!!');
  }
}

export const ServiceContext = createContext<ServiceContextType>({
  session: {
    setToken: (token: string) => { },
    clearToken: () => { },
    hasReadRight: (part: RightPart) => false,
    hasWriteRight: (part: RightPart) => false,
    state: SessionState.NO_USER,
    getRestConfig: getRestConfig,
  },
  track: {
    store: emptyStore,
  },
  artist: {
    store: emptyStore,
  },
  album: {
    store: emptyStore,
  },
  gender: {
    store: emptyStore,
  },
  activePlaylist: {
    playTrackList: [],
    trackOffset: undefined,
    trackActive: undefined,
    setNewPlaylist: (_listIds: number[]) => {
      console.error('!!! WTF !!!');
    },
    setNewPlaylistShuffle: (_listIds: number[]) => {
      console.error('!!! WTF !!!');
    },
    playInList: (_id: number, _listIds: number[]) => {
      console.error('!!! WTF !!!');
    },
    play: (_id: number) => {
      console.error('!!! WTF !!!');
    },
    previous: () => {
      console.error('!!! WTF !!!');
    },
    next: () => {
      console.error('!!! WTF !!!');
    },
    first: () => {
      console.error('!!! WTF !!!');
    },
  },
});

export const useServiceContext = () => useContext(ServiceContext);

export const ServiceContextProvider = ({
  children,
}: {
  children: ReactNode;
}) => {
  const session = useSessionServiceWrapped();
  const track = useTrackServiceWrapped(session);
  const artist = useArtistServiceWrapped(session);
  const album = useAlbumServiceWrapped(session);
  const gender = useGenderServiceWrapped(session);
  const activePlaylist = useActivePlaylistServiceWrapped(track);
  const contextObjectData = useMemo(
    () => ({
      session,
      track,
      artist,
      album,
      activePlaylist,
      gender,
    }),
    [session, track, artist, album]
  );
  return (
    <ServiceContext.Provider value={contextObjectData}>
      {children}
    </ServiceContext.Provider>
  );
};
