import { useEffect, useMemo, useRef } from "react";
import type { FormEvent } from "react";
import { exactHtmlDocuments } from "./exact-html";
import type { ExactHtmlKey } from "./exact-html";
import type { AuthMode, NavigateFn, Page } from "./route-config";

const fileToPage: Record<string, Page | "login" | "register" | null> = {
  "account.html": "account",
  "asset-factory.html": "assetFactory",
  "image-optimize.html": "imageOptimize",
  "index.html": "dashboard",
  "library.html": "library",
  "login.html": "login",
  "messages.html": "messages",
  "model-photo.html": "modelPhoto",
  "model-photo-demo-a.html": "modelPhotoDemoA",
  "model-photo-demo-b.html": "modelPhotoDemoB",
  "pipeline.html": "pipeline",
  "platform-cover.html": "platformCover",
  "product-create.html": "productCreateUpload",
  "product-create-upload.html": "productCreateUpload",
  "product-detail.html": "productDetail",
  "products.html": "products",
  "projects-new.html": "projectWizard",
  "projects.html": "projects",
  "register.html": "register",
  "settings.html": "settings",
  "team.html": "team"
};

const pageToExactKey: Record<Page, ExactHtmlKey> = {
  dashboard: "dashboard",
  products: "products",
  productDetail: "productDetail",
  productCreateUpload: "productCreateUpload",
  projects: "projects",
  projectWizard: "projectWizard",
  pipeline: "pipeline",
  library: "library",
  account: "account",
  team: "team",
  messages: "messages",
  assetFactory: "assetFactory",
  imageOptimize: "imageOptimize",
  modelPhoto: "modelPhoto",
  modelPhotoDemoA: "modelPhotoDemoA",
  modelPhotoDemoB: "modelPhotoDemoB",
  platformCover: "platformCover",
  settings: "settings",
  settingsNotify: "settings"
};

const exactKeyToPage: Partial<Record<ExactHtmlKey, Page | "login" | "register">> = {
  account: "account",
  assetFactory: "assetFactory",
  dashboard: "dashboard",
  imageOptimize: "imageOptimize",
  library: "library",
  login: "login",
  messages: "messages",
  modelPhoto: "modelPhoto",
  modelPhotoDemoA: "modelPhotoDemoA",
  modelPhotoDemoB: "modelPhotoDemoB",
  pipeline: "pipeline",
  platformCover: "platformCover",
  productCreate: "productCreateUpload",
  productCreateUpload: "productCreateUpload",
  productDetail: "productDetail",
  products: "products",
  projectWizard: "projectWizard",
  projects: "projects",
  register: "register",
  settings: "settings",
  team: "team"
};

const exactKeyToFile: Record<ExactHtmlKey, string> = {
  account: "account.html",
  assetFactory: "asset-factory.html",
  dashboard: "index.html",
  imageOptimize: "image-optimize.html",
  library: "library.html",
  login: "login.html",
  messages: "messages.html",
  modelPhoto: "model-photo.html",
  modelPhotoDemoA: "model-photo-demo-a.html",
  modelPhotoDemoB: "model-photo-demo-b.html",
  pipeline: "pipeline.html",
  platformCover: "platform-cover.html",
  productCreate: "product-create.html",
  productCreateUpload: "product-create-upload.html",
  productDetail: "product-detail.html",
  products: "products.html",
  projectWizard: "projects-new.html",
  projects: "projects.html",
  register: "register.html",
  settings: "settings.html",
  team: "team.html"
};

const liveHydratePages = new Set<ExactHtmlKey>([
  "dashboard",
  "products",
  "productDetail",
  "projectWizard",
  "projects",
  "pipeline",
  "library",
  "account",
  "settings",
  "team"
]);

function routeFromHref(rawHref: string | null) {
  if (!rawHref || rawHref === "#" || rawHref.startsWith("javascript:")) return null;
  const url = new URL(rawHref, "https://airshelf.local/exact/");
  const fileName = url.pathname.split("/").filter(Boolean).pop() || "index.html";
  const page = fileToPage[fileName];
  if (!page) return null;
  const params = new URLSearchParams(url.search);
  return {
    page,
    hash: url.hash || "",
    search: url.search || "",
    productId: params.get("product_id") || undefined,
    projectId: params.get("project_id") || undefined
  };
}

