import { createQuery, createInfiniteQuery } from '@tanstack/svelte-query';
import { api } from './client';
import type { ArtistRef, ArtistDetail, AlbumDetail, Page, SearchResponse } from './types';

export type ArtistSort = 'alpha' | 'newest';
export const ARTIST_PAGE_SIZE = 50;
export const SEARCH_SUMMARY_LIMIT = 10;
export const SEARCH_FACET_PAGE_SIZE = 50;

export const qk = {
  artists: (sort: ArtistSort) => ['artists', { sort }] as const,
  artist:  (id: string)       => ['artist', id] as const,
  album:   (id: string)       => ['album', id] as const,
  search:        (q: string) => ['search', { q }] as const,
  searchArtists: (q: string) => ['searchArtists', { q }] as const,
  searchAlbums:  (q: string) => ['searchAlbums',  { q }] as const,
  searchTracks:  (q: string) => ['searchTracks',  { q }] as const,
  likedIds:      ()          => ['likedIds'] as const,
  likedTracks:   ()          => ['likedTracks'] as const,
  likedAlbums:   ()          => ['likedAlbums'] as const,
  likedArtists:  ()          => ['likedArtists'] as const,
  // Lidarr / requests / admin.
  lidarrSearch:          (q: string, kind: string) =>
    ['lidarrSearch', { q, kind }] as const,
  myRequests:            () => ['myRequests'] as const,
  lidarrConfig:          () => ['lidarrConfig'] as const,
  lidarrQualityProfiles:  () => ['lidarrQualityProfiles'] as const,
  lidarrMetadataProfiles: () => ['lidarrMetadataProfiles'] as const,
  lidarrRootFolders:      () => ['lidarrRootFolders'] as const,
  adminRequests:         (status?: string) =>
    ['adminRequests', { status: status ?? 'all' }] as const,
  myQuarantine:           ()              => ['myQuarantine'] as const,
  adminQuarantine:        ()              => ['adminQuarantine'] as const,
  adminQuarantineActions: (limit?: number) =>
    ['adminQuarantineActions', { limit: limit ?? 50 }] as const,
  suggestions:            (limit?: number) =>
    ['suggestions', { limit: limit ?? 12 }] as const,
  home:         ()                 => ['home'] as const,
  albumsAlpha:  ()                 => ['albumsAlpha'] as const,
  artistTracks: (artistId: string) => ['artistTracks', artistId] as const,
  playlists:    ()                 => ['playlists'] as const,
  playlist:     (id: string)       => ['playlist', id] as const,
};

export function createArtistsQuery(sort: ArtistSort) {
  return createInfiniteQuery({
    queryKey: qk.artists(sort),
    queryFn: ({ pageParam = 0 }) =>
      api.get<Page<ArtistRef>>(
        `/api/artists?sort=${sort}&limit=${ARTIST_PAGE_SIZE}&offset=${pageParam}`
      ),
    initialPageParam: 0,
    getNextPageParam: (last) => {
      const loaded = last.offset + last.items.length;
      return loaded >= last.total ? undefined : loaded;
    },
  });
}

export function createArtistQuery(id: string) {
  return createQuery({
    queryKey: qk.artist(id),
    queryFn: () => api.get<ArtistDetail>(`/api/artists/${id}`),
  });
}

export function createAlbumQuery(id: string) {
  return createQuery({
    queryKey: qk.album(id),
    queryFn: () => api.get<AlbumDetail>(`/api/albums/${id}`),
  });
}

export function createSearchQuery(q: string) {
  return createQuery({
    queryKey: qk.search(q),
    queryFn: () =>
      api.get<SearchResponse>(
        `/api/search?q=${encodeURIComponent(q)}&limit=${SEARCH_SUMMARY_LIMIT}`
      ),
    enabled: q.length > 0
  });
}

export function createSearchArtistsInfiniteQuery(q: string) {
  return createInfiniteQuery({
    queryKey: qk.searchArtists(q),
    queryFn: ({ pageParam = 0 }) =>
      api.get<SearchResponse>(
        `/api/search?q=${encodeURIComponent(q)}&limit=${SEARCH_FACET_PAGE_SIZE}&offset=${pageParam}`
      ).then((r) => r.artists),
    initialPageParam: 0,
    getNextPageParam: (last) => {
      const loaded = last.offset + last.items.length;
      return loaded >= last.total ? undefined : loaded;
    },
    enabled: q.length > 0
  });
}

export function createSearchAlbumsInfiniteQuery(q: string) {
  return createInfiniteQuery({
    queryKey: qk.searchAlbums(q),
    queryFn: ({ pageParam = 0 }) =>
      api.get<SearchResponse>(
        `/api/search?q=${encodeURIComponent(q)}&limit=${SEARCH_FACET_PAGE_SIZE}&offset=${pageParam}`
      ).then((r) => r.albums),
    initialPageParam: 0,
    getNextPageParam: (last) => {
      const loaded = last.offset + last.items.length;
      return loaded >= last.total ? undefined : loaded;
    },
    enabled: q.length > 0
  });
}

export function createSearchTracksInfiniteQuery(q: string) {
  return createInfiniteQuery({
    queryKey: qk.searchTracks(q),
    queryFn: ({ pageParam = 0 }) =>
      api.get<SearchResponse>(
        `/api/search?q=${encodeURIComponent(q)}&limit=${SEARCH_FACET_PAGE_SIZE}&offset=${pageParam}`
      ).then((r) => r.tracks),
    initialPageParam: 0,
    getNextPageParam: (last) => {
      const loaded = last.offset + last.items.length;
      return loaded >= last.total ? undefined : loaded;
    },
    enabled: q.length > 0
  });
}
