import subsonic from '../subsonic/index.js'
import { playTracks } from '../actions/index.js'
const shuffleArray = (array) => {
const shuffled = [...array]
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1))
;[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]
}
return shuffled
}
const mapReplayGain = (song) => {
const { replayGain: rg } = song
if (!rg) {
return song
}
return {
...song,
...(rg.albumGain !== undefined && { rgAlbumGain: rg.albumGain }),
...(rg.albumPeak !== undefined && { rgAlbumPeak: rg.albumPeak }),
...(rg.trackGain !== undefined && { rgTrackGain: rg.trackGain }),
...(rg.trackPeak !== undefined && { rgTrackPeak: rg.trackPeak }),
}
}
export const processSongsForPlayback = (songs) => {
const songData = {}
const ids = []
songs.forEach((s) => {
const song = mapReplayGain(s)
songData[song.id] = song
ids.push(song.id)
})
return { songData, ids }
}
export const playSimilar = async (dispatch, notify, id, options = {}) => {
const { seedRecord = null, shuffle = false } = options
const res = await subsonic.getSimilarSongs2(id, 100)
const data = res.json['subsonic-response']
if (data.status !== 'ok') {
throw new Error(
`Error fetching similar songs: ${data.error?.message || 'Unknown error'} (Code: ${data.error?.code || 'unknown'})`,
)
}
let songs = data.similarSongs2?.song || []
if (shuffle) {
songs = shuffleArray(songs)
}
if (!songs.length && !seedRecord) {
notify('message.noSimilarSongsFound', 'warning')
return
}
const { songData, ids } = processSongsForPlayback(songs)
if (seedRecord) {
const seedId = seedRecord.mediaFileId || seedRecord.id
const filteredIds = ids.filter((songId) => songId !== seedId)
songData[seedId] = mapReplayGain(seedRecord)
dispatch(playTracks(songData, [seedId, ...filteredIds]))
} else {
dispatch(playTracks(songData, ids))
}
}