import { Badge } from '@/Components/ui/badge';
import { ease } from '@/lib/motion';
import { GameDetail } from '@/types/models';
import { motion, useReducedMotion, useScroll, useTransform } from 'framer-motion';
import { Star } from 'lucide-react';
import { ReactNode, useRef } from 'react';

export const formatDate = (d: string | null) =>
    d ? new Date(`${d}T00:00:00Z`).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric', timeZone: 'UTC' }) : 'TBA';

export default function GameHero({ game, actions }: { game: GameDetail; actions: ReactNode }) {
    const ref = useRef<HTMLElement>(null);
    const reduce = useReducedMotion();
    const { scrollYProgress } = useScroll({ target: ref, offset: ['start start', 'end start'] });
    const bgY = useTransform(scrollYProgress, [0, 1], ['0%', '22%']);
    const bgScale = useTransform(scrollYProgress, [0, 1], [1.05, 1.18]);
    const fgY = useTransform(scrollYProgress, [0, 1], ['0%', '-8%']);
    const fade = useTransform(scrollYProgress, [0, 0.75], [1, 0.2]);
    const bg = game.hero ?? game.cover;

    return (
        <header ref={ref} className="relative isolate overflow-hidden rounded-3xl border border-border shadow-lift">
            <motion.div aria-hidden style={reduce ? undefined : { y: bgY, scale: bgScale }} className="absolute inset-0 -z-20">
                {bg ? <img src={bg} alt="" className={`size-full object-cover ${game.hero ? '' : 'scale-125 blur-2xl'}`} /> : <div className="size-full bg-gradient-to-br from-secondary to-muted" />}
            </motion.div>
            <div aria-hidden className="absolute inset-0 -z-10 bg-gradient-to-t from-background via-background/70 to-background/10" />
            <div aria-hidden className="absolute inset-0 -z-10 bg-gradient-to-r from-background/80 via-transparent to-transparent" />

            <motion.div style={reduce ? undefined : { y: fgY, opacity: fade }} className="flex min-h-[540px] flex-col justify-end gap-8 p-5 pt-40 sm:min-h-[620px] sm:p-10 sm:pt-48">
                <div className="flex flex-col gap-6 sm:flex-row sm:items-end sm:gap-8">
                    <motion.div
                        initial={{ opacity: 0, y: 24, rotateX: 8 }}
                        animate={{ opacity: 1, y: 0, rotateX: 0 }}
                        transition={{ duration: 0.7, ease }}
                        className="mx-auto aspect-[3/4] w-44 shrink-0 overflow-hidden rounded-2xl border border-white/10 bg-card shadow-2xl shadow-black/50 sm:mx-0 sm:w-56"
                    >
                        {game.cover ? <img src={game.cover} alt={`${game.title} cover`} className="size-full object-cover" /> : <div className="flex size-full items-end bg-gradient-to-br from-secondary to-muted p-4 text-h3">{game.title}</div>}
                    </motion.div>

                    <motion.div initial={{ opacity: 0, y: 16 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.7, delay: 0.1, ease }} className="min-w-0 flex-1 space-y-4 text-center sm:text-left">
                        <div className="flex flex-wrap justify-center gap-1.5 sm:justify-start">
                            {game.genres.map((g) => <Badge key={g.slug} variant="glass">{g.name}</Badge>)}
                            {game.status === 'upcoming' && <Badge variant="accent">Upcoming</Badge>}
                        </div>
                        <h1 className="text-display">{game.title}</h1>
                        <p className="text-sm text-muted-foreground">
                            {[game.developer, formatDate(game.release_date), game.age_rating && `Rated ${game.age_rating}`].filter(Boolean).join('  ·  ')}
                        </p>
                        {game.summary && <p className="mx-auto max-w-2xl text-body text-foreground/80 sm:mx-0">{game.summary}</p>}
                        <div className="flex flex-wrap items-center justify-center gap-4 sm:justify-start">
                            {game.rating_count > 0 && (
                                <span className="inline-flex items-center gap-1.5">
                                    <Star className="size-5 fill-amber-400 text-amber-400" />
                                    <span className="text-h2">{game.rating_avg.toFixed(1)}</span>
                                    <span className="text-caption">/ 10 · {game.rating_count.toLocaleString()} ratings</span>
                                </span>
                            )}
                            {game.metacritic && (
                                <span className="inline-flex items-center gap-2 text-caption">
                                    <span className="flex size-8 items-center justify-center rounded-md bg-emerald-500/20 text-sm font-semibold text-emerald-400">{game.metacritic}</span>Metacritic
                                </span>
                            )}
                        </div>
                    </motion.div>
                </div>

                <motion.div initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.6, delay: 0.25, ease }} className="glass flex flex-col gap-4 rounded-2xl border border-border p-3 sm:flex-row sm:items-center sm:justify-between sm:p-4">
                    {actions}
                </motion.div>
            </motion.div>
        </header>
    );
}
