import { motion } from 'framer-motion'
import { useNavigate, type NavigateFunction } from 'react-router-dom'
import {
  Play,
  Heart,
  Clock,
  Star,
  Plus,
  Share2,
  ChevronRight,
  RefreshCw,
  Tv2,
  Film as FilmIcon,
  Disc3,
} from '../../lib/icons'
import type { BaseItemDto } from '../../api/types'
import type { TmdbMovie, TmdbTvShow } from '../../api/tmdb'
import type { CinemetaMeta } from '../../api/cinemeta'
import MetaBadges from '../ui/MetaBadges'
import WatchlistButton from '../ui/WatchlistButton'
import RequestButton from '../request/RequestButton'
import ExternalLinks from './ExternalLinks'
import HeroTechCard from './HeroTechCard'
import CastMenu from './CastMenu'
import { useYoutubeViewer } from '../../stores/youtube-viewer-store'
import { usePreferencesStore } from '../../stores/preferences-store'
import type { useRefreshItem, useSampleEpisode } from '../../hooks/use-jellyfin'
import { buildShareUrl, copyToClipboard } from '../../lib/share'
import { toast } from '../../stores/toast-store'

interface Props {
  item: BaseItemDto
  itemType: string
  tmdbMovieData: TmdbMovie | null | undefined
  tmdbTvData: TmdbTvShow | null | undefined
  tmdbId: string | null | undefined
  posterUrl: string
  logoUrl: string | null
  backdropUrl: string | null
  title: string
  year?: number | null
  rating: string | null | undefined
  runtime: string | null
  taglineText: string | null | undefined
  genres: string[]
  resumeTime: string | null
  progress: number | null | undefined
  isFavorite: boolean | null | undefined
  playUrl: string
  resumeUrl: string
  trailer: { key: string; official?: boolean } | null | undefined
  cinemetaData: CinemetaMeta | null | undefined
  showTmdbRatings: boolean
  sampleEpisode: ReturnType<typeof useSampleEpisode>
  refresh: ReturnType<typeof useRefreshItem>
}

