import { useSearchParams } from 'react-router';
import { Loader2 } from 'lucide-react';
import { MediaGrid } from './MediaCard';
import { VIEW_PARAM } from './shared';
import { useJellyfinItems, useJellyfinViews } from './useJellyfinData';

// One library, as a grid.
//
// Which library is `?view=<id>`; the sort is `?sort=` and `?order=`. All three are in the URL rather than in
// component state so a particular view of a particular library is a link you can keep — and so the nav can
// tell which library is open without either panel talking to the other.

const SORTS = [
  { id: 'SortName', label: 'Name' },
  { id: 'DateCreated', label: 'Recently added' },
  { id: 'PremiereDate', label: 'Release date' },
  { id: 'CommunityRating', label: 'Rating' },
  { id: 'Random', label: 'Random' },
] as const;

const SORT_PARAM = 'sort';
const ORDER_PARAM = 'order';

// A show is a Series, not its episodes: a tvshows library browsed recursively for Episode would be thousands
// of tiles of the same six posters. BoxSets are collapsed for the same reason.
const TYPES_FOR_COLLECTION: Record<string, string> = {
  movies: 'Movie',
  tvshows: 'Series',
  homevideos: 'Video,Photo',
  musicvideos: 'MusicVideo',
  boxsets: 'BoxSet',
  playlists: 'Playlist',
};

const CHIP = 'rounded-md px-2 py-1 text-[11px] transition-colors';

export const LibrarySection = () => {
  const [params, setParams] = useSearchParams();
  const viewId = params.get(VIEW_PARAM);
  const sortBy = params.get(SORT_PARAM) ?? 'SortName';
  const sortOrder = params.get(ORDER_PARAM) === 'Descending' ? 'Descending' : 'Ascending';

  const { data: viewData } = useJellyfinViews();
  const view = viewData?.views.find((v) => v.Id === viewId) ?? null;

  const { data, isLoading } = useJellyfinItems(
    {
      parentId: viewId ?? undefined,
      includeItemTypes: TYPES_FOR_COLLECTION[view?.CollectionType ?? ''] ?? undefined,
      sortBy,
      sortOrder,
      limit: 500,
      collapseBoxSetItems: false,
    },
    !!viewId,
  );

  if (!viewId) {
    return (
      <div className="flex h-full items-center justify-center p-6 text-center text-xs text-muted-foreground">
        Pick a library on the left.
      </div>
    );
  }

  const items = data?.Items ?? [];
  const wide = view?.CollectionType === 'homevideos';

  const setSort = (id: string) => {
    const next = new URLSearchParams(params);
    // Clicking the sort you are already on flips the direction, which is the behaviour every table has and
    // saves a second control that would only ever be used with this one.
    if (id === sortBy) next.set(ORDER_PARAM, sortOrder === 'Ascending' ? 'Descending' : 'Ascending');
    else next.delete(ORDER_PARAM);
    next.set(SORT_PARAM, id);
    setParams(next, { replace: true });
  };

  return (
    <div className="flex h-full flex-col">
      <div className="flex items-center gap-2 border-b px-4 py-2">
        <h2 className="truncate text-sm font-semibold">{view?.Name ?? 'Library'}</h2>
        <span className="text-[11px] text-muted-foreground">
          {data?.TotalRecordCount != null ? `${data.TotalRecordCount.toLocaleString()} items` : ''}
        </span>
        <div className="ml-auto flex items-center gap-0.5 rounded-lg bg-muted p-0.5">
          {SORTS.map((sort) => (
            <button
              key={sort.id}
              type="button"
              onClick={() => setSort(sort.id)}
              className={`${CHIP} ${sortBy === sort.id ? 'bg-background shadow-sm' : 'text-muted-foreground'}`}
            >
              {sort.label}
              {sortBy === sort.id && sort.id !== 'Random' ? (sortOrder === 'Ascending' ? ' ↑' : ' ↓') : ''}
            </button>
          ))}
        </div>
      </div>

      <div className="flex-1 overflow-y-auto p-4">
        {isLoading ? (
          <div className="flex h-full items-center justify-center text-muted-foreground">
            <Loader2 className="h-5 w-5 animate-spin" />
          </div>
        ) : items.length ? (
          <MediaGrid items={items} wide={wide} />
        ) : (
          <p className="pt-10 text-center text-xs text-muted-foreground">This library is empty.</p>
        )}
      </div>
    </div>
  );
};
