import { useEffect, useRef, useState } from "react";
import { ArrowUpRight, GitBranch, Lock, Archive, Globe } from "lucide-react";
import { formatDistanceToNow } from "date-fns";
import { de } from "date-fns/locale";
import BorderGlow from "@/components/BorderGlow";
import {
  accentFor,
  monogram,
  STATE_LABELS,
  CATEGORY_LABELS,
  type LiveProject,
} from "@/lib/projects";

/** Breite, mit der die eingebettete Seite gerendert und dann herunterskaliert wird */
const DESIGN_WIDTH = 1280;
const DESIGN_HEIGHT = 800;

/** Iframe erst laden, wenn die Karte in Sichtweite kommt – 100 Karten sollen den Browser nicht killen. */
function useInViewport<T extends HTMLElement>(rootMargin = "300px") {
  const ref = useRef<T>(null);
  const [inView, setInView] = useState(false);

  useEffect(() => {
    const el = ref.current;
    if (!el || inView) return;
    if (typeof IntersectionObserver === "undefined") {
      setInView(true);
      return;
    }
    const observer = new IntersectionObserver(
      (entries) => {
        if (entries.some((e) => e.isIntersecting)) {
          setInView(true);
          observer.disconnect();
        }
      },
      { rootMargin }
    );
    observer.observe(el);
    return () => observer.disconnect();
  }, [inView, rootMargin]);

  return { ref, inView };
}

/** Skalierungsfaktor, damit die 1280px-Seite exakt in die Kachel passt */
function useScaleToWidth<T extends HTMLElement>(designWidth: number) {
  const ref = useRef<T>(null);
  const [scale, setScale] = useState(0.25);

  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const update = () => setScale(el.clientWidth / designWidth);
    update();
    if (typeof ResizeObserver === "undefined") {
      window.addEventListener("resize", update);
      return () => window.removeEventListener("resize", update);
    }
    const observer = new ResizeObserver(update);
    observer.observe(el);
    return () => observer.disconnect();
  }, [designWidth]);

  return { ref, scale };
}

function relativeDate(iso: string | null): string | null {
  if (!iso) return null;
  const date = new Date(iso);
  if (Number.isNaN(date.getTime())) return null;
  return formatDistanceToNow(date, { addSuffix: true, locale: de });
}

const STATE_STYLES: Record<LiveProject["state"], { dot: string; text: string; Icon: typeof Globe }> = {
  live: { dot: "bg-emerald-400", text: "text-emerald-400", Icon: Globe },
  online: { dot: "bg-emerald-400", text: "text-emerald-400", Icon: Globe },
  protected: { dot: "bg-amber-400", text: "text-amber-400", Icon: Lock },
  hosted: { dot: "bg-sky-400", text: "text-sky-400", Icon: Globe },
  repo: { dot: "bg-muted-foreground", text: "text-muted-foreground", Icon: GitBranch },
  archived: { dot: "bg-muted-foreground/60", text: "text-muted-foreground", Icon: Archive },
};

type Props = { project: LiveProject; cardBg: string };

const ProjectCard = ({ project, cardBg }: Props) => {
  const { ref: viewRef, inView } = useInViewport<HTMLAnchorElement>();
  const { ref: frameRef, scale } = useScaleToWidth<HTMLDivElement>(DESIGN_WIDTH);
  const [frameFailed, setFrameFailed] = useState(false);

  const accent = accentFor(project.repo);
  const state = STATE_STYLES[project.state];
  const showFrame = project.embeddable && project.url && inView && !frameFailed;
  const updated = relativeDate(project.lastCommit?.date ?? project.updatedAt);
  const linkUrl = project.reachable && project.url ? project.url : project.repoUrl;

  return (
    <BorderGlow
      edgeSensitivity={30}
      glowColor="40 80 80"
      backgroundColor={cardBg}
      borderRadius={10}
      glowRadius={26}
      glowIntensity={0.7}
      coneSpread={25}
      colors={["#c084fc", "#f472b6", "#38bdf8"]}
    >
      <a
        ref={viewRef}
        href={linkUrl}
        target="_blank"
        rel="noopener noreferrer"
        className="group flex h-full flex-col"
        aria-label={`${project.name} – ${STATE_LABELS[project.state]}`}
      >
        {/* Vorschau: echtes Live-Iframe, sonst Live-Daten-Kachel */}
        <div
          ref={frameRef}
          className="relative aspect-[16/10] w-full overflow-hidden rounded-t-[10px] border-b border-border/60 bg-secondary/30"
        >
          {showFrame ? (
            <iframe
              src={project.url ?? undefined}
              title={project.name}
              loading="lazy"
              tabIndex={-1}
              aria-hidden="true"
              sandbox="allow-scripts allow-same-origin"
              referrerPolicy="no-referrer"
              onError={() => setFrameFailed(true)}
              style={{
                position: "absolute",
                top: 0,
                left: 0,
                width: DESIGN_WIDTH,
                height: DESIGN_HEIGHT,
                border: 0,
                transform: `scale(${scale})`,
                transformOrigin: "top left",
                pointerEvents: "none",
              }}
            />
          ) : (
            <div
              className="absolute inset-0 flex items-center justify-center"
              style={{ background: `linear-gradient(135deg, ${accent.from}, ${accent.to})` }}
            >
              <span className="font-display text-5xl font-medium tracking-tight text-background/80 mix-blend-overlay md:text-6xl">
                {monogram(project.name)}
              </span>
            </div>
          )}

          {/* Status-Badge */}
          <div className="absolute left-3 top-3 flex items-center gap-2 rounded-full bg-background/85 px-3 py-1 backdrop-blur-sm">
            <span className={`h-1.5 w-1.5 rounded-full ${state.dot}`} />
            <span className={`text-[10px] uppercase tracking-wider ${state.text}`}>
              {STATE_LABELS[project.state]}
            </span>
          </div>

          <div className="absolute right-3 top-3 rounded-full bg-background/85 px-3 py-1 text-[10px] uppercase tracking-wider text-muted-foreground backdrop-blur-sm">
            {CATEGORY_LABELS[project.category]}
          </div>
        </div>

        {/* Text */}
        <div className="flex flex-1 flex-col p-5 md:p-6">
          <div className="mb-3 flex items-start justify-between gap-3">
            <h3 className="font-display text-lg font-medium uppercase leading-tight tracking-tight text-foreground transition-colors group-hover:text-muted-foreground md:text-xl">
              {project.name}
            </h3>
            <ArrowUpRight className="mt-0.5 h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-foreground" />
          </div>

          {project.description && (
            <p className="mb-4 line-clamp-2 text-sm leading-relaxed text-muted-foreground">
              {project.description}
            </p>
          )}

          <div className="mt-auto space-y-2 border-t border-border/60 pt-4">
            <div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] uppercase tracking-wider text-muted-foreground">
              <span className="inline-flex items-center gap-1.5">
                <state.Icon className="h-3 w-3" />
                {project.repo}
              </span>
              {project.language && <span>{project.language}</span>}
              {updated && <span>{updated}</span>}
            </div>
            {project.lastCommit?.message && (
              <p className="truncate font-mono text-[11px] text-muted-foreground/80">
                {project.lastCommit.message}
              </p>
            )}
          </div>
        </div>
      </a>
    </BorderGlow>
  );
};

export default ProjectCard;
