import React, { ReactNode, useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";

type NewWindowProps = {
  children: ReactNode;
  title?: string;
  width?: number;
  height?: number;
  left?: number;
  top?: number;
  center?: boolean;
  features?: Partial<{
    toolbar: boolean;
    menubar: boolean;
    scrollbars: boolean;
    resizable: boolean;
    location: boolean;
    status: boolean;
  }>;
  onClose?: () => void;
  copyStyles?: boolean;
  noopener?: boolean;
  className?: string;
  theme?: string | null;
};

export const RenderInNewWindow: React.FC<NewWindowProps> = ({
  children,
  title = "New Window",
  width = 900,
  height = 700,
  left,
  top,
  center = true,
  features,
  onClose,
  copyStyles = true,
  noopener = true,
  className,
  theme = "light",
}) => {
  const [mounted, setMounted] = useState(false);
  const childWindowRef = useRef<Window | null>(null);
  const containerElRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    if (typeof window === "undefined") return;

    const screenLeft = window.screenLeft ?? window.screenX ?? 0;
    const screenTop = window.screenTop ?? window.screenY ?? 0;
    const availWidth = window.outerWidth ?? window.innerWidth;
    const availHeight = window.outerHeight ?? window.innerHeight;

    const finalLeft =
      center && availWidth
        ? Math.max(0, screenLeft + (availWidth - width) / 2)
        : left ?? 100;

    const finalTop =
      center && availHeight
        ? Math.max(0, screenTop + (availHeight - height) / 2)
        : top ?? 100;

    const baseFeatures = [
      `width=${Math.floor(width)}`,
      `height=${Math.floor(height)}`,
      `left=${Math.floor(finalLeft)}`,
      `top=${Math.floor(finalTop)}`,
    ];

    const featureFlags = features ?? {
      toolbar: false,
      menubar: false,
      scrollbars: true,
      resizable: true,
      location: false,
      status: false,
    };

    Object.entries(featureFlags).forEach(([k, v]) =>
      baseFeatures.push(`${k}=${v ? "yes" : "no"}`)
    );

    const newWin = window.open("", "_blank", baseFeatures.join(","));
    if (!newWin) {
      console.warn("Popup blocked or failed to open window.");
      onClose?.();
      return;
    }

    if (noopener) {
      try {
        newWin.opener = null;
      } catch {}
    }

    newWin.document.open();
    newWin.document.write(`<!doctype html>
<html data-theme=${theme}>
  <head>
    <meta charset="utf-8" />
    <title>${title}</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body style="margin:0;"></body>
</html>`);
    newWin.document.close();

    if (copyStyles) {
      const head = newWin.document.head;
      Array.from(document.styleSheets).forEach((styleSheet) => {
        try {
          if ((styleSheet as CSSStyleSheet).cssRules) {
            const newStyleEl = newWin.document.createElement("style");
            const rules = Array.from(
              (styleSheet as CSSStyleSheet).cssRules
            ).map((r) => r.cssText);
            newStyleEl.appendChild(
              newWin.document.createTextNode(rules.join("\n"))
            );
            head.appendChild(newStyleEl);
          }
        } catch {
          const ownerNode = styleSheet.ownerNode as HTMLElement | null;
          if (ownerNode && ownerNode.tagName === "LINK") {
            const link = ownerNode as HTMLLinkElement;
            const newLink = newWin.document.createElement("link");
            newLink.rel = link.rel;
            newLink.href = link.href;
            newLink.media = link.media;
            head.appendChild(newLink);
          }
        }
      });
    }

    const container = newWin.document.createElement("div");
    if (className) container.className = className;
    newWin.document.body.appendChild(container);

    newWin.document.title = title;

    // Handle child window close
    const handleChildUnload = () => {
      onClose?.();
    };
    newWin.addEventListener("beforeunload", handleChildUnload);

    // 👇 Handle parent refresh/close → auto close child
    const handleParentUnload = () => {
      try {
        newWin.close();
      } catch {}
    };
    window.addEventListener("beforeunload", handleParentUnload);

    childWindowRef.current = newWin;
    containerElRef.current = container;
    setMounted(true);

    return () => {
      newWin.removeEventListener("beforeunload", handleChildUnload);
      window.removeEventListener("beforeunload", handleParentUnload);
      try {
        newWin.close();
      } catch {}
      childWindowRef.current = null;
      containerElRef.current = null;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    const w = childWindowRef.current;
    if (w && !w.closed) {
      w.document.title = title;
    }
  }, [title]);

  if (!mounted || !containerElRef.current) return null;

  return createPortal(children, containerElRef.current);
};
