'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import { useLocale } from '@/lib/i18n/locale-context';
import { SectionHeader } from '@/components/ui/SectionHeader';
import type { Dict } from '@/lib/i18n/dictionaries';
import { cn } from '@/lib/utils';

type Item = Dict['portfolio']['items'][number];
type Accent = 'electric' | 'violet' | 'magenta' | 'emerald' | 'cyan';

const ACCENT_TEXT: Record<Accent, string> = {
  electric: 'text-electric',
  violet: 'text-violet',
  magenta: 'text-magenta',
  emerald: 'text-emerald',
  cyan: 'text-cyan',
};
const ACCENT_BORDER: Record<Accent, string> = {
  electric: 'border-electric/30 bg-electric/5 text-electric',
  violet: 'border-violet/30 bg-violet/5 text-violet',
  magenta: 'border-magenta/30 bg-magenta/5 text-magenta',
  emerald: 'border-emerald/30 bg-emerald/5 text-emerald',
  cyan: 'border-cyan/30 bg-cyan/5 text-cyan',
};
const ACCENT_RING: Record<Accent, string> = {
  electric: 'hover:ring-electric/40',
  violet: 'hover:ring-violet/40',
  magenta: 'hover:ring-magenta/40',
  emerald: 'hover:ring-emerald/40',
  cyan: 'hover:ring-cyan/40',
};
// Full literal classes so Tailwind's JIT scanner picks them up — runtime
// string concatenation (`group-hover:${...}`) would never be detected.
const ACCENT_GROUP_HOVER: Record<Accent, string> = {
  electric: 'group-hover:text-electric',
  violet: 'group-hover:text-violet',
  magenta: 'group-hover:text-magenta',
  emerald: 'group-hover:text-emerald',
  cyan: 'group-hover:text-cyan',
};

export function Portfolio() {
  const { t, locale } = useLocale();
  const items = t.portfolio.items as readonly Item[];
  const [openId, setOpenId] = useState<string | null>(null);

  const active = useMemo(
    () => items.find((p) => p.id === openId) ?? null,
    [items, openId],
  );

  return (
    <section id="portfolio" className="relative px-5 py-28 sm:px-8">
      <div className="mx-auto max-w-7xl">
        <SectionHeader
          eyebrow={t.portfolio.eyebrow}
          title={t.portfolio.title}
          sub={t.portfolio.sub}
        />

        <div className="mt-14 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3">
          {items.map((item, i) => {
            const accent = item.accent as Accent;
            return (
              <motion.button
                key={item.id}
                type="button"
                onClick={() => setOpenId(item.id)}
                initial={{ opacity: 0, y: 24 }}
                whileInView={{ opacity: 1, y: 0 }}
                viewport={{ once: true, margin: '-60px' }}
                transition={{
                  duration: 0.55,
                  ease: [0.22, 1, 0.36, 1],
                  delay: 0.04 * i,
                }}
                className={cn(
                  'group relative flex flex-col overflow-hidden rounded-2xl border border-white/8 bg-white/[0.02] text-start ring-1 ring-transparent transition-all duration-300 hover:-translate-y-1',
                  ACCENT_RING[accent],
                )}
              >
                {/* Cover */}
                <div className="relative aspect-[16/10] overflow-hidden">
                  {/* eslint-disable-next-line @next/next/no-img-element */}
                  <img
                    src={item.cover}
                    alt={item.title}
                    loading="lazy"
                    className="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
                  />
                  <div className="absolute inset-0 bg-gradient-to-t from-base-900/90 via-base-900/10 to-transparent" />
                  <div className="absolute inset-x-0 bottom-0 flex items-end justify-between gap-3 p-4">
                    <span
                      className={cn(
                        'rounded-full border px-2.5 py-0.5 font-mono text-[0.62rem] uppercase tracking-wider backdrop-blur-sm',
                        ACCENT_BORDER[accent],
                      )}
                    >
                      {item.role}
                    </span>
                    <span className="font-mono text-[0.7rem] text-slate-300">
                      {item.year}
                    </span>
                  </div>
                </div>

                {/* Body */}
                <div className="flex grow flex-col p-5">
                  <h3
                    className={cn(
                      'font-display text-[1.05rem] font-semibold leading-snug text-white transition-colors',
                      ACCENT_GROUP_HOVER[accent],
                      locale === 'fa' && 'font-fa',
                    )}
                  >
                    {item.title}
                  </h3>
                  <p className="mt-2 line-clamp-2 grow text-[0.9rem] leading-relaxed text-slate-400">
                    {item.summary}
                  </p>
                  <div className="mt-4 flex flex-wrap gap-1.5">
                    {item.tags.slice(0, 4).map((tag) => (
                      <span
                        key={tag}
                        className="rounded-md border border-white/8 bg-white/[0.03] px-2 py-0.5 font-mono text-[0.62rem] text-slate-400"
                      >
                        {tag}
                      </span>
                    ))}
                  </div>
                  <span
                    className={cn(
                      'mt-5 inline-flex items-center gap-1.5 font-mono text-[0.7rem] uppercase tracking-wider',
                      ACCENT_TEXT[accent],
                    )}
                  >
                    {t.portfolio.labels.view}
                    <Arrow locale={locale} />
                  </span>
                </div>
              </motion.button>
            );
          })}
        </div>
      </div>

      <AnimatePresence>
        {active && (
          <Lightbox
            key={active.id}
            item={active}
            labels={t.portfolio.labels}
            locale={locale}
            onClose={() => setOpenId(null)}
          />
        )}
      </AnimatePresence>
    </section>
  );
}

