import { useState } from 'react';
import { useQuery, keepPreviousData } from '@tanstack/react-query';
import { Tag, Play, AlertCircle, Music } from 'lucide-react';
import { genreService, GetGenreTracksParams } from '../services/genreService';
import { usePlaybackStore } from '../store/usePlaybackStore';
import { TrackRow } from '../components/TrackRow';
import { BackLink } from '../components/BackLink';
import { Button } from '../components/ethos/Button';
import { PageContainer } from '../components/PageContainer';
import { PageHeader } from '../components/PageHeader';
import { Pagination } from '../components/Pagination';
import { EmptyState } from '../components/EmptyState';
import { SkeletonRows, SkeletonGrid } from '../components/LoadingState';
import type { Genre, Track } from '../types';

const GENRE_TRACKS_PAGE_SIZE = 50;

/**
 * One genre entry. Flat surface, hairline separation, mono count — the previous
 * version painted every card with a hue derived from its name, which turned the
 * page into 40 unrelated colour fields and read as decoration, not information.
 */
function GenreButton({
  genre,
  onSelect,
  primary = false,
}: {
  genre: Genre;
  onSelect: (g: Genre) => void;
  primary?: boolean;
}) {
  return (
    <button
      onClick={() => onSelect(genre)}
      className={`group flex w-full items-center gap-2.5 bg-bg1 px-3 text-left transition-colors hover:bg-surface0 ${
        primary ? 'h-12 rounded-t-lg' : 'h-11'
      }`}
    >
      <Tag size={primary ? 16 : 14} className="flex-none text-muted transition-colors group-hover:text-accent" />
      <span className={`min-w-0 flex-1 truncate ${primary ? 'text-sm font-medium text-text' : 'text-xs text-secondary group-hover:text-text'}`}>
        {genre.name}
      </span>
      <span className="flex-none font-mono text-xs tabular-nums text-machine">
        {(genre.track_count ?? 0).toLocaleString()}
      </span>
    </button>
  );
}

export default function Genres() {
  const [selected, setSelected] = useState<Genre | null>(null);
  const [genrePage, setGenrePage] = useState(0);
  const { setQueue, playTrack } = usePlaybackStore();

  const genresQ = useQuery<Genre[]>({ queryKey: ['genres'], queryFn: () => genreService.listGenres() });

  const params: GetGenreTracksParams = { limit: GENRE_TRACKS_PAGE_SIZE, offset: genrePage * GENRE_TRACKS_PAGE_SIZE };
  const tracksQ = useQuery<Track[]>({
    queryKey: ['genre-tracks', selected?.id, genrePage],
    queryFn: () => genreService.getGenreTracks(selected!.id, params),
    enabled: !!selected,
    placeholderData: keepPreviousData,
  });

  if (selected) {
    const tracks = tracksQ.data ?? [];
    const hasNext = tracks.length === GENRE_TRACKS_PAGE_SIZE;
    return (
      <PageContainer>
        <BackLink to="/genres" label="Genres" />
        <PageHeader
          title={selected.name}
          meta={`${(selected.track_count ?? tracks.length).toLocaleString()} tracks`}
          actions={
            <Button
              variant="primary"
              icon={<Play size={16} fill="currentColor" />}
              onClick={() => { if (tracks.length) { setQueue(tracks); playTrack(tracks[0]); } }}
              disabled={!tracks.length}
            >
              Play all
            </Button>
          }
        />
        {tracksQ.isLoading ? <SkeletonRows count={8} />
          : tracks.length === 0 ? <EmptyState compact icon={<Music size={28} />} title="No tracks in this genre" />
          : (
            <>
              <div className="track-list">{tracks.map((t, i) => <TrackRow key={t.id} track={t} queue={tracks} index={i} />)}</div>
              <Pagination
                page={genrePage}
                hasNext={hasNext}
                isLoading={tracksQ.isPlaceholderData}
                onPrev={() => setGenrePage((p) => Math.max(0, p - 1))}
                onNext={() => setGenrePage((p) => p + 1)}
              />
            </>
          )}
      </PageContainer>
    );
  }

  const genres = genresQ.data ?? [];
  const roots = genres.filter((g) => !g.parent_id);
  const childrenOf = (id: string) => genres.filter((g) => g.parent_id === id);
  const orphans = genres.filter((g) => g.parent_id && !genres.some((p) => p.id === g.parent_id));
  const flat = [...roots.filter((g) => childrenOf(g.id).length === 0), ...orphans];

  return (
    <PageContainer>
      <PageHeader
        title="Genres"
        meta={genres.length ? `${genres.length} genres · ${roots.length} top level` : undefined}
      />
      {genresQ.isLoading ? <SkeletonGrid count={10} />
        : genresQ.isError ? <EmptyState compact icon={<AlertCircle size={28} />} title="Couldn't load genres" subtitle="Something went wrong. Try reloading the page." />
        : !genres.length ? <EmptyState compact icon={<Tag size={28} />} title="No genres yet" subtitle="Genres appear after you scan and enrich your library." />
        : (
          <div className="space-y-4">
            {roots.filter((g) => childrenOf(g.id).length > 0).map((genre) => {
              const subs = childrenOf(genre.id);
              return (
                <section key={genre.id} className="rounded-lg border border-border bg-surface0/40">
                  <GenreButton genre={genre} onSelect={setSelected} primary />
                  {subs.length > 0 && (
                    <div className="grid grid-cols-2 gap-px border-t border-border bg-border/40 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
                      {subs.map((sub) => (
                        <GenreButton key={sub.id} genre={sub} onSelect={setSelected} />
                      ))}
                    </div>
                  )}
                </section>
              );
            })}
            {/* Childless roots + orphans (parent missing from the list) share one grid —
                a section per genre wastes a full row on a single tag. */}
            {flat.length > 0 && (
              <div className="grid grid-cols-2 gap-px overflow-hidden rounded-lg border border-border bg-border/40 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
                {flat.map((genre) => (
                  <GenreButton key={genre.id} genre={genre} onSelect={setSelected} />
                ))}
              </div>
            )}
          </div>
        )}
    </PageContainer>
  );
}
