import 'react-jinke-music-player/assets/index.css'
import get from 'lodash.get'
import { v4 as uuidv4 } from 'uuid'
import subsonic from '../subsonic'
import config from '../config'

import {
  PLAYER_CLEAR_QUEUE,
  PLAYER_SET_VOLUME,
  PLAYER_CURRENT,
  PLAYER_ADD_TRACKS,
  PLAYER_PLAY_NEXT,
  PLAYER_SET_TRACK,
  PLAYER_SYNC_QUEUE,
  PLAYER_SCROBBLE,
  PLAYER_PLAY_TRACKS,
} from '../actions'

const mapToAudioLists = (item) => {
  // If item comes from a playlist, id is mediaFileId
  const id = item.mediaFileId || item.id
  return {
    trackId: id,
    name: item.title,
    singer: item.artist,
    album: item.album,
    albumId: item.albumId,
    artistId: item.albumArtistId,
    duration: item.duration,
    musicSrc: subsonic.url('stream', id, { ts: true }),
    cover: subsonic.url(
      'getCoverArt',
      config.devFastAccessCoverArt ? item.albumId : id,
      { size: 300 }
    ),
    scrobbled: false,
    uuid: uuidv4(),
  }
}

const initialState = {
  queue: [],
  clear: true,
  current: {},
  volume: 1,
  playIndex: 0,
}

export const playQueueReducer = (previousState = initialState, payload) => {
  let queue, current
  let newQueue
  const { type, data } = payload
  switch (type) {
    case PLAYER_CLEAR_QUEUE:
      return initialState
    case PLAYER_SET_VOLUME:
      return {
        ...previousState,
        playIndex: undefined,
        volume: data.volume,
      }
    case PLAYER_CURRENT:
      queue = previousState.queue
      current = data.ended
        ? {}
        : {
            trackId: data.trackId,
            uuid: data.uuid,
            paused: data.paused,
          }
      return {
        ...previousState,
        current,
        playIndex: undefined,
        volume: data.volume,
      }
    case PLAYER_ADD_TRACKS:
      queue = previousState.queue
      Object.keys(data).forEach((id) => {
        queue.push(mapToAudioLists(data[id]))
      })
      return { ...previousState, queue, clear: false, playIndex: undefined }
    case PLAYER_PLAY_NEXT:
      current = get(previousState.current, 'uuid', '')
      newQueue = []
      let foundPos = false
      previousState.queue.forEach((item) => {
        newQueue.push(item)
        if (item.uuid === current) {
          foundPos = true
          Object.keys(data).forEach((id) => {
            newQueue.push(mapToAudioLists(data[id]))
          })
        }
      })
      if (!foundPos) {
        Object.keys(data).forEach((id) => {
          newQueue.push(mapToAudioLists(data[id]))
        })
      }
      return {
        ...previousState,
        queue: newQueue,
        clear: true,
        playIndex: undefined,
      }
    case PLAYER_SET_TRACK:
      return {
        ...previousState,
        queue: [mapToAudioLists(data)],
        clear: true,
        playIndex: 0,
      }
    case PLAYER_SYNC_QUEUE:
      current = data.length > 0 ? previousState.current : {}
      return {
        ...previousState,
        queue: data,
        clear: false,
        playIndex: undefined,
        current,
      }
    case PLAYER_SCROBBLE:
      newQueue = previousState.queue.map((item) => {
        return {
          ...item,
          scrobbled:
            item.scrobbled || (item.trackId === payload.id && payload.submit),
        }
      })
      return {
        ...previousState,
        queue: newQueue,
        playIndex: undefined,
        clear: false,
      }
    case PLAYER_PLAY_TRACKS:
      queue = []
      let match = false
      Object.keys(data).forEach((id) => {
        if (id === payload.id) {
          match = true
        }
        if (match) {
          queue.push(mapToAudioLists(data[id]))
        }
      })
      return {
        ...previousState,
        queue,
        playIndex: 0,
        clear: true,
      }
    default:
      return previousState
  }
}