function Lightbox({
  item,
  labels,
  locale,
  onClose,
}: {
  item: Item;
  labels: Dict['portfolio']['labels'];
  locale: 'fa' | 'en';
  onClose: () => void;
}) {
  const accent = item.accent as Accent;
  const images = useMemo(() => [item.cover, ...item.gallery], [item]);
  const [idx, setIdx] = useState(0);

  const go = useCallback(
    (dir: number) => setIdx((i) => (i + dir + images.length) % images.length),
    [images.length],
  );

  // Keyboard navigation + scroll lock while the lightbox is open.
  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
      else if (e.key === 'ArrowRight') go(locale === 'fa' ? -1 : 1);
      else if (e.key === 'ArrowLeft') go(locale === 'fa' ? 1 : -1);
    };
    document.addEventListener('keydown', onKey);
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.removeEventListener('keydown', onKey);
      document.body.style.overflow = prevOverflow;
    };
  }, [go, locale, onClose]);

  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
      transition={{ duration: 0.25 }}
      onClick={onClose}
      className="fixed inset-0 z-[60] flex items-center justify-center bg-base-900/85 p-4 backdrop-blur-md sm:p-8"
      dir={locale === 'fa' ? 'rtl' : 'ltr'}
      role="dialog"
      aria-modal="true"
      aria-label={item.title}
    >
      <motion.div
        initial={{ opacity: 0, scale: 0.96, y: 16 }}
        animate={{ opacity: 1, scale: 1, y: 0 }}
        exit={{ opacity: 0, scale: 0.97, y: 10 }}
        transition={{ duration: 0.3, ease: [0.22, 1, 0.36, 1] }}
        onClick={(e) => e.stopPropagation()}
        className="grid max-h-full w-full max-w-5xl grid-rows-[auto] overflow-hidden rounded-3xl border border-white/10 bg-base-900/95 shadow-2xl md:grid-cols-[1.4fr_1fr]"
      >
        {/* Gallery viewer */}
        <div className="relative flex flex-col bg-black/30">
          <div className="relative aspect-[16/10] w-full overflow-hidden">
            <AnimatePresence mode="wait">
              {/* eslint-disable-next-line @next/next/no-img-element */}
              <motion.img
                key={images[idx]}
                src={images[idx]}
                alt={`${item.title} — ${idx + 1}`}
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                exit={{ opacity: 0 }}
                transition={{ duration: 0.2 }}
                className="h-full w-full object-cover"
              />
            </AnimatePresence>

            {images.length > 1 && (
              <>
                <NavButton side="prev" locale={locale} onClick={() => go(locale === 'fa' ? 1 : -1)} label={labels.prev} />
                <NavButton side="next" locale={locale} onClick={() => go(locale === 'fa' ? -1 : 1)} label={labels.next} />
              </>
            )}
          </div>

          {/* Thumbnails */}
          <div className="flex gap-2 overflow-x-auto p-3">
            {images.map((src, i) => (
              <button
                key={src}
                type="button"
                onClick={() => setIdx(i)}
                aria-label={`${labels.gallery} ${i + 1}`}
                className={cn(
                  'relative h-12 w-20 shrink-0 overflow-hidden rounded-lg border transition-all',
                  i === idx
                    ? cn('border-2', ACCENT_BORDER[accent])
                    : 'border-white/10 opacity-60 hover:opacity-100',
                )}
              >
                {/* eslint-disable-next-line @next/next/no-img-element */}
                <img src={src} alt="" className="h-full w-full object-cover" />
              </button>
            ))}
          </div>
        </div>

        {/* Meta panel */}
        <div className="flex flex-col gap-5 overflow-y-auto p-6 sm:p-7">
          <div className="flex items-start justify-between gap-3">
            <span
              className={cn(
                'rounded-full border px-2.5 py-0.5 font-mono text-[0.62rem] uppercase tracking-wider',
                ACCENT_BORDER[accent],
              )}
            >
              {item.client}
            </span>
            <button
              type="button"
              onClick={onClose}
              aria-label={labels.close}
              className="inline-flex h-8 w-8 items-center justify-center rounded-full border border-white/10 bg-white/[0.03] text-slate-300 transition-colors hover:bg-white/[0.07] hover:text-white"
            >
              <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
                <path d="M6 6 L18 18" />
                <path d="M18 6 L6 18" />
              </svg>
            </button>
          </div>

          <h3
            className={cn(
              'font-display text-[1.45rem] font-bold leading-tight text-white',
              locale === 'fa' && 'font-fa',
            )}
          >
            {item.title}
          </h3>

          <p className="text-[0.95rem] leading-relaxed text-slate-300">
            {item.summary}
          </p>

          {/* Metrics */}
          <div className="grid grid-cols-3 gap-3">
            {item.metrics.map((mt) => (
              <div
                key={mt.label}
                className="rounded-xl border border-white/8 bg-white/[0.02] p-3 text-center"
              >
                <div className={cn('font-display text-lg font-bold', ACCENT_TEXT[accent])}>
                  {mt.value}
                </div>
                <div className="mt-0.5 text-[0.65rem] leading-tight text-slate-500">
                  {mt.label}
                </div>
              </div>
            ))}
          </div>

          <dl className="grid grid-cols-2 gap-x-4 gap-y-3 border-t border-white/5 pt-5 text-sm">
            <Field label={labels.role} value={item.role} />
            <Field label={labels.year} value={item.year} />
            <Field label={labels.client} value={item.client} />
          </dl>

          <div>
            <span className="label-mono text-slate-500">{labels.stack}</span>
            <div className="mt-2 flex flex-wrap gap-1.5">
              {item.tags.map((tag) => (
                <span
                  key={tag}
                  className="rounded-md border border-white/8 bg-white/[0.03] px-2 py-0.5 font-mono text-[0.66rem] text-slate-300"
                >
                  {tag}
                </span>
              ))}
            </div>
          </div>
        </div>
      </motion.div>
    </motion.div>
  );
}

