import { useEffect, useRef, useState } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';

/**
 * Same-origin host for the user-management module.
 *
 * The host app (React 19 / Mantine 8 / Tailwind 3) embeds the module (React 18 /
 * Mantine 7 / Tailwind 4) via an iframe so the two never share a React tree,
 * router, or CSS — the version mismatch is fully isolated by the document
 * boundary. The module is built into apps/backoffice/public/_um and served by
 * THIS same server at <origin>/_um/, so there is no second server and no second
 * port. Override the mount path with VITE_USER_MANAGEMENT_BASE (default /_um).
 *
 * SSO: the module and host authenticate against the SAME backend, so the host's
 * token is valid in the module. The module posts `UM_REQUEST_AUTH`; we reply with
 * our stored token. Route-sync mirrors the module's internal route into the host
 * URL (/um/<path>) so a refresh deep-links back to the selected menu.
 */

function readToken(): string | null {
  return (
    localStorage.getItem('fhc-backoffice-auth-token') ??
    (() => {
      const escaped = 'auth-token'.replace(/([.$?*|{}()[\]\\/+^])/g, '\\$1');
      const match = document.cookie.match(new RegExp('(?:^|; )' + escaped + '=([^;]*)'));
      return match ? decodeURIComponent(match[1]) : null;
    })()
  );
}

function readRefreshToken(): string | null {
  return localStorage.getItem('fhc-backoffice-auth-refresh-token') ?? null;
}

export default function UserManagementHostPage() {
  const navigate = useNavigate();
  const location = useLocation();
  const iframeRef = useRef<HTMLIFrameElement>(null);

  // Same-origin sub-path the module is served from (matches the module's Vite
  // `base` + the apps/backoffice/public/_um build). Same origin ⇒ no second port.
  const mountBase = (
    (import.meta.env.VITE_USER_MANAGEMENT_BASE as string | undefined) ?? '/_um'
  ).replace(/\/$/, '');
  const moduleOrigin = window.location.origin;

  // Deep-link: the host route is /um/*, so whatever follows /um is the module's
  // own route. Compute src ONCE (frozen) so later parent-URL updates don't reload.
  const [iframeSrc] = useState(() => {
    const sub = location.pathname.replace(/^\/um(?=\/|$)/, '');
    return mountBase + sub + location.search;
  });

  useEffect(() => {
    const onMessage = (event: MessageEvent) => {
      if (event.origin !== moduleOrigin) return;
      const data = event.data as { type?: string; path?: string } | undefined;
      if (!data) return;

      if (data.type === 'UM_REQUEST_AUTH') {
        const token = readToken();
        const refreshToken = readRefreshToken();
        const target = iframeRef.current?.contentWindow;
        if (token && target) {
          target.postMessage({ type: 'UM_AUTH_TOKEN', token, refreshToken }, moduleOrigin);
        }
        return;
      }

      if (data.type === 'UM_ROUTE_CHANGED' && typeof data.path === 'string') {
        const target = '/um' + data.path;
        if (window.location.pathname + window.location.search !== target) {
          navigate(target, { replace: true });
        }
      }
    };

    window.addEventListener('message', onMessage);
    return () => window.removeEventListener('message', onMessage);
  }, [moduleOrigin, navigate]);

  return (
    <div style={{ position: 'fixed', inset: 0 }}>
      <iframe
        ref={iframeRef}
        title="User Management"
        src={iframeSrc}
        style={{ width: '100%', height: '100%', border: 0, display: 'block' }}
      />
    </div>
  );
}
