import { useMemo } from 'react'
import { useNamedPlaylist, usePlaylistAdd, usePlaylistItems, usePlaylistRemove } from './use-jellyfin'
import { getPlaylistItemId } from '../lib/item-types'

const WATCHLIST_NAME = 'Watchlist'

/**
 * Backed by a user-private Jellyfin playlist named "Watchlist". Created
 * lazily the first time the user adds something. Server-side state
 * means the watchlist follows the user across devices.
 *
 * Returns the playlist id, the item-id set for fast `isInWatchlist`
 * checks, and toggle / add / remove mutations.
 */
export function useWatchlist() {
  const playlist = useNamedPlaylist(WATCHLIST_NAME)
  const playlistId = playlist.data?.Id || undefined
  const items = usePlaylistItems(playlistId)
  const add = usePlaylistAdd(playlistId)
  const remove = usePlaylistRemove(playlistId)

  const idSet = useMemo(() => {
    const s = new Set<string>()
    for (const it of items.data || []) {
      if (it.Id) s.add(it.Id)
    }
    return s
  }, [items.data])

  // Map item-id -> PlaylistItemId so we can call removeItemFromPlaylist
  // (which needs the entry id, not the item id).
  const entryByItemId = useMemo(() => {
    const m = new Map<string, string>()
    for (const it of items.data || []) {
      const itemId = it.Id
      const entryId = getPlaylistItemId(it)
      if (itemId && entryId) m.set(itemId, entryId)
    }
    return m
  }, [items.data])

  function isInWatchlist(itemId: string | null | undefined) {
    return !!itemId && idSet.has(itemId)
  }

  async function toggle(itemId: string | null | undefined) {
    if (!itemId) return
    if (idSet.has(itemId)) {
      const entry = entryByItemId.get(itemId)
      if (entry) await remove.mutateAsync([entry])
    } else {
      await add.mutateAsync([itemId])
    }
  }

  return {
    playlistId,
    items: items.data || [],
    idSet,
    isInWatchlist,
    toggle,
    addToWatchlist: (id: string) => add.mutateAsync([id]),
    removeFromWatchlist: (id: string) => {
      const entry = entryByItemId.get(id)
      if (entry) return remove.mutateAsync([entry])
    },
    isLoading: playlist.isLoading || items.isLoading,
  }
}
