import type { HandoffRecord, HandoffStatus } from "@openhandoff/shared";

export const HANDOFF_STATUS_GROUPS = ["queued", "running", "idle", "archived", "killed", "error"] as const;

export type HandoffStatusGroup = (typeof HANDOFF_STATUS_GROUPS)[number];

const QUEUED_STATUSES = new Set<HandoffStatus>([
  "init_bootstrap_db",
  "init_enqueue_provision",
  "init_ensure_name",
  "init_assert_name",
  "init_create_sandbox",
  "init_ensure_agent",
  "init_start_sandbox_instance",
  "init_create_session",
  "init_write_db",
  "init_start_status_sync",
  "init_complete",
  "archive_stop_status_sync",
  "archive_release_sandbox",
  "archive_finalize",
  "kill_destroy_sandbox",
  "kill_finalize",
]);

export function groupHandoffStatus(status: HandoffStatus): HandoffStatusGroup {
  if (status === "running") return "running";
  if (status === "idle") return "idle";
  if (status === "archived") return "archived";
  if (status === "killed") return "killed";
  if (status === "error") return "error";
  if (QUEUED_STATUSES.has(status)) return "queued";
  return "queued";
}

function emptyStatusCounts(): Record<HandoffStatusGroup, number> {
  return {
    queued: 0,
    running: 0,
    idle: 0,
    archived: 0,
    killed: 0,
    error: 0,
  };
}

export interface HandoffSummary {
  total: number;
  byStatus: Record<HandoffStatusGroup, number>;
  byProvider: Record<string, number>;
}

export function fuzzyMatch(target: string, query: string): boolean {
  const haystack = target.toLowerCase();
  const needle = query.toLowerCase();
  let i = 0;
  for (const ch of needle) {
    i = haystack.indexOf(ch, i);
    if (i < 0) {
      return false;
    }
    i += 1;
  }
  return true;
}

export function filterHandoffs(rows: HandoffRecord[], query: string): HandoffRecord[] {
  const q = query.trim();
  if (!q) {
    return rows;
  }

  return rows.filter((row) => {
    const fields = [row.branchName ?? "", row.title ?? "", row.handoffId, row.task, row.prAuthor ?? "", row.reviewer ?? ""];
    return fields.some((field) => fuzzyMatch(field, q));
  });
}

export function formatRelativeAge(updatedAt: number, now = Date.now()): string {
  const deltaSeconds = Math.max(0, Math.floor((now - updatedAt) / 1000));
  if (deltaSeconds < 60) return `${deltaSeconds}s`;
  const minutes = Math.floor(deltaSeconds / 60);
  if (minutes < 60) return `${minutes}m`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours}h`;
  const days = Math.floor(hours / 24);
  return `${days}d`;
}

export function summarizeHandoffs(rows: HandoffRecord[]): HandoffSummary {
  const byStatus = emptyStatusCounts();
  const byProvider: Record<string, number> = {};

  for (const row of rows) {
    byStatus[groupHandoffStatus(row.status)] += 1;
    byProvider[row.providerId] = (byProvider[row.providerId] ?? 0) + 1;
  }

  return {
    total: rows.length,
    byStatus,
    byProvider,
  };
}