function Field({ label, value }: { label: string; value: string }) {
  return (
    <div>
      <dt className="font-mono text-[0.6rem] uppercase tracking-wider text-slate-500">
        {label}
      </dt>
      <dd className="mt-1 text-slate-200">{value}</dd>
    </div>
  );
}

function NavButton({
  side,
  locale,
  onClick,
  label,
}: {
  side: 'prev' | 'next';
  locale: 'fa' | 'en';
  onClick: () => void;
  label: string;
}) {
  // Visually pin to the left/right edge regardless of text direction.
  const edge = side === 'prev' ? 'left-3' : 'right-3';
  const pointLeft = side === 'prev';
  return (
    <button
      type="button"
      onClick={onClick}
      aria-label={label}
      className={cn(
        'absolute top-1/2 -translate-y-1/2 inline-flex h-9 w-9 items-center justify-center rounded-full border border-white/15 bg-base-900/70 text-slate-200 backdrop-blur transition-colors hover:bg-base-900/90 hover:text-white',
        edge,
      )}
    >
      <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" className={pointLeft ? '' : 'rotate-180'}>
        <path d="M15 6 L9 12 L15 18" />
      </svg>
    </button>
  );
}

function Arrow({ locale }: { locale: 'fa' | 'en' }) {
  return (
    <svg
      viewBox="0 0 24 24"
      width="12"
      height="12"
      fill="none"
      stroke="currentColor"
      strokeWidth="2.4"
      strokeLinecap="round"
      strokeLinejoin="round"
      className={locale === 'fa' ? 'rotate-180' : ''}
      aria-hidden
    >
      <path d="M5 12 H19" />
      <path d="M13 6 L19 12 L13 18" />
    </svg>
  );
}
