"use client";

import { useSearchParams } from "next/navigation";
import { useCallback, useEffect, useRef } from "react";
import { useDispatch } from "react-redux";

import { apiRequest } from "@/services/http.universal";
import { handleLoginSuccess, logoutAndRedirect } from "@/utils/auth.client";
import { setCookies } from "@/utils/cookies";

/**
 * Allowed origin for postMessage communication with the browser extension.
 * Set NEXT_PUBLIC_EXTENSION_ORIGIN=chrome-extension://<EXTENSION_ID> in .env.
 * Falls back to "*" only when the variable is not configured (local dev without extension).
 */
const EXTENSION_ORIGIN =
  process.env.NEXT_PUBLIC_EXTENSION_ORIGIN?.trim() || null;

/**
 * ExtensionAuthPage
 * - Handles Extension → Website login/logout via hidden iframe
 * - Fully edge-case-proof and generic
 * - Uses localStorage or postMessage for extension JWT
 */
export default function ExtensionAuthPage() {
  const searchParams = useSearchParams();
  const dispatch = useDispatch();
  // Captures the origin of the extension's first postMessage so we can reply
  // to that exact origin rather than broadcasting with "*".
  const extensionOriginRef = useRef<string | null>(null);

  const postToParent = useCallback((payload: Record<string, unknown>) => {
    // Priority: configured env var → captured ref origin → dev wildcard
    const target = EXTENSION_ORIGIN ?? extensionOriginRef.current ?? null;
    if (target) {
      window.parent.postMessage(payload, target);
    } else {
      console.warn(
        "[extension-auth] NEXT_PUBLIC_EXTENSION_ORIGIN is not set. " +
          "Using '*' as postMessage target — do NOT deploy this to production.",
      );
      window.parent.postMessage(payload, "*");
    }
  }, []);

  const handleExtensionLogin = useCallback(async () => {
    try {
      // Step 1: Get extension token
      // Priority: URL query param (set by offscreen iframe URL) → postMessage token → localStorage
      const extensionToken =
        searchParams.get("token") ||
        (window as any)?.EXTENSION_TOKEN ||
        localStorage.getItem("extension_jwt");
      console.log("Extension token obtained:", extensionToken);
      if (!extensionToken) {
        console.error("No extension token found");
        return;
      }

      const res = await apiRequest("GET", "/auth/me", null, {
        headers: { Authorization: `Bearer ${extensionToken}` },
      });

      console.log("Extension session validation response:", res);

      if (!res.success) {
        console.error("Extension session validation failed");
        postToParent({
          type: "WEBSITE_LOGIN_COMPLETE",
          success: false,
          message: "Extension session validation failed",
        });
        return;
      }

      const apiData = res?.data;

      // Step 3: Call existing login handler
      handleLoginSuccess(apiData, dispatch, setCookies, true);

      // Normalize the same way handleLoginSuccess does so field names match.
      const data = apiData?.data ?? apiData ?? {};
      const {
        access_token,
        refresh_token,
        expires_in = 0,
        user_id,
        full_name = "",
        email = "",
        is_plus_user = false,
        is_banner_user = false,
        phone_number = "",
      } = data;

      // Step 4: Notify extension with all cookie key/value pairs so it can
      // call chrome.cookies.set() for every name — keys match what the website
      // stores via setCookies() / clearAuthCookies().
      postToParent({
        type: "WEBSITE_LOGIN_COMPLETE",
        success: true,
        cookiesToBeSet: {
          token: access_token,
          refresh_token: refresh_token ?? null,
          id: user_id,
          full_name,
          email,
          is_plus_user,
          is_banner_user,
          logged_in: true,
          phone_number,
          user_type: is_plus_user ? "PLUS" : "NORMAL",
        },
        expires_in, // seconds — use to compute expirationDate in chrome.cookies.set()
      });

      // Step 5: Optional silent redirect to dashboard or stay on page
      // router.replace("/user/dashboard");
    } catch (err) {
      console.error("Extension login failed", err);
      // Notify extension of failure
      postToParent({
        type: "WEBSITE_LOGIN_COMPLETE",
        success: false,
        message: err instanceof Error ? err.message : "Unknown error",
        err,
      });
    }
  }, [searchParams, dispatch, postToParent]);

  const handleExtensionLogout = useCallback(async () => {
    try {
      // Notify the extension FIRST so the WEBSITE_LOGOUT_COMPLETE message is
      // guaranteed to be delivered before logoutAndRedirect() performs its
      // hard redirect (window.location.replace("/")), which would otherwise
      // unload this offscreen iframe and drop the message.
      postToParent({ type: "WEBSITE_LOGOUT_COMPLETE" });

      // Call website logout (clears cookies, Redux, storage, then redirects)
      await logoutAndRedirect();
    } catch (err) {
      console.error("Extension logout failed", err);
    }
  }, [postToParent]);

  useEffect(() => {
    const action = searchParams.get("action");

    if (action === "login") {
      handleExtensionLogin();
    } else if (action === "logout") {
      handleExtensionLogout();
    }

    // Step 6: Listen for postMessage from extension (optional trigger)
    const receiveMessage = (event: MessageEvent) => {
      // SECURITY: reject messages from any origin that is not the configured
      // extension origin. When NEXT_PUBLIC_EXTENSION_ORIGIN is set (production)
      // only that exact origin is accepted. In development (no env var) the
      // check is skipped so local testing without a real extension still works.
      if (EXTENSION_ORIGIN && event.origin !== EXTENSION_ORIGIN) return;

      // Record where this message came from so postToParent can reply to it.
      if (event.origin && event.origin !== "null") {
        extensionOriginRef.current = event.origin;
      }

      const { type, token } = event.data || {};
      if (type === "EXTENSION_LOGIN_READY" && token) {
        (window as any).EXTENSION_TOKEN = token;
        handleExtensionLogin();
      } else if (type === "EXTENSION_LOGOUT_READY") {
        handleExtensionLogout();
      }
    };

    window.addEventListener("message", receiveMessage);
    return () => window.removeEventListener("message", receiveMessage);
  }, [searchParams, handleExtensionLogin, handleExtensionLogout]);

  return null; // hidden iframe
}