function routeFromInlineAction(action: string | null) {
  if (!action) return null;
  const hrefMatch = action.match(/location\.href\s*=\s*['"]([^'"]+)/);
  if (hrefMatch) return routeFromHref(hrefMatch[1]);
  const hashMatch = action.match(/location\.hash\s*=\s*['"]([^'"]+)/);
  if (hashMatch) return { page: null, hash: hashMatch[1], search: "" };
  return null;
}

function setFrameHeight(frame: HTMLIFrameElement) {
  frame.style.height = `${Math.max(window.innerHeight, 720)}px`;
}

export type ExactDocumentPageProps = {
  pageKey: ExactHtmlKey;
  hash?: string;
  productId?: string;
  projectId?: string;
  navigate?: NavigateFn;
  onAuthModeChange?: (mode: AuthMode) => void;
  onAuthSubmit?: (mode: AuthMode, event: FormEvent<HTMLFormElement>, form: HTMLFormElement) => void;
};

export function exactKeyForPage(page: Page): ExactHtmlKey {
  return pageToExactKey[page] || "dashboard";
}

function contextSearch(pageKey: ExactHtmlKey, productId?: string, projectId?: string) {
  const params = new URLSearchParams();
  if (pageKey === "productDetail" && productId) params.set("product_id", productId);
  if (pageKey === "pipeline" && projectId) params.set("project_id", projectId);
  const text = params.toString();
  return text ? `?${text}` : "";
}

export function ExactDocumentPage({
  pageKey,
  hash,
  productId,
  projectId,
  navigate,
  onAuthModeChange,
  onAuthSubmit
}: ExactDocumentPageProps) {
  const frameRef = useRef<HTMLIFrameElement | null>(null);
  const html = useMemo(() => {
    const context = {
      page: exactKeyToFile[pageKey],
      search: contextSearch(pageKey, productId, projectId),
      hash: hash ? `#${hash.replace(/^#/, "")}` : "",
      liveHydrate: liveHydratePages.has(pageKey)
    };
    return exactHtmlDocuments[pageKey].replace(
      "</head>",
      `<script>window.__AIR_SHELF_EXACT_CONTEXT__=${JSON.stringify(context)};</script></head>`
    );
  }, [hash, pageKey, productId, projectId]);

  useEffect(() => {
    const frame = frameRef.current;
    if (!frame) return;
    const currentFrame: HTMLIFrameElement = frame;

    function onLoad() {
      const doc = currentFrame.contentDocument;
      const win = currentFrame.contentWindow;
      if (!doc || !win) return;

      (win as Window & { __AIR_SHELF_HOST_NAVIGATE__?: (href: string) => void }).__AIR_SHELF_HOST_NAVIGATE__ = (
        href: string
      ) => {
        const hostRoute = routeFromHref(href);
        if (!hostRoute?.page) return;
        if (hostRoute.page === "login" || hostRoute.page === "register") {
          onAuthModeChange?.(hostRoute.page);
          return;
        }
        navigate?.(hostRoute.page, {
          hash: hostRoute.hash || undefined,
          productId: hostRoute.productId || (hostRoute.page === "productDetail" ? productId : undefined),
          projectId: hostRoute.projectId || (hostRoute.page === "pipeline" ? projectId : undefined)
        });
      };

      const applyFrameHash = (nextHash: string) => {
        const cleanHash = nextHash.replace(/^#/, "");
        const stageMatch = cleanHash.match(/^stage-(\d+)$/);
        const pipelineWindow = win as Window & { activateStage?: (stage: number) => void };
        if (pageKey === "pipeline" && stageMatch && typeof pipelineWindow.activateStage === "function") {
          pipelineWindow.activateStage(Number(stageMatch[1]));
          return;
        }
        const settingsWindow = win as Window & { showSection?: (sectionId: string) => void };
        if (pageKey === "settings" && cleanHash.startsWith("sec-") && typeof settingsWindow.showSection === "function") {
          settingsWindow.showSection(cleanHash);
          return;
        }
        doc.getElementById(cleanHash)?.scrollIntoView({ behavior: "smooth", block: "start" });
      };

      if (hash) {
        setTimeout(() => {
          applyFrameHash(hash);
        }, 0);
      }

      const clickHandler = (event: MouseEvent) => {
        const target = event.target as Element | null;
        if (!target) return;

        const syncHashOnlyRoute = (nextHash: string) => {
          const cleanHash = nextHash.replace(/^#/, "");
          applyFrameHash(cleanHash);
          if (exactKeyToPage[pageKey]) {
            const nextUrl = `${window.location.pathname}${window.location.search}#${cleanHash}`;
            window.history.replaceState(null, "", nextUrl);
          }
        };

        const actionNode = target.closest("[onclick]") as HTMLElement | null;
        const actionRoute = routeFromInlineAction(actionNode?.getAttribute("onclick") || null);
        if (actionRoute?.hash && actionRoute.page === null) {
          event.preventDefault();
          event.stopPropagation();
          event.stopImmediatePropagation();
          syncHashOnlyRoute(actionRoute.hash);
          return;
        }
        if (actionRoute?.page) {
          event.preventDefault();
          event.stopPropagation();
          event.stopImmediatePropagation();
          if (actionRoute.page === "login" || actionRoute.page === "register") {
            onAuthModeChange?.(actionRoute.page);
            return;
          }
          navigate?.(actionRoute.page, {
            hash: actionRoute.hash || undefined,
            productId: actionRoute.productId || (actionRoute.page === "productDetail" ? productId || "exact" : undefined),
            projectId: actionRoute.projectId
          });
          return;
        }

        const anchor = target.closest("a[href]") as HTMLAnchorElement | null;
        const rawAnchorHref = anchor?.getAttribute("href") || null;
        if (rawAnchorHref?.startsWith("#")) {
          event.preventDefault();
          event.stopPropagation();
          event.stopImmediatePropagation();
          syncHashOnlyRoute(rawAnchorHref);
          return;
        }
        const anchorRoute = routeFromHref(rawAnchorHref);
        if (!anchorRoute) return;
        event.preventDefault();
        event.stopPropagation();
        if (anchorRoute.page === "login" || anchorRoute.page === "register") {
          onAuthModeChange?.(anchorRoute.page);
          return;
        }
        navigate?.(anchorRoute.page, {
          hash: anchorRoute.hash || undefined,
          productId: anchorRoute.productId || (anchorRoute.page === "productDetail" ? productId || "exact" : undefined),
          projectId: anchorRoute.projectId
        });
      };

      const submitHandler = (event: SubmitEvent) => {
        const form = event.target as HTMLFormElement | null;
        if (!form) return;
        const isLogin = pageKey === "login" && form.id === "login-form";
        const isRegister = pageKey === "register" && form.id === "register-form";
        if (!isLogin && !isRegister) return;
        event.preventDefault();
        event.stopPropagation();
        event.stopImmediatePropagation();
        onAuthSubmit?.(isLogin ? "login" : "register", event as unknown as FormEvent<HTMLFormElement>, form);
      };

      doc.addEventListener("click", clickHandler, true);
      doc.addEventListener("submit", submitHandler, true);
      setFrameHeight(currentFrame);
      const resizeFrame = () => setFrameHeight(currentFrame);
      window.addEventListener("resize", resizeFrame);
      const observer = new ResizeObserver(() => setFrameHeight(currentFrame));
      observer.observe(doc.documentElement);
      observer.observe(doc.body);

      const cleanup = () => {
        doc.removeEventListener("click", clickHandler, true);
        doc.removeEventListener("submit", submitHandler, true);
        window.removeEventListener("resize", resizeFrame);
        observer.disconnect();
      };
      currentFrame.dataset.cleanupKey = String(Date.now());
      (currentFrame as HTMLIFrameElement & { __airshelfCleanup?: () => void }).__airshelfCleanup?.();
      (currentFrame as HTMLIFrameElement & { __airshelfCleanup?: () => void }).__airshelfCleanup = cleanup;
    }

    currentFrame.addEventListener("load", onLoad);
    if (currentFrame.contentDocument?.readyState !== "loading") onLoad();
    return () => {
      currentFrame.removeEventListener("load", onLoad);
      (currentFrame as HTMLIFrameElement & { __airshelfCleanup?: () => void }).__airshelfCleanup?.();
      (currentFrame as HTMLIFrameElement & { __airshelfCleanup?: () => void }).__airshelfCleanup = undefined;
    };
  }, [hash, navigate, onAuthModeChange, onAuthSubmit, pageKey]);

  return (
    <div className="exact-document-route" data-exact-page={pageKey}>
      <iframe
        ref={frameRef}
        title={`Airshelf ${pageKey}`}
        className="exact-document-frame"
        srcDoc={html}
      />
    </div>
  );
}
