"use client";
import { useEffect, useRef, useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import { Pencil, User, Image as ImageIcon, ArrowLeft } from "lucide-react";
import { ActressPortraitEditor } from "./ActressPortraitEditor";
import { ActressMetaEditor } from "./ActressMetaEditor";
import { CategoryIcon } from "./CategoryIcon";
import { buildAltNameChips } from "@/lib/jav/nameUtils";
import type { ActressCategory, ActressAllPortraits, PortraitSlotKey } from "@/lib/db/queries";
import { toggleActressCategory } from "@/app/actions/actressCategories";
import { reorderActressPortraitSlots } from "@/app/actions/actressPortrait";
import { portraitUrl } from "@/lib/assetUrls";

interface Props {
  actress: {
    id: number;
    name: string;
    slug: string;
    altNames: string | null;
    notes: string | null;
    portraits: ActressAllPortraits;
    categories: ActressCategory[];
    bornOn: string | null;
    heightCm: number | null;
    weightKg: number | null;
    cupSize: string | null;
  };
  coverCount: number;
  allCategories: ActressCategory[];
}

function computeAge(bornOn: string | null): number | null {
  if (!bornOn) return null;
  const d = new Date(bornOn);
  if (Number.isNaN(d.getTime())) return null;
  const now = new Date();
  let age = now.getFullYear() - d.getFullYear();
  const m = now.getMonth() - d.getMonth();
  if (m < 0 || (m === 0 && now.getDate() < d.getDate())) age--;
  return age >= 0 ? age : null;
}

const PHI = 1.618;
const FRAME_H = 308;
const PORTRAIT_W = Math.floor(FRAME_H / PHI);
const HORIZ_W = Math.floor(FRAME_H * PHI);
const SLOT_LABEL: Record<PortraitSlotKey, string> = { "1": "P1", "2": "P2", "3": "P3", "4": "P4", "h": "L" };

export function ActressHero({ actress, coverCount, allCategories }: Props) {
  const [editingMeta, setEditingMeta] = useState(false);
  const [editingSlot, setEditingSlot] = useState<PortraitSlotKey | null>(null);
  const router = useRouter();
  const [, start] = useTransition();
  const altChips = buildAltNameChips(actress.name, actress.altNames);
  const ringColor = actress.categories[0]?.color ?? null;
  const activeIds = new Set(actress.categories.map((c) => c.id));
  const orderedCategories = (() => {
    const list = [...allCategories];
    const vipIdx = list.findIndex((c) => c.slug === "vip");
    const favIdx = list.findIndex((c) => c.slug === "favorite");
    if (vipIdx !== -1 && favIdx !== -1 && vipIdx > favIdx) {
      const [vip] = list.splice(vipIdx, 1);
      list.splice(favIdx, 0, vip);
    }
    return list;
  })();

  function toggleCat(id: number) {
    start(async () => {
      await toggleActressCategory(actress.id, id);
      router.refresh();
    });
  }

  const dragSlotRef = useRef<PortraitSlotKey | null>(null);
  const [dragSlot, setDragSlotState] = useState<PortraitSlotKey | null>(null);
  function setDragSlot(s: PortraitSlotKey | null) {
    dragSlotRef.current = s;
    setDragSlotState(s);
  }
  const [overSlot, setOverSlot] = useState<PortraitSlotKey | null>(null);
  const [optimistic, setOptimistic] = useState<ActressAllPortraits | null>(null);
  const portraits = optimistic ?? actress.portraits;

  useEffect(() => { setOptimistic(null); }, [actress.portraits]);

  function handleDrop(target: PortraitSlotKey) {
    const src = dragSlotRef.current;
    setDragSlot(null);
    setOverSlot(null);
    if (!src || src === target) return;
    if (src === "h" || target === "h") return;

    const order: PortraitSlotKey[] = ["1", "2", "3", "4"];
    const keyMap: Record<"1" | "2" | "3" | "4", "p1" | "p2" | "p3" | "p4"> = { "1": "p1", "2": "p2", "3": "p3", "4": "p4" };
    const arr = order.map((k) => portraits[keyMap[k as "1" | "2" | "3" | "4"]]);
    const srcIdx = order.indexOf(src);
    const destIdx = order.indexOf(target);
    const [moved] = arr.splice(srcIdx, 1);
    arr.splice(destIdx, 0, moved);
    setOptimistic({ ...portraits, p1: arr[0], p2: arr[1], p3: arr[2], p4: arr[3] });

    start(async () => {
      await reorderActressPortraitSlots(actress.id, src, target);
      router.refresh();
    });
  }

  return (
    <>
      <div className="flex items-center justify-between mb-4">
        <Link
          href="/actress"
          className="inline-flex items-center gap-1 text-sm text-[var(--color-fg-dim)] hover:text-[var(--color-fg)]"
        >
          <ArrowLeft className="w-4 h-4" /> All Actresses
        </Link>
        <button
          type="button"
          onClick={() => setEditingMeta(true)}
          className="flex items-center gap-1 text-xs px-2.5 py-1 rounded-lg glass glass-hover shrink-0"
        >
          <Pencil className="w-3.5 h-3.5" /> Edit
        </button>
      </div>

      <div
        className="glass rounded-2xl p-card mb-6 flex flex-col gap-section"
        style={ringColor ? { boxShadow: `0 0 0 2px ${ringColor}, 0 0 24px -4px ${ringColor}66` } : undefined}
      >
        <div className="flex items-start justify-between gap-4">
          <div className="min-w-0">
            <h1 className="text-3xl font-semibold tracking-tight text-[var(--color-violet)] break-words">{actress.name}</h1>
            {altChips.length > 0 && (
              <div className="flex flex-wrap gap-1.5 mt-2">
                {altChips.map((c) => (
                  <span
                    key={c.value}
                    title={c.auto ? "Auto-generated reversed name (used for search)" : undefined}
                    className={`text-xs px-2 py-0.5 rounded-full border font-mono ${
                      c.auto
                        ? "border-[var(--color-cyan)]/30 text-[var(--color-cyan)] bg-[var(--color-cyan)]/5"
                        : "border-[var(--color-glass-border)] text-[var(--color-fg-dim)]"
                    }`}
                  >
                    {c.value}
                  </span>
                ))}
              </div>
            )}
          </div>
          <div className="text-right shrink-0">
            <Stat label="Covers" value={coverCount} />
          </div>
        </div>

        <div className="flex flex-wrap gap-3 items-stretch justify-center">
          <PortraitFrame
            slot="1"
            data={portraits.p1}
            width={PORTRAIT_W}
            height={FRAME_H}
            onEdit={() => setEditingSlot("1")}
          />
          <PortraitFrame
            slot="2"
            data={portraits.p2}
            width={PORTRAIT_W}
            height={FRAME_H}
            onEdit={() => setEditingSlot("2")}
          />
          <PortraitFrame
            slot="3"
            data={portraits.p3}
            width={PORTRAIT_W}
            height={FRAME_H}
            onEdit={() => setEditingSlot("3")}
          />
          <PortraitFrame
            slot="4"
            data={portraits.p4}
            width={PORTRAIT_W}
            height={FRAME_H}
            onEdit={() => setEditingSlot("4")}
          />
          <PortraitFrame
            slot="h"
            data={portraits.ph}
            width={HORIZ_W}
            height={FRAME_H}
            onEdit={() => setEditingSlot("h")}
          />
          <BioPanel actress={actress} width={PORTRAIT_W} height={FRAME_H} />
        </div>

        <div className="min-w-0 flex flex-col">
          {allCategories.length > 0 && (
            <div>
              <div className="text-[10px] uppercase tracking-wider font-mono text-[var(--color-fg-muted)] mb-label">Categories</div>
              <div className="flex flex-wrap gap-chip">
                {orderedCategories.map((c) => {
                  const active = activeIds.has(c.id);
                  const color = c.color ?? "#888";
                  return (
                    <button
                      key={c.id}
                      type="button"
                      onClick={() => toggleCat(c.id)}
                      className="flex items-center gap-1.5 text-xs px-2.5 py-1 rounded-full font-mono transition-all"
                      style={
                        active
                          ? { background: `${color}25`, color, border: `1px solid ${color}aa` }
                          : { background: "transparent", color: "var(--color-fg-muted)", border: "1px solid var(--color-glass-border)" }
                      }
                    >
                      <CategoryIcon name={c.icon} className="w-3 h-3" />
                      {c.name}
                    </button>
                  );
                })}
              </div>
            </div>
          )}

          {actress.notes && (
            <p className="text-sm text-[var(--color-fg-dim)] mt-4 leading-relaxed whitespace-pre-wrap max-w-prose">
              {actress.notes}
            </p>
          )}
        </div>
      </div>

      {editingMeta && (
        <ActressMetaEditor
          actressId={actress.id}
          initial={{
            name: actress.name,
            altNames: actress.altNames,
            notes: actress.notes,
            bornOn: actress.bornOn,
            heightCm: actress.heightCm,
            weightKg: actress.weightKg,
            cupSize: actress.cupSize,
          }}
          onClose={() => setEditingMeta(false)}
        />
      )}
      {editingSlot && (
        <ActressPortraitEditor
          actressId={actress.id}
          actressName={actress.name}
          initial={portraits}
          initialSlot={editingSlot}
          onClose={() => setEditingSlot(null)}
        />
      )}
    </>
  );

  function PortraitFrame({
    slot,
    data,
    width,
    height,
    onEdit,
  }: {
    slot: PortraitSlotKey;
    data: ActressAllPortraits[keyof ActressAllPortraits];
    width: number;
    height: number;
    onEdit: () => void;
  }) {
    const reorderable = slot !== "h";
    const isDragging = dragSlot === slot;
    const isDropTarget = reorderable && overSlot === slot && dragSlot !== null && dragSlot !== "h" && dragSlot !== slot;
    return (
      <div
        className="relative shrink-0 rounded-xl overflow-hidden bg-[var(--color-bg-1)] group"
        style={{
          width,
          height,
          cursor: reorderable ? "grab" : undefined,
          opacity: isDragging ? 0.4 : 1,
          outline: isDropTarget ? "2px dashed var(--color-cyan)" : undefined,
          outlineOffset: isDropTarget ? "-2px" : undefined,
          transition: "opacity 120ms ease",
        }}
        draggable={reorderable}
        onDragStart={(e) => {
          if (!reorderable) return;
          dragSlotRef.current = slot;
          e.dataTransfer.effectAllowed = "move";
          e.dataTransfer.setData("text/plain", slot);
          requestAnimationFrame(() => setDragSlotState(slot));
        }}
        onDragEnd={() => { dragSlotRef.current = null; setDragSlotState(null); setOverSlot(null); }}
        onDragOver={(e) => {
          if (!reorderable) return;
          const ds = dragSlotRef.current;
          if (ds && ds !== "h" && ds !== slot) {
            e.preventDefault();
            e.dataTransfer.dropEffect = "move";
          }
        }}
        onDragEnter={() => { if (reorderable) setOverSlot(slot); }}
        onDragLeave={(e) => {
          if (e.currentTarget === e.target) setOverSlot((s) => (s === slot ? null : s));
        }}
        onDrop={(e) => { e.preventDefault(); handleDrop(slot); }}
      >
        {data.path ? (
          /* eslint-disable-next-line @next/next/no-img-element */
          <img
            src={portraitUrl({ path: data.path!, slug: actress.slug, slot })}
            alt=""
            draggable={false}
            className="absolute top-1/2 left-1/2 max-w-none origin-center pointer-events-none"
            style={{
              transform: `translate(-50%, -50%) translate(${data.offsetX}px, ${data.offsetY}px) scale(${data.zoom})`,
              width,
              height: "auto",
            }}
          />
        ) : (
          <div className="absolute inset-0 grid place-items-center">
            <User className="w-12 h-12 text-[var(--color-fg-muted)]" />
          </div>
        )}
        <div className="absolute top-1.5 left-1.5 text-[9px] uppercase tracking-wider font-mono text-white px-1.5 py-0.5 rounded bg-black/60 backdrop-blur-sm pointer-events-none">
          {SLOT_LABEL[slot]}
        </div>
        <div className="absolute inset-0 grid place-items-center bg-black/0 opacity-0 group-hover:opacity-100 group-hover:bg-black/40 transition-all pointer-events-none">
          <button
            type="button"
            onClick={onEdit}
            className="flex items-center gap-1.5 px-2 py-1 rounded-md bg-black/60 text-white text-xs font-medium pointer-events-auto"
            draggable={false}
          >
            <ImageIcon className="w-3.5 h-3.5" /> Edit
          </button>
        </div>
      </div>
    );
  }
}

function BioPanel({
  actress,
  width,
  height,
}: {
  actress: { bornOn: string | null; heightCm: number | null; weightKg: number | null; cupSize: string | null };
  width: number;
  height: number;
}) {
  const age = computeAge(actress.bornOn);
  return (
    <div
      className="shrink-0 rounded-xl bg-[var(--color-bg-1)]/40 border border-[var(--color-glass-border)] p-3 flex flex-col gap-3"
      style={{ width, height }}
    >
      <Section title="Personal">
        <BioRow label="Age" value={age != null ? String(age) : null} />
        <BioRow label="Born" value={actress.bornOn} />
      </Section>
      <Section title="Body">
        <BioRow label="Height" value={actress.heightCm != null ? `${actress.heightCm} cm` : null} />
        <BioRow label="Weight" value={actress.weightKg != null ? `${actress.weightKg} kg` : null} />
        <BioRow label="Cup Size" value={actress.cupSize} />
      </Section>
    </div>
  );
}

function Section({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <div>
      <div className="text-[10px] uppercase tracking-wider font-mono text-[var(--color-cyan)] mb-1.5">{title}</div>
      <div className="space-y-1">{children}</div>
    </div>
  );
}

function BioRow({ label, value }: { label: string; value: string | null }) {
  return (
    <div className="flex items-baseline justify-between gap-3 text-sm">
      <span className="text-[var(--color-fg-muted)]">{label}</span>
      <span className={`font-mono tabular-nums ${value ? "text-[var(--color-fg)]" : "text-[var(--color-fg-muted)]/40"}`}>
        {value ?? "—"}
      </span>
    </div>
  );
}

function Stat({ label, value }: { label: string; value: number }) {
  return (
    <div>
      <div className="text-2xl font-mono font-semibold tabular-nums">{value}</div>
      <div className="text-[10px] uppercase tracking-wider text-[var(--color-fg-muted)]">{label}</div>
    </div>
  );
}
