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 { Pagination } from '../components/Pagination';
import { EmptyState } from '../components/EmptyState';
import { SkeletonRows, SkeletonGrid } from '../components/LoadingState';
import { hueFromString } from '../lib/color';
import type { Genre, Track } from '../types';

const GENRE_TRACKS_PAGE_SIZE = 50;

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" />
        <div className="flex items-center justify-between">
          <h1 className="flex items-center gap-3 text-3xl font-bold text-text"><Tag size={28} className="text-accent" />{selected.name}</h1>
          <Button
            variant="primary"
            icon={<Play size={16} fill="currentColor" />}
            onClick={() => { if (tracks.length) { setQueue(tracks); playTrack(tracks[0]); } }}
            disabled={!tracks.length}
          >
            Play all
          </Button>
        </div>
        {tracksQ.isLoading ? <SkeletonRows count={8} />
          : tracks.length === 0 ? <EmptyState compact icon={<Music size={28} />} title="No tracks in this genre" />
          : (
            <>
              <div className="space-y-1">{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);

  return (
    <PageContainer>
      <h1 className="flex items-center gap-3 text-3xl font-bold text-text"><Tag size={28} className="text-accent" />Genres</h1>
      {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-6">
            {roots.map((genre) => {
              const hue = hueFromString(genre.name);
              const subs = childrenOf(genre.id);
              return (
                <div key={genre.id} className="space-y-2">
                  <button onClick={() => setSelected(genre)}
                    className="group flex items-center gap-3 rounded-xl border border-border/70 p-4 w-full text-left transition-colors hover:border-accent/40"
                    style={{ background: `linear-gradient(135deg, hsl(${hue},40%,15%), hsl(${(hue+60)%360},30%,10%))` }}>
                    <Tag size={20} className="text-muted group-hover:text-accent flex-none" />
                    <div className="min-w-0 flex-1">
                      <div className="truncate font-medium text-text">{genre.name}</div>
                      <div className="text-xs text-muted">{genre.track_count ?? 0} tracks</div>
                    </div>
                  </button>
                  {subs.length > 0 && (
                    <div className="ml-6 grid grid-cols-2 gap-2 sm:grid-cols-3 md:grid-cols-4">
                      {subs.map((sub) => {
                        const subHue = hueFromString(sub.name);
                        return (
                          <button key={sub.id} onClick={() => setSelected(sub)}
                            className="group flex flex-col items-start gap-1 rounded-lg border border-border/70 p-3 text-left transition-colors hover:border-accent/40"
                            style={{ background: `linear-gradient(135deg, hsl(${subHue},30%,12%), hsl(${(subHue+60)%360},25%,8%))` }}>
                            <div className="w-full truncate text-sm font-medium text-text">{sub.name}</div>
                            <div className="text-xs text-muted">{sub.track_count ?? 0} tracks</div>
                          </button>
                        );
                      })}
                    </div>
                  )}
                </div>
              );
            })}
            {/* Orphan genres (parent_id set but parent not in list) fall back to flat display */}
            {genres.filter((g) => g.parent_id && !genres.find((p) => p.id === g.parent_id)).map((genre) => {
              const hue = hueFromString(genre.name);
              return (
                <button key={genre.id} onClick={() => setSelected(genre)}
                  className="group flex flex-col items-start gap-2 rounded-xl border border-border/70 p-4 text-left transition-colors hover:border-accent/40"
                  style={{ background: `linear-gradient(135deg, hsl(${hue},40%,15%), hsl(${(hue+60)%360},30%,10%))` }}>
                  <Tag size={20} className="text-muted group-hover:text-accent" />
                  <div className="w-full truncate font-medium text-text">{genre.name}</div>
                  <div className="text-xs text-muted">{genre.track_count ?? 0} tracks</div>
                </button>
              );
            })}
          </div>
        )}
    </PageContainer>
  );
}
