"use client";

import { useEffect, useRef } from "react";
import { resolveBaseUrl } from "@/lib/api";
import { logger } from "@/lib/logger";
import {
  type OrderStreamEvent,
  type OrderUpdateEventPayload,
} from "@customer-portal/domain/orders";

type OrderUpdateHandler = (event: OrderUpdateEventPayload) => void;

export function useOrderUpdates(orderId: string | undefined, onUpdate: OrderUpdateHandler) {
  const handlerRef = useRef<OrderUpdateHandler>(onUpdate);

  useEffect(() => {
    handlerRef.current = onUpdate;
  }, [onUpdate]);

  useEffect(() => {
    if (!orderId) {
      return undefined;
    }

    let isCancelled = false;
    let eventSource: EventSource | null = null;
    let reconnectTimeout: ReturnType<typeof setTimeout> | null = null;

    const baseUrl = resolveBaseUrl();
    const url = new URL(`/api/orders/${orderId}/events`, baseUrl).toString();

    const connect = () => {
      if (isCancelled) return;

      logger.debug("Connecting to order updates stream", { orderId, url });
      const es = new EventSource(url, { withCredentials: true });
      eventSource = es;

      const handleMessage = (event: MessageEvent<string>) => {
        try {
          const parsed = JSON.parse(event.data) as OrderStreamEvent;
          if (!parsed || typeof parsed !== "object") {
            return;
          }

          if (parsed.event === "order.update") {
            const payload = parsed.data as OrderUpdateEventPayload;
            handlerRef.current?.(payload);
          }
        } catch (error) {
          logger.warn("Failed to parse order update event", { orderId, error });
        }
      };

      const handleError = (error: Event) => {
        logger.warn("Order updates stream disconnected", { orderId, error });
        es.close();
        eventSource = null;

        if (!isCancelled) {
          reconnectTimeout = setTimeout(connect, 5000);
        }
      };

      es.addEventListener("message", handleMessage as EventListener);
      es.onerror = handleError;
    };

    connect();

    return () => {
      isCancelled = true;
      if (eventSource) {
        eventSource.close();
      }
      if (reconnectTimeout) {
        clearTimeout(reconnectTimeout);
      }
    };
  }, [orderId]);
}
