import { useCallback, useEffect, useRef, useState } from "react";
import {
  getTruckLaneScheduleClient,
  listTruckLaneSchedulesClient,
  pendingTruckLaneScheduleShopIdsClient,
} from "@/app/api/shop/client";
import {
  collectFailedTruckRowIdsFromSchedules,
  filterFailedSchedules,
} from "@/components/Shop/scheduleClientHelpers";

export function useRouteBoardScheduleIndicators(options?: {
  pollMs?: number;
  applyingPollMs?: number;
  paused?: boolean;
}) {
  const pollMs = options?.pollMs ?? 60_000;
  const applyingPollMs = options?.applyingPollMs ?? 5_000;
  const paused = options?.paused ?? false;
  const [hasApplyingSchedule, setHasApplyingSchedule] = useState(false);

  const [pendingScheduleShopIds, setPendingScheduleShopIds] = useState<
    Set<number>
  >(new Set());
  const [lockedScheduleShopIds, setLockedScheduleShopIds] = useState<
    Set<number>
  >(new Set());
  const [failedScheduleShopIds, setFailedScheduleShopIds] = useState<
    Set<number>
  >(new Set());
  const [failedScheduleCount, setFailedScheduleCount] = useState(0);

  const refreshScheduleIndicators = useCallback(async () => {
    try {
      const [pendingIds, scheduleList] = await Promise.all([
        pendingTruckLaneScheduleShopIdsClient(),
        listTruckLaneSchedulesClient(
          ["PENDING", "APPLYING", "FAILED", "PARTIAL"],
          200,
        ),
      ]);
      setPendingScheduleShopIds(new Set(pendingIds.truckRowIds ?? []));
      setLockedScheduleShopIds(
        new Set(pendingIds.lockedTruckRowIds ?? pendingIds.truckRowIds ?? []),
      );

      const failedSchedules = filterFailedSchedules(scheduleList);
      setFailedScheduleCount(failedSchedules.length);
      const needsLineWarm = failedSchedules.filter(
        (s) => !s.lineCounts || (s.lineCounts.failed ?? 0) > 0,
      );
      const details = await Promise.all(
        needsLineWarm.map((s) =>
          getTruckLaneScheduleClient(s.id).catch(() => null),
        ),
      );
      setFailedScheduleShopIds(
        collectFailedTruckRowIdsFromSchedules(failedSchedules, details),
      );
      setHasApplyingSchedule(
        scheduleList.some((s) => String(s.status).toUpperCase() === "APPLYING"),
      );
    } catch (e) {
      console.warn("refreshScheduleIndicators failed", e);
    }
  }, []);

  const pausedRef = useRef(paused);
  pausedRef.current = paused;

  useEffect(() => {
    if (paused) return;
    void refreshScheduleIndicators();
    const intervalMs = hasApplyingSchedule ? applyingPollMs : pollMs;
    const timer = window.setInterval(() => {
      if (pausedRef.current) return;
      void refreshScheduleIndicators();
    }, intervalMs);
    return () => window.clearInterval(timer);
  }, [paused, pollMs, applyingPollMs, hasApplyingSchedule, refreshScheduleIndicators]);

  return {
    pendingScheduleShopIds,
    lockedScheduleShopIds,
    failedScheduleShopIds,
    failedScheduleCount,
    refreshScheduleIndicators,
  };
}
