"use client";

import { useParams } from "next/navigation";
import { useEffect, useLayoutEffect, useRef, useState } from "react";
import { Loader2 } from "lucide-react";
import { useAnatomy } from "@/components/project/use-anatomy";
import { usePreviewBridge } from "@/components/project/preview-bridge-context";
import { usePreviewToolbarStore } from "@/components/project/preview-toolbar/preview-toolbar-state";

const SAME_ORIGIN_SANDBOX =
  "allow-scripts allow-forms allow-same-origin allow-popups allow-modals allow-downloads" as const;

function sandboxIframe(src: string, origin: string): boolean {
  if (!src.startsWith("http://") && !src.startsWith("https://")) return true;
  try {
    return origin.length > 0 && new URL(src).origin === origin;
  } catch {
    return true;
  }
}

export default function PreviewTab() {
  const params = useParams();
  const projectId = params.projectId as string;
  const { anatomy, loading } = useAnatomy(projectId, { pollMs: 0 });

  const previews = anatomy?.hosting.previews ?? [];
  // Find the port 3000 preview if it exists, otherwise fall back to null
  const primaryPreview = previews.find((p) => p.port === 3000);

  const [iframeSrc, setIframeSrc] = useState<string | null>(null);
  const iframeDomRef = useRef<HTMLIFrameElement | null>(null);
  const bridge = usePreviewBridge();
  const origin = typeof window !== "undefined" ? window.location.origin : "";

  const deviceMode = usePreviewToolbarStore((s) => s.deviceMode);
  const refreshKey = usePreviewToolbarStore((s) => s.refreshKey);

  useLayoutEffect(() => {
    setIframeSrc(primaryPreview?.url ?? null);
  }, [primaryPreview?.url]);

  useEffect(() => {
    if (!bridge || !iframeSrc || !iframeDomRef.current) return;
    bridge.registerPreviewIframe(iframeDomRef.current, iframeSrc);
  }, [bridge, iframeSrc]);

  return (
    <div style={canvas}>
      <div
        style={{
          flex: 1,
          minHeight: 0,
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
        }}
      >
        <div
          style={{
            ...(deviceMode === "desktop" ? desktopFrame : mobileFrame),
            transition: "all 0.3s ease",
          }}
        >
          {deviceMode === "mobile" && <MobileChrome />}

          {loading && !iframeSrc ? (
            <div style={loaderWrap}>
              <Loader2
                className="animate-spin"
                style={{ width: 22, height: 22, color: "#9c9590" }}
              />
            </div>
          ) : iframeSrc ? (
            <iframe
              key={`${iframeSrc}-${refreshKey}`}
              src={iframeSrc}
              title="Preview"
              ref={(el) => {
                iframeDomRef.current = el;
                if (el) bridge?.registerPreviewIframe(el, iframeSrc);
              }}
              onLoad={() => bridge?.notifyPreviewIframeLoaded()}
              style={{
                ...iframeStyle,
                borderRadius: deviceMode === "mobile" ? 44 : 0,
              }}
              {...(sandboxIframe(iframeSrc, origin)
                ? { sandbox: SAME_ORIGIN_SANDBOX }
                : {})}
            />
          ) : (
            <div style={loaderWrap}>
              <p style={emptyText}>Preview not running on port 3000.</p>
              <p style={{ ...emptyText, fontSize: "0.75rem", marginTop: 8 }}>
                Ask the AI to start the dev server.
              </p>
            </div>
          )}

          {deviceMode === "mobile" && <div style={homeIndicator} aria-hidden />}
        </div>
      </div>
    </div>
  );
}

const canvas: React.CSSProperties = {
  flex: 1,
  minHeight: 0,
  width: "100%",
  display: "flex",
  flexDirection: "column",
  alignSelf: "stretch",
  boxSizing: "border-box",
  padding: "14px 16px 18px",
  background: "linear-gradient(165deg, #faf8f5 0%, #f4f0ea 42%, #ebe7df 100%)",
};

const desktopFrame: React.CSSProperties = {
  flex: 1,
  width: "100%",
  height: "100%",
  display: "flex",
  flexDirection: "column",
  borderRadius: 14,
  overflow: "hidden",
  background: "#fff",
  border: "1px solid rgba(26, 26, 26, 0.07)",
  boxShadow:
    "0 1px 2px rgba(26, 26, 26, 0.04), 0 12px 40px rgba(26, 26, 26, 0.07), inset 0 1px 0 rgba(255, 255, 255, 0.85)",
};

const mobileFrame: React.CSSProperties = {
  position: "relative",
  width: 390,
  height: 844,
  flexShrink: 0,
  borderRadius: 56,
  overflow: "hidden",
  background: "#000",
  border: "14px solid #1a1a1a",
  boxShadow:
    "0 0 0 1px rgba(255,255,255,0.1) inset, 0 24px 60px rgba(26, 26, 26, 0.15)",
  display: "flex",
  flexDirection: "column",
};

const iframeStyle: React.CSSProperties = {
  flex: 1,
  width: "100%",
  height: "100%",
  border: "none",
  background: "#fff",
  pointerEvents: "auto",
};

const loaderWrap: React.CSSProperties = {
  flex: 1,
  display: "flex",
  flexDirection: "column",
  alignItems: "center",
  justifyContent: "center",
  background: "#fff",
};

const emptyText: React.CSSProperties = {
  margin: 0,
  fontSize: "0.85rem",
  color: "#a1a1aa",
};

function MobileChrome() {
  return (
    <div style={notchWrap}>
      <div style={notch} />
    </div>
  );
}

const notchWrap: React.CSSProperties = {
  position: "absolute",
  top: 0,
  left: 0,
  right: 0,
  height: 32,
  display: "flex",
  justifyContent: "center",
  zIndex: 10,
  pointerEvents: "none",
};

const notch: React.CSSProperties = {
  width: 120,
  height: 30,
  background: "#1a1a1a",
  borderBottomLeftRadius: 20,
  borderBottomRightRadius: 20,
};

const homeIndicator: React.CSSProperties = {
  position: "absolute",
  bottom: 8,
  left: "50%",
  transform: "translateX(-50%)",
  width: 140,
  height: 5,
  borderRadius: 10,
  background: "rgba(255, 255, 255, 0.4)",
  mixBlendMode: "difference",
  zIndex: 10,
  pointerEvents: "none",
};
