import { readAutoPostLogs } from "@/lib/logging/auto-post-logger";
import { getAutoPostLockState, isAutoPostRunInProgress } from "./auto-post-lock";
import {
  ensureScheduledPublishPoller,
  getPollerIntervalMs,
  isPollerStarted,
} from "./cron-poller";
import { readSchedulerHeartbeat } from "./scheduler-heartbeat";
import { formatDuration } from "./next-slot";

export type SchedulerHealthStatus = "running" | "stopped" | "disabled" | "tick_in_progress";

export interface SchedulerHealth {
  status: SchedulerHealthStatus;
  statusLabel: string;
  cronSecretConfigured: boolean;
  internalPollerEnabled: boolean;
  pollerStartedOnWorker: boolean;
  pollerJustStarted: boolean;
  intervalMinutes: number;
  lastTickAt: string | null;
  lastPollerStartAt: string | null;
  minutesSinceLastTick: number | null;
  tickInProgress: boolean;
  lastRunAt: string | null;
}

function minutesSince(iso: string | null | undefined, now: Date): number | null {
  if (!iso) return null;
  const ms = now.getTime() - new Date(iso).getTime();
  if (Number.isNaN(ms) || ms < 0) return null;
  return Math.floor(ms / 60_000);
}

export async function evaluateSchedulerHealth(
  options?: { autoStartPoller?: boolean; now?: Date },
): Promise<SchedulerHealth> {
  const now = options?.now ?? new Date();
  const cronSecretConfigured = Boolean(process.env.CRON_SECRET?.trim());
  const internalPollerEnabled =
    cronSecretConfigured && process.env.DISABLE_INTERNAL_CRON !== "true";
  const intervalMs = getPollerIntervalMs();
  const intervalMinutes = intervalMs / 60_000;
  const staleMs = intervalMs * 2.5;

  let pollerJustStarted = false;
  if (options?.autoStartPoller !== false && internalPollerEnabled) {
    pollerJustStarted = ensureScheduledPublishPoller();
  }

  const tickInProgress = isAutoPostRunInProgress();
  const lockState = getAutoPostLockState();
  const pollerStartedOnWorker = isPollerStarted();

  const heartbeat = await readSchedulerHeartbeat();
  let lastTickAt = heartbeat?.lastTickAt ?? lockState.lastRunAt ?? null;

  if (!lastTickAt) {
    const logs = await readAutoPostLogs({ limit: 30 });
    const recentTick = logs.find(
      (l) =>
        l.event === "auto_post_started" ||
        l.event === "auto_post_tick_completed" ||
        l.event === "outside_schedule_slot",
    );
    lastTickAt = recentTick?.timestamp ?? null;
  }

  const msSinceTick = lastTickAt
    ? now.getTime() - new Date(lastTickAt).getTime()
    : Number.POSITIVE_INFINITY;
  const recentlyActive = msSinceTick < staleMs;
  const minutesSinceLastTick = minutesSince(lastTickAt, now);

  if (!cronSecretConfigured) {
    return {
      status: "disabled",
      statusLabel: "Disabled — set CRON_SECRET on the server",
      cronSecretConfigured,
      internalPollerEnabled,
      pollerStartedOnWorker,
      pollerJustStarted,
      intervalMinutes,
      lastTickAt,
      lastPollerStartAt: heartbeat?.lastPollerStartAt ?? null,
      minutesSinceLastTick,
      tickInProgress,
      lastRunAt: lockState.lastRunAt,
    };
  }

  if (!internalPollerEnabled) {
    return {
      status: "stopped",
      statusLabel: "Internal poller off — use external cron on /api/cron/scheduled-publish",
      cronSecretConfigured,
      internalPollerEnabled,
      pollerStartedOnWorker,
      pollerJustStarted,
      intervalMinutes,
      lastTickAt,
      lastPollerStartAt: heartbeat?.lastPollerStartAt ?? null,
      minutesSinceLastTick,
      tickInProgress,
      lastRunAt: lockState.lastRunAt,
    };
  }

  if (tickInProgress) {
    return {
      status: "tick_in_progress",
      statusLabel: "Running auto-post tick now",
      cronSecretConfigured,
      internalPollerEnabled,
      pollerStartedOnWorker,
      pollerJustStarted,
      intervalMinutes,
      lastTickAt,
      lastPollerStartAt: heartbeat?.lastPollerStartAt ?? null,
      minutesSinceLastTick,
      tickInProgress,
      lastRunAt: lockState.lastRunAt,
    };
  }

  if (recentlyActive || pollerStartedOnWorker || pollerJustStarted) {
    const ago =
      minutesSinceLastTick !== null && minutesSinceLastTick > 0
        ? `last tick ${minutesSinceLastTick}m ago`
        : "active now";
    const label = pollerJustStarted
      ? `Started — checking every ${intervalMinutes} min`
      : `Running (every ${intervalMinutes} min, ${ago})`;

    return {
      status: "running",
      statusLabel: label,
      cronSecretConfigured,
      internalPollerEnabled,
      pollerStartedOnWorker,
      pollerJustStarted,
      intervalMinutes,
      lastTickAt,
      lastPollerStartAt: heartbeat?.lastPollerStartAt ?? null,
      minutesSinceLastTick,
      tickInProgress,
      lastRunAt: lockState.lastRunAt,
    };
  }

  const waitLabel =
    minutesSinceLastTick !== null
      ? `No tick in ${formatDuration(msSinceTick)} — click Start Scheduler below`
      : "Click Start Scheduler below (no server restart needed)";

  return {
    status: "stopped",
    statusLabel: waitLabel,
    cronSecretConfigured,
    internalPollerEnabled,
    pollerStartedOnWorker,
    pollerJustStarted,
    intervalMinutes,
    lastTickAt,
    lastPollerStartAt: heartbeat?.lastPollerStartAt ?? null,
    minutesSinceLastTick,
    tickInProgress,
    lastRunAt: lockState.lastRunAt,
  };
}