export default function DetailHero({
  item,
  itemType,
  tmdbMovieData,
  tmdbTvData,
  tmdbId,
  posterUrl,
  logoUrl,
  backdropUrl,
  title,
  year,
  rating,
  runtime,
  taglineText,
  genres,
  resumeTime,
  progress,
  isFavorite,
  playUrl,
  resumeUrl,
  trailer,
  cinemetaData,
  showTmdbRatings,
  sampleEpisode,
  refresh,
}: Props) {
  const navigate = useNavigate()
  const tmdbData = itemType === 'Movie' ? tmdbMovieData : tmdbTvData
  const preRollTrailers = usePreferencesStore(s => s.preRollTrailers)
  const youtube = useYoutubeViewer()

  function handlePlay() {
    if (preRollTrailers && trailer && itemType === 'Movie') {
      youtube.show({
        videoKey: trailer.key,
        title: `${title} - Trailer`,
        subtitle: trailer.official ? 'Official trailer' : 'Trailer',
        onClose: () => navigate(playUrl),
      })
      return
    }
    navigate(playUrl)
  }

  return (
    <div className="relative h-[68vh] min-h-[520px] -mt-14 overflow-hidden">
      {backdropUrl && (
        <motion.div
          initial={{ scale: 1.06, opacity: 0 }}
          animate={{ scale: 1, opacity: 1 }}
          transition={{ duration: 1.4, ease: [0.16, 1, 0.3, 1] }}
          className="absolute inset-0 bg-cover bg-top"
          style={{ backgroundImage: `url(${backdropUrl})` }}
        />
      )}
      <div className="absolute inset-0 bg-gradient-to-r from-void via-void/60 to-void/10" />
      <div className="absolute inset-0 bg-gradient-to-t from-void via-void/30 to-transparent" />
      <div className="absolute inset-0 bg-[radial-gradient(circle_at_75%_25%,transparent_0%,rgba(0,0,0,0.5)_85%)]" />

      <div className="relative h-full flex items-end pb-12 px-7 gap-7">
        {/* Left column: type pill + poster */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.6, ease: [0.16, 1, 0.3, 1], delay: 0.1 }}
          className="hidden md:flex flex-col gap-3 shrink-0"
        >
          {itemType && <TypePill itemType={itemType} />}
          {posterUrl && (
            <motion.img
              src={posterUrl}
              alt={title}
              initial={{ opacity: 0, scale: 0.96 }}
              animate={{ opacity: 1, scale: 1 }}
              transition={{ duration: 0.7, ease: [0.16, 1, 0.3, 1], delay: 0.15 }}
              onError={e => { (e.target as HTMLImageElement).style.display = 'none' }}
              className="w-[180px] aspect-[2/3] object-cover rounded-xl ring-1 ring-white/10 shadow-[0_24px_60px_-12px_rgba(0,0,0,0.7)]"
            />
          )}
        </motion.div>

        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.6, ease: [0.16, 1, 0.3, 1], delay: 0.2 }}
          className="flex-1 min-w-0 max-w-3xl"
        >
          {/* Type pill (small screens only - shown above poster on md+) */}
          <div className="flex items-center gap-2 mb-4 flex-wrap md:hidden">
            {itemType && <TypePill itemType={itemType} />}
            <MetaBadges item={item} variant="hero" />
          </div>

          {itemType === 'Episode' && item.SeriesId && (
            <EpisodeBreadcrumb item={item} navigate={navigate} />
          )}

          {logoUrl ? (
            <div className="mb-4 flex justify-start">
              <img
                src={logoUrl}
                alt={title}
                className="block h-auto max-h-40 md:max-h-48 max-w-[520px] w-auto drop-shadow-[0_4px_24px_rgba(0,0,0,0.7)]"
                onError={e => { (e.target as HTMLImageElement).style.display = 'none' }}
              />
            </div>
          ) : (
            <h1 className="font-display text-5xl md:text-6xl font-bold text-white leading-[0.95] tracking-tight mb-4 text-left drop-shadow-[0_4px_16px_rgba(0,0,0,0.55)]">
              {title}
            </h1>
          )}

          {taglineText && (
            <p className="text-white/65 text-[15px] italic mb-3 max-w-xl font-display">
              "{taglineText}"
            </p>
          )}

          <div className="flex items-center gap-2.5 text-[12px] text-white/70 font-medium mb-3 flex-wrap">
            {year && <span className="tabular-nums">{year}</span>}
            {year && (rating || runtime) && <Dot />}
            {rating && (
              <span className="px-1.5 py-0.5 border border-white/25 rounded text-[10px] font-semibold tracking-wide">
                {rating}
              </span>
            )}
            {rating && runtime && <Dot />}
            {runtime && (
              <span className="flex items-center gap-1 tabular-nums">
                <Clock size={11} /> {runtime}
              </span>
            )}
            {/* Ratings shown on the right-side card (and here only on small screens for accessibility) */}
            <span className="lg:hidden flex items-center gap-2.5">
              {showTmdbRatings && tmdbData?.vote_average != null && tmdbData.vote_average > 0 && (
                <>
                  <Dot />
                  <span className="flex items-center gap-1" title="TMDB community score">
                    <Star size={11} className="text-accent fill-accent" />
                    <span className="tabular-nums">{tmdbData.vote_average.toFixed(1)}</span>
                    <span className="text-white/45 text-[10px] uppercase tracking-wide">TMDB</span>
                  </span>
                </>
              )}
              {item.CommunityRating != null && item.CommunityRating > 0 && (
                <>
                  <Dot />
                  <span className="flex items-center gap-1 text-cool" title="Jellyfin community average">
                    <Star size={11} className="fill-current" />
                    <span className="tabular-nums">{item.CommunityRating.toFixed(1)}</span>
                    <span className="text-white/45 text-[10px] uppercase tracking-wide">Jellyfin</span>
                  </span>
                </>
              )}
            </span>
            {cinemetaData?.imdbRating && Number(cinemetaData.imdbRating) > 0 && (
              <>
                <Dot />
                <span className="flex items-center gap-1" title="IMDB rating">
                  <Star size={11} className="text-yellow-400 fill-yellow-400" />
                  <span className="tabular-nums">{Number(cinemetaData.imdbRating).toFixed(1)}</span>
                  <span className="text-white/45 text-[10px] uppercase tracking-wide">IMDB</span>
                </span>
              </>
            )}
          </div>

          {genres.length > 0 && (
            <div className="flex flex-wrap gap-1.5 mb-4">
              {genres.slice(0, 5).map(g => (
                <span
                  key={g}
                  className="px-2.5 h-6 inline-flex items-center bg-white/8 hover:bg-white/12 backdrop-blur text-white/80 text-[11px] rounded-full border border-white/8 transition-colors cursor-default"
                >
                  {g}
                </span>
              ))}
            </div>
          )}

          <div className="flex items-center gap-2 flex-wrap mb-5">
            <button
              onClick={handlePlay}
              className="group h-11 px-6 bg-white text-void rounded-lg flex items-center gap-2 text-[14px] font-semibold transition-all duration-200 hover:scale-[1.02] active:scale-[0.98] shadow-lg shadow-black/30 focus-ring"
            >
              <Play size={16} strokeWidth={0} fill="currentColor" />
              Play
            </button>

            {resumeTime && (
              <button
                onClick={() => navigate(resumeUrl)}
                className="h-11 px-4 bg-accent/15 text-accent border border-accent/30 hover:bg-accent/20 rounded-lg flex items-center gap-2 text-[13px] font-medium transition-all duration-200 hover:scale-[1.02] active:scale-[0.98] focus-ring"
              >
                <Play size={14} strokeWidth={0} fill="currentColor" />
                Resume from <span className="tabular-nums">{resumeTime}</span>
              </button>
            )}

            {trailer && (
              <button
                onClick={() =>
                  useYoutubeViewer.getState().show({
                    videoKey: trailer.key,
                    title: `${title} - Trailer`,
                    subtitle: trailer.official ? 'Official trailer' : 'Trailer',
                  })
                }
                className="h-11 px-4 bg-white/10 hover:bg-white/15 text-white border border-white/15 backdrop-blur rounded-lg flex items-center gap-2 text-[13px] font-medium transition-all duration-200 hover:scale-[1.02] active:scale-[0.98] focus-ring"
              >
                Trailer
              </button>
            )}

            {item.Id && (item.Type === 'Movie' || item.Type === 'Series') && (
              <WatchlistButton itemId={item.Id} />
            )}

            {tmdbId && (item.Type === 'Movie' || item.Type === 'Series') && (
              <RequestButton
                tmdbId={Number(tmdbId)}
                kind={item.Type === 'Movie' ? 'movie' : 'tv'}
                tmdbData={tmdbData as any}
              />
            )}

            <IconButton aria-label={isFavorite ? 'Remove favorite' : 'Add favorite'} active={!!isFavorite}>
              <Heart size={16} className={isFavorite ? 'text-accent fill-accent' : 'text-white/80'} />
            </IconButton>
            <IconButton aria-label="Add to playlist">
              <Plus size={16} className="text-white/80" />
            </IconButton>
            <IconButton
              aria-label="Copy share link"
              title="Copy share link"
              onClick={async () => {
                const url = buildShareUrl({
                  tmdbId,
                  imdbId: item.ProviderIds?.Imdb,
                  kind: itemType === 'Series' || itemType === 'Episode' ? 'tv' : 'movie',
                })
                if (!url) {
                  toast('No shareable link for this item', 'error')
                  return
                }
                const ok = await copyToClipboard(url)
                toast(ok ? 'Link copied to clipboard' : 'Could not copy link', ok ? 'success' : 'error')
              }}
            >
              <Share2 size={16} className="text-white/80" />
            </IconButton>
            {item.Id && <CastMenu itemId={item.Id} mediaType={item.MediaType ?? undefined} />}
            <IconButton
              aria-label="Refresh metadata"
              onClick={() => {
                if (!item.Id) return
                refresh.mutate({
                  itemId: item.Id,
                  replaceAllMetadata: false,
                  replaceAllImages: false,
                })
              }}
              disabled={refresh.isPending}
              title={
                refresh.isPending
                  ? 'Refreshing...'
                  : refresh.isSuccess
                    ? 'Refresh queued'
                    : 'Re-scrape metadata + images from TMDB / TVDB'
              }
            >
              <RefreshCw
                size={16}
                className={`text-white/80 ${refresh.isPending ? 'animate-[spin-soft_0.8s_linear_infinite]' : ''}`}
              />
            </IconButton>
          </div>

          <ExternalLinks
            tmdbId={tmdbId}
            type={itemType === 'Series' ? 'tv' : 'movie'}
            ids={tmdbData?.external_ids}
            jellyfinExternalUrls={item.ExternalUrls as any}
          />

          {progress != null && progress > 0 && (
            <div className="mt-5 max-w-md">
              <div className="flex items-center justify-between text-[10px] text-white/60 mb-1.5 font-medium uppercase tracking-wider">
                <span>Watch progress</span>
                <span className="tabular-nums">{Math.round(progress)}%</span>
              </div>
              <div className="h-1 bg-white/10 rounded-full overflow-hidden">
                <motion.div
                  initial={{ width: 0 }}
                  animate={{ width: `${progress}%` }}
                  transition={{ duration: 1, ease: [0.16, 1, 0.3, 1], delay: 0.4 }}
                  className="h-full bg-accent shadow-[0_0_8px_rgba(245,182,66,0.6)]"
                />
              </div>
            </div>
          )}
        </motion.div>

        <motion.div
          initial={{ opacity: 0, y: 14 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.6, ease: [0.16, 1, 0.3, 1], delay: 0.35 }}
          className="self-end"
        >
          <HeroTechCard
            techItem={itemType === 'Series' ? sampleEpisode.data : item}
            tmdbVote={tmdbData?.vote_average}
            tmdbVoteCount={tmdbData?.vote_count}
            jellyfinCommunity={item.CommunityRating}
            jellyfinCritic={item.CriticRating}
            imdbRating={
              cinemetaData?.imdbRating
                ? Number(cinemetaData.imdbRating)
                : null
            }
            showTmdbRatings={showTmdbRatings}
            seasonsCount={
              itemType === 'Series'
                ? tmdbTvData?.number_of_seasons ?? null
                : null
            }
            episodesCount={
              itemType === 'Series'
                ? tmdbTvData?.number_of_episodes ?? null
                : null
            }
            seriesStatus={itemType === 'Series' ? tmdbTvData?.status ?? null : null}
            onRescan={
              item.Id
                ? () =>
                    refresh.mutate({
                      itemId: item.Id!,
                      replaceAllMetadata: false,
                      replaceAllImages: false,
                    })
                : undefined
            }
            isRescanning={refresh.isPending}
          />
        </motion.div>
      </div>

      <div className="absolute bottom-0 left-0 right-0 h-32 bg-gradient-to-b from-transparent to-void pointer-events-none" />
    </div>
  )
}

