import { getHostQuotePollIntervalMs } from "@/lib/constants/host-public-api";
import { QUOTE_TIMEOUT_MS } from "@/lib/constants/quote";
import { prisma } from "@/lib/prisma";
import {
  serializeQuoteDetail,
  type QuoteDetailResponse,
} from "@/modules/quote/quote-serializer";

function sleep(ms: number): Promise<void> {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

export class HostQuoteWaitError extends Error {
  constructor(
    message: string,
    readonly code: "QUOTE_NOT_FOUND" | "QUOTE_TIMEOUT" | "QUOTE_FAILED",
    readonly detail?: QuoteDetailResponse,
  ) {
    super(message);
    this.name = "HostQuoteWaitError";
  }
}

/** 服务端轮询 DB，直至报价完成或超时（供宿主同步接口使用） */
export async function waitForQuoteDetail(
  quoteId: string,
  customerId: string,
  options?: { timeoutMs?: number },
): Promise<QuoteDetailResponse> {
  const timeoutMs = options?.timeoutMs ?? QUOTE_TIMEOUT_MS;
  const deadline = Date.now() + timeoutMs;

  while (Date.now() < deadline) {
    const record = await prisma.quoteRecord.findFirst({
      where: { quoteId, customerId, isDeleted: false },
    });

    if (!record) {
      throw new HostQuoteWaitError("报价不存在", "QUOTE_NOT_FOUND");
    }

    const detail = serializeQuoteDetail(record);
    if (detail.status === "processing") {
      const remaining = deadline - Date.now();
      if (remaining <= 0) {
        break;
      }
      await sleep(Math.min(getHostQuotePollIntervalMs(), remaining));
      continue;
    }

    if (detail.status === "failed") {
      throw new HostQuoteWaitError(
        detail.error_message ?? "询价失败",
        "QUOTE_FAILED",
        detail,
      );
    }

    if (detail.status === "expired") {
      throw new HostQuoteWaitError("报价已过期", "QUOTE_FAILED", detail);
    }

    return detail;
  }

  throw new HostQuoteWaitError("询价超时，请稍后重试", "QUOTE_TIMEOUT");
}
