import { useEffect, useRef } from "react";
import { useSmartlinkParentMessaging } from "./messaging/useSmartlinkParentMessaging";
import { createSmartlinkMessage } from "./messaging/types";
import {
  SMARTLINK_BASE_URL,
  PrePaymentMethod,
  getEnviroment,
  Environment,
} from "./helpers";

/**
 * String announcement sent to the iframe so the child can detect that this
 * parent speaks the structured SMARTLINK_* protocol.
 *
 * Sent as a plain string so legacy children (if any) survive it.
 * Repeated on a short interval until the child responds with SMARTLINK_READY,
 * which proves it received the announcement and is proceeding with the
 * structured handshake.
 *
 * ── LEGACY DEPRECATION: delete the announcement effect ──
 */
const STRUCTURED_ANNOUNCEMENT = "SMARTLINK_STRUCTURED";
const ANNOUNCEMENT_INTERVAL_MS = 500;
const ANNOUNCEMENT_MAX_ATTEMPTS = 10;

const useSmartlinkComponent = (
  prePaymentMethod: PrePaymentMethod,
  onPaymentSuccess: (successPaymentData: string) => void,
  env: Environment | undefined,
) => {
  const iframeRef = useRef<HTMLIFrameElement | null>(null);
  const enviroment = env ?? getEnviroment(window?.location?.href ?? "");
  const pluginUrl = SMARTLINK_BASE_URL[enviroment];
  const pluginOrigin = pluginUrl ? new URL(pluginUrl).origin : null;

  const { sendInit, sendMessage, subscribeTo } = useSmartlinkParentMessaging({
    pluginUrl,
    iframeRef,
  });

  /*
   * ── LEGACY DEPRECATION: delete this effect ──
   *
   * Announce to the child that this parent is structured.
   * Repeats until SMARTLINK_READY arrives (proving the child heard us)
   * or max attempts are exhausted.
   */
  useEffect(() => {
    if (!pluginOrigin) return;

    let attempts = 0;
    const interval = setInterval(() => {
      attempts++;
      iframeRef.current?.contentWindow?.postMessage(
        STRUCTURED_ANNOUNCEMENT,
        pluginOrigin,
      );
      if (attempts >= ANNOUNCEMENT_MAX_ATTEMPTS) clearInterval(interval);
    }, ANNOUNCEMENT_INTERVAL_MS);

    // Also fire one immediately (interval waits one tick before first call).
    iframeRef.current?.contentWindow?.postMessage(
      STRUCTURED_ANNOUNCEMENT,
      pluginOrigin,
    );

    const unsubscribe = subscribeTo("SMARTLINK_READY", () => {
      clearInterval(interval);
    });

    return () => {
      clearInterval(interval);
      unsubscribe();
    };
  }, [pluginOrigin, subscribeTo]);

  useEffect(() => {
    return subscribeTo("SMARTLINK_READY", ({ requestId }, _event, isValid) => {
      if (!isValid) {
        console.warn(
          "[SMARTLINK_HANDSHAKE] Origin validation failed — not sending SMARTLINK_INIT",
        );
        return;
      }

      sendInit(requestId);
    });
  }, [subscribeTo, sendInit]);

  useEffect(() => {
    return subscribeTo(
      "SMARTLINK_STEP_COMPLETE",
      (message, _event, isValid) => {
        if (!isValid) {
          console.warn(
            "[SMARTLINK_STEP_COMPLETE] Origin validation failed — not sending SMARTLINK_STEP_COMPLETE",
          );
          return;
        }
        const {
          success,
          source,
          payment_data,
          consent_data: _consent,
          uploader_data: _uploader,
        } = message?.payload ?? {};
        if (!success || source !== "payments") return;

        onPaymentSuccess(payment_data || JSON.stringify({}));
      },
    );
  }, [subscribeTo, onPaymentSuccess]);

  useEffect(() => {
    return subscribeTo(
      "SMARTLINK_PREPAYMENT_METHOD",
      async (message, _event, isValid) => {
        if (!isValid) {
          console.warn(
            "[SMARTLINK_PREPAYMENT_METHOD] Origin validation failed — not sending SMARTLINK_PREPAYMENT_METHOD_COMPLETE",
          );
          return;
        }
        const { requestId, payload } = message;
        const { quote_id } = payload ?? {};

        try {
          const { success, payment_id } = await prePaymentMethod(
            quote_id ?? "",
          );
          sendMessage(
            createSmartlinkMessage(
              "SMARTLINK_PREPAYMENT_METHOD_COMPLETE",
              { success, payment_id },
              requestId,
            ),
          );
        } catch (err) {
          sendMessage(
            createSmartlinkMessage(
              "SMARTLINK_PREPAYMENT_METHOD_COMPLETE",
              {
                success: false,
                payment_id: "",
                error: err instanceof Error ? err.message : String(err),
              },
              requestId,
            ),
          );
        }
      },
    );
  }, [subscribeTo, sendMessage, prePaymentMethod]);

  return {
    iframeRef,
    enviroment,
  };
};

export default useSmartlinkComponent;
