import { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { Play, Check, Tv2, Film, Music } from '../../lib/icons'
import { getBestImage } from '../../api/jellyfin'
import { formatRuntime } from '../../lib/format'
import type { BaseItemDto } from '../../api/types'

interface Props {
  item: BaseItemDto
  index: number
  serverUrl: string
  selected: boolean
  dragging: boolean
  showDropIndicatorBefore: boolean
  onPointerDownBody: (e: React.PointerEvent) => void
  refSetter: (el: HTMLLIElement | null) => void
}

export default function PlaylistRow({
  item,
  index,
  serverUrl,
  selected,
  dragging,
  showDropIndicatorBefore,
  onPointerDownBody,
  refSetter,
}: Props) {
  const navigate = useNavigate()
  const [thumbErrored, setThumbErrored] = useState(false)
  const thumb = getBestImage(serverUrl, item, 'thumb', 320)
  const showThumb = thumb && !thumbErrored

  const isWatched = item.UserData?.Played
  const progress = item.UserData?.PlayedPercentage
  const runtime = item.RunTimeTicks ? formatRuntime(item.RunTimeTicks) : null
  const year = item.ProductionYear || (item.PremiereDate ? new Date(item.PremiereDate).getFullYear() : null)
  const augmented = item as BaseItemDto & {
    LocationType?: string
    MediaSources?: unknown[]
    Path?: string
    AlbumArtist?: string
    Album?: string
  }
  const isMissing =
    augmented.LocationType === 'Virtual' ||
    (!(augmented.MediaSources?.length) && !augmented.Path)

  const subtitle =
    item.Type === 'Episode'
      ? `${item.SeriesName || ''}${
          item.ParentIndexNumber != null && item.IndexNumber != null
            ? ` · S${item.ParentIndexNumber} · E${item.IndexNumber}`
            : ''
        }`
      : item.Type === 'Movie'
        ? 'Movie'
        : item.Type === 'Audio'
          ? augmented.AlbumArtist || augmented.Album || 'Audio'
          : item.Type || ''

  const TypeIcon =
    item.Type === 'Episode' || item.Type === 'Series'
      ? Tv2
      : item.Type === 'Audio' || item.Type === 'MusicAlbum'
        ? Music
        : Film

  function goPlay(e: React.MouseEvent) {
    e.stopPropagation()
    if (isMissing || !item.Id) return
    navigate(`/play/${item.Id}`)
  }

  return (
    <li
      ref={refSetter}
      className={`relative ${dragging ? 'opacity-30' : ''}`}
    >
      {showDropIndicatorBefore && (
        <span className="absolute -top-px inset-x-2 h-px bg-accent z-10 shadow-[0_0_8px_rgba(245,182,66,0.6)]" />
      )}
      <div
        onPointerDown={onPointerDownBody}
        role="button"
        tabIndex={0}
        aria-label={`Playlist item ${index + 1}`}
        aria-selected={selected}
        className={`group flex items-center gap-4 px-3 py-2.5 rounded-lg transition-colors duration-150 cursor-pointer focus-ring touch-none ${
          isMissing ? 'opacity-60' : ''
        } ${
          selected
            ? 'bg-accent/12 ring-1 ring-accent/40 hover:bg-accent/15'
            : 'hover:bg-elevated/60'
        }`}
      >
        <span className="w-8 shrink-0 text-[12px] tabular-nums font-mono text-text-4 group-hover:text-text-3 transition-colors text-center">
          {String(index + 1).padStart(2, '0')}
        </span>

        <button
          type="button"
          onClick={goPlay}
          onPointerDown={e => e.stopPropagation()}
          disabled={isMissing}
          aria-label={isMissing ? 'Item missing' : `Play ${item.Name}`}
          className={`relative shrink-0 w-[120px] aspect-video rounded-md overflow-hidden bg-elevated ring-1 ring-border focus-ring ${
            isMissing ? 'cursor-not-allowed' : 'cursor-pointer'
          }`}
        >
          {showThumb ? (
            <img
              src={thumb}
              alt=""
              onError={() => setThumbErrored(true)}
              className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
              loading="lazy"
            />
          ) : (
            <div className="w-full h-full grid place-items-center bg-gradient-to-br from-elevated to-surface">
              <TypeIcon size={20} className="text-text-4 opacity-60" />
            </div>
          )}
          <div className="absolute inset-0 bg-gradient-to-t from-black/40 to-transparent" />
          {!isMissing && (
            <div className="absolute inset-0 grid place-items-center opacity-0 group-hover:opacity-100 transition-opacity duration-200">
              <div className="w-9 h-9 rounded-full bg-accent grid place-items-center shadow-lg shadow-black/40">
                <Play size={13} className="text-void translate-x-0.5" fill="currentColor" />
              </div>
            </div>
          )}
          {progress != null && progress > 0 && progress < 95 && (
            <div className="absolute bottom-0 left-0 right-0 h-[2px] bg-black/30">
              <div className="h-full bg-accent" style={{ width: `${progress}%` }} />
            </div>
          )}
        </button>

        <div className="flex-1 min-w-0 flex flex-col gap-0.5">
          <div className="flex items-center gap-2 min-w-0">
            <p className="text-[13.5px] text-text-1 font-semibold tracking-tight truncate">
              {item.Name || 'Untitled'}
            </p>
            {isWatched && (
              <span
                className="shrink-0 w-4 h-4 rounded-full bg-accent grid place-items-center self-center"
                title="Watched"
              >
                <Check size={9} className="text-void" strokeWidth={3} />
              </span>
            )}
          </div>
          {subtitle && (
            <p className="text-[11.5px] text-text-3 truncate flex items-center gap-1.5">
              <TypeIcon size={10} className="text-text-4 shrink-0" />
              {subtitle}
            </p>
          )}
        </div>

        <div className="hidden md:flex items-center gap-3 text-[11.5px] text-text-4 tabular-nums shrink-0">
          {year && <span>{year}</span>}
          {year && runtime && <span className="text-text-5">·</span>}
          {runtime && <span>{runtime}</span>}
        </div>
      </div>
    </li>
  )
}
