import { Play, Pause, ThumbsDown, Sparkles } from 'lucide-react';
import { Link, useRouter } from '@tanstack/react-router';
import type { Track } from '../types';
import { usePlaybackStore } from '../store/usePlaybackStore';
import { useDislikeTrack } from '../hooks/useDislikeTrack';
import { startVibeSession } from '../services/vibeSession';
import { Artwork } from './Artwork';
import { ArtistLinks } from './ArtistLinks';

export function formatDuration(seconds?: number | null): string {
  if (!seconds || seconds < 0 || !Number.isFinite(seconds)) return '0:00';
  const total = Math.floor(seconds);
  return `${Math.floor(total / 60)}:${(total % 60).toString().padStart(2, '0')}`;
}

type TrackRowVariant = 'default' | 'compact';

interface TrackRowProps {
  track: Track;
  queue: Track[];
  index: number;
  showActions?: boolean;
  /** compact — smaller artwork, no duration, for queue panels / VibeTimeline */
  variant?: TrackRowVariant;
  /** Show a "Vibe by track" button that starts a vibe session seeded from this track. */
  showVibe?: boolean;
  /** Override ordinary queue playback, for contextual actions such as Vibe seed rows. */
  onSelect?: (track: Track) => void;
  /** Display-only rows keep their surrounding playback controller authoritative. */
  playable?: boolean;
}

export function TrackRow({ track, queue, showActions = true, variant = 'default', showVibe = false, onSelect, playable = true }: TrackRowProps) {
  const { setQueue, playTrack, play, pause, currentTrack, isPlaying } = usePlaybackStore();
  const dislikeTrack = useDislikeTrack();
  const router = useRouter();
  const isCurrent = currentTrack?.id === track.id;
  const compact = variant === 'compact';

  const handlePlay = () => {
    if (!playable) return;
    if (onSelect) {
      onSelect(track);
      return;
    }
    if (isCurrent) { isPlaying ? pause() : play(); return; }
    // Queue the whole list and start at this track, so Previous can walk back
    // into the tracks before it.
    setQueue(queue);
    playTrack(track);
  };

  const playLabel = !playable
    ? `${track.title || 'Track'} is queued by Vibe`
    : isCurrent && isPlaying
    ? `Pause ${track.title || 'track'}`
    : `Play ${track.title || 'track'}`;

  const handleDislike = (e: React.MouseEvent) => {
    e.stopPropagation();
    dislikeTrack(track.id);
  };

  const handleVibe = (e: React.MouseEvent) => {
    e.stopPropagation();
    // Start and hydrate the V2 plan before showing the Vibe page.
    startVibeSession(track).then(() => {
      router.navigate({ to: '/vibe' });
    }).catch(() => {
      // Session failed — still navigate so the user can try manually.
      router.navigate({ to: '/vibe' });
    });
  };

  return (
    <div
      // With the title linking to its album, a seed row would otherwise only be
      // selectable by its 36px artwork tile. The whole row takes the click.
      onClick={onSelect ? handlePlay : undefined}
      role={onSelect ? 'button' : undefined}
      className={`group relative flex w-full items-center gap-2.5 rounded-md px-1.5 transition-colors ${onSelect ? 'cursor-pointer' : ''} ${
        compact ? 'h-11' : 'h-[52px]'
      } ${
        isCurrent
          ? "bg-accent/10 before:absolute before:left-0 before:top-1.5 before:bottom-1.5 before:w-0.5 before:rounded-full before:bg-accent before:content-['']"
          // `.track-row` carries the hover light (see index.css) — a gradient that
          // falls off to the right instead of a flat slab. Display-only rows still
          // light up; what they skip is the play-icon ramp below.
          : 'track-row'
      }`}
    >
      {/* Artwork + play overlay */}
      <button
        type="button"
        onClick={handlePlay}
        disabled={!playable}
        aria-label={playLabel}
        className={`relative flex flex-none items-center justify-center rounded overflow-hidden focus-visible:z-30 disabled:cursor-default disabled:opacity-70 ${
        // 32px, written as an arbitrary value on purpose: the spacing scale is
        // remapped, so `h-8` is 64px and overflowed this 44px row — that overflow
        // was the "stacked" look, not a design choice.
        compact ? 'h-[32px] w-[32px]' : 'h-9 w-9'
      }`}>
        {/* glyph={false}: the play/pause icon below is the only glyph this tile gets. */}
        <Artwork seed={`${track.title} ${track.artist}`} src={track.artwork_id} glyph={false} className="absolute inset-0 w-full h-full" />
        {isCurrent && isPlaying ? (
          <Pause size={compact ? 14 : 18} className="absolute z-20 text-text opacity-100" />
        ) : (
          <Play
            size={compact ? 14 : 18}
            className={`absolute z-20 text-text opacity-70 transition-opacity ${playable ? 'group-hover:opacity-100' : ''}`}
          />
        )}
      </button>

      {/* Title + artist */}
      <div className="min-w-0 flex-1">
        {/* The title navigates to the album, matching the artist links beside it.
            Playback lives on the artwork tile; a title that played was the surprise. */}
        {track.album_id ? (
          <Link
            to="/albums/$albumId"
            params={{ albumId: track.album_id }}
            onClick={(e) => e.stopPropagation()}
            title={track.title || 'Untitled'}
            className={`block max-w-full truncate rounded text-left text-sm font-medium hover:underline ${isCurrent ? 'text-accent' : 'text-text'}`}
          >
            {track.title || 'Untitled'}
          </Link>
        ) : (
          <span className={`block max-w-full truncate text-sm font-medium ${isCurrent ? 'text-accent' : 'text-text'}`}>
            {track.title || 'Untitled'}
          </span>
        )}
        <ArtistLinks
          artists={track.artists}
          fallback={track.artist}
          stopPropagation
          className={`truncate block text-muted ${compact ? 'text-xs' : 'text-xs'}`}
        />
      </div>

      {/* Actions (vibe → album link → dislike) */}
      {showActions && !compact && (
        <div className="track-row-actions flex flex-none items-center gap-1">
          {showVibe && (
            <button type="button" onClick={handleVibe} aria-label="Start a Vibe from this track" title="Vibe by track" className="rounded p-1.5 text-muted hover:bg-surface1 hover:text-accent">
              <Sparkles size={16} />
            </button>
          )}
          {/* The album disc button is gone — the title itself is the album link now. */}
          <button type="button" onClick={handleDislike} aria-label={`Dislike ${track.title || 'track'}`} title="Dislike" className="rounded p-1.5 text-muted hover:bg-surface1 hover:text-red-400">
            <ThumbsDown size={16} />
          </button>
        </div>
      )}

      {/* Duration (hidden in compact) */}
      {!compact && (
        <div className="flex-none pr-1 font-mono text-xs tabular-nums text-machine">{formatDuration(track.duration)}</div>
      )}
    </div>
  );
}
