import type { WorkerJobRecord } from "@/lib/types";

type WorkerProgressShape = {
  phase?: string;
  message?: string;
  total_chunks?: number;
  processed_chunks?: number;
  total_batches?: number;
  current_batch?: number;
  batch_size?: number;
  percent?: number;
};

function asRecord(value: unknown): Record<string, unknown> | null {
  if (!value || typeof value !== "object" || Array.isArray(value)) {
    return null;
  }

  return value as Record<string, unknown>;
}

function asNumber(value: unknown): number | null {
  if (typeof value === "number" && Number.isFinite(value)) {
    return value;
  }

  if (typeof value === "string") {
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : null;
  }

  return null;
}

function asText(value: unknown): string | null {
  return typeof value === "string" && value.trim() ? value.trim() : null;
}

export function getWorkerProgress(
  job: Pick<WorkerJobRecord, "result">,
): WorkerProgressShape | null {
  const result = asRecord(job.result);
  if (!result) {
    return null;
  }

  const nested = asRecord(result.progress);
  const source = nested ?? result;
  const percent = asNumber(source.percent);
  const totalChunks = asNumber(source.total_chunks);
  const processedChunks = asNumber(source.processed_chunks);
  const totalBatches = asNumber(source.total_batches);
  const currentBatch = asNumber(source.current_batch);
  const batchSize = asNumber(source.batch_size);
  const phase = asText(source.phase) ?? asText(result.phase) ?? undefined;
  const message = asText(source.message) ?? asText(result.message) ?? undefined;

  if (
    percent === null &&
    totalChunks === null &&
    processedChunks === null &&
    totalBatches === null &&
    currentBatch === null &&
    batchSize === null &&
    !phase &&
    !message
  ) {
    return null;
  }

  return {
    phase,
    message,
    total_chunks: totalChunks ?? undefined,
    processed_chunks: processedChunks ?? undefined,
    total_batches: totalBatches ?? undefined,
    current_batch: currentBatch ?? undefined,
    batch_size: batchSize ?? undefined,
    percent: percent ?? undefined,
  };
}

export function formatWorkerProgress(
  job: Pick<WorkerJobRecord, "result">,
): string | null {
  const progress = getWorkerProgress(job);
  if (!progress) {
    return null;
  }

  const percentText =
    typeof progress.percent === "number"
      ? `${Math.max(0, Math.min(100, Math.round(progress.percent)))}%`
      : null;
  const chunkText =
    typeof progress.processed_chunks === "number" &&
    typeof progress.total_chunks === "number"
      ? `${progress.processed_chunks}/${progress.total_chunks} 分块`
      : null;
  const batchText =
    typeof progress.current_batch === "number" &&
    typeof progress.total_batches === "number" &&
    progress.total_batches > 0
      ? `第 ${progress.current_batch}/${progress.total_batches} 批`
      : null;

  const details = [percentText, chunkText, batchText]
    .filter(Boolean)
    .join(" · ");

  if (progress.message && details) {
    return `${progress.message} ${details}`;
  }

  return progress.message ?? (details || null);
}

export function getWorkerProgressPercent(
  job: Pick<WorkerJobRecord, "result">,
): number | null {
  const progress = getWorkerProgress(job);
  if (typeof progress?.percent !== "number") {
    return null;
  }

  return Math.max(0, Math.min(100, Math.round(progress.percent)));
}
