import { z } from "zod";
import type { Adapter } from "../adapter";
import type { AdapterResult, Panel } from "../schema";
import { readLandqState, type LandqStateOptions } from "../activity/sources/landq-state";

const DEFAULT_INTERVAL_MS = 8_000;

const TicketSchema = z.object({
  ticket: z.string(),
  branch: z.string().nullable(),
  gateClass: z.string().nullable(),
  ownerPid: z.number().int().nullable(),
  enqueuedAt: z.string().nullable(),
  waitSeconds: z.number().int().nonnegative().nullable(),
  queueDepthAtArrival: z.number().int().nonnegative().nullable(),
  position: z.number().int().positive(),
  ownerLockHeld: z.boolean().nullable(),
  malformed: z.boolean(),
});

const RepoStateSchema = z.object({
  repoRoot: z.string(),
  project: z.string(),
  status: z.enum(["ok", "absent", "error"]),
  queueDepth: z.number().int().nonnegative(),
  waiting: z.array(TicketSchema),
  waitingComplete: z.boolean(),
  conductorHeld: z.boolean().nullable(),
  conductorHolderPid: z.number().int().nullable(),
  conductorHolderAgeSeconds: z.number().nullable(),
  conductorComplete: z.boolean(),
});

export const LandqStatePanelDataSchema = z.object({
  repos: z.array(RepoStateSchema),
});

export type LandqStatePanelData = z.infer<typeof LandqStatePanelDataSchema>;

export interface LandqStateAdapterOptions {
  id?: string;
  interval?: number;
  landqStateOptions?: LandqStateOptions;
}

/** Live land-queue state (who is waiting, who holds the conductor) for the /ci page. Read-only. */
export function createLandqStateAdapter(options: LandqStateAdapterOptions = {}): Adapter {
  const id = options.id ?? "landq-state";

  return {
    id,
    interval: options.interval ?? DEFAULT_INTERVAL_MS,
    async poll(): Promise<AdapterResult> {
      const state = readLandqState(options.landqStateOptions);
      const panelData = LandqStatePanelDataSchema.parse(state);
      const panels: Panel[] = [{ id, ts: new Date().toISOString(), data: panelData }];
      return { items: [], panels };
    },
  };
}