function TypePill({ itemType }: { itemType: string }) {
  return (
    <span className="inline-flex items-center gap-1.5 h-6 px-2.5 self-start rounded-full bg-white/8 border border-white/12 backdrop-blur text-[10px] font-semibold uppercase tracking-[0.12em] text-white/80">
      {itemType === 'Series' || itemType === 'Episode' ? (
        <Tv2 size={10} className="text-accent" />
      ) : itemType === 'MusicAlbum' || itemType === 'MusicArtist' ? (
        <Disc3 size={10} className="text-accent" />
      ) : (
        <FilmIcon size={10} className="text-accent" />
      )}
      {itemType === 'Series' ? 'Series' : itemType === 'Movie' ? 'Movie' : itemType}
    </span>
  )
}

function EpisodeBreadcrumb({ item, navigate }: { item: BaseItemDto; navigate: NavigateFunction }) {
  return (
    <button
      onClick={() => navigate(`/item/${item.SeriesId}`)}
      className="inline-flex items-center gap-2 mb-3 group focus-ring rounded"
    >
      <span className="text-[11px] font-semibold text-white/70 uppercase tracking-[0.18em] group-hover:text-white transition">
        {item.SeriesName}
      </span>
      {item.ParentIndexNumber != null && item.IndexNumber != null && (
        <span className="text-[11px] text-white/50 font-medium tabular-nums">
          S{item.ParentIndexNumber} · E{item.IndexNumber}
        </span>
      )}
      <ChevronRight size={12} className="text-white/40 group-hover:text-white/80 group-hover:translate-x-0.5 transition" />
    </button>
  )
}

function Dot() {
  return <span className="text-white/30">·</span>
}

function IconButton({
  children,
  active,
  ...props
}: React.ButtonHTMLAttributes<HTMLButtonElement> & { active?: boolean }) {
  return (
    <button
      {...props}
      className={`w-11 h-11 rounded-lg backdrop-blur grid place-items-center transition-all duration-200 hover:scale-105 active:scale-95 focus-ring disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100 ${
        active
          ? 'bg-accent/15 border border-accent/30'
          : 'bg-white/10 border border-white/15 hover:bg-white/15'
      }`}
    >
      {children}
    </button>
  )
}
