// One typed client method per RFQ/Quotation endpoint (docs/11-BACKEND-PHASE1.md §3.2, FR-PROC-02).
// In-memory sample data (lib/api/mock-data.ts) — no backend API calls.
import { PagedResponse } from "@/types/common"
import {
  CreateQuotationRequest,
  CreateRfqRequest,
  Quotation,
  Rfq,
  RfqComparison,
  RfqComparisonLine,
  RfqSummary,
} from "@/types/procurement"
import {
  allocateQuotationId,
  allocateRfqId,
  allocateRfqLineId,
  mockDelay,
  mockQuotations,
  mockRfqs,
} from "@/lib/api/mock-data"

function toSummary(r: Rfq): RfqSummary {
  return {
    rfqId: r.rfqId,
    docNo: r.docNo,
    requisitionId: r.requisitionId,
    status: r.status,
    vendorIds: r.vendorIds,
    createdAt: r.createdAt,
  }
}

export const rfqsApi = {
  list(): Promise<PagedResponse<RfqSummary>> {
    const items = [...mockRfqs].sort((a, b) => b.rfqId - a.rfqId).map(toSummary)
    return mockDelay({
      items,
      pagination: { page: 1, pageSize: 20, totalItems: items.length, totalPages: 1 },
    })
  },

  get(rfqId: number): Promise<Rfq> {
    const r = mockRfqs.find((x) => x.rfqId === rfqId)
    if (!r) return Promise.reject(new Error(`Mock RFQ ${rfqId} not found`))
    return mockDelay(r)
  },

  create(request: CreateRfqRequest): Promise<Rfq> {
    if (request.vendorIds.length === 0) return Promise.reject(new Error("Select at least one vendor."))
    if (request.lines.length === 0) return Promise.reject(new Error("Add at least one line."))
    const rfq: Rfq = {
      rfqId: allocateRfqId(),
      docNo: "",
      requisitionId: request.requisitionId ?? null,
      status: "Open",
      vendorIds: request.vendorIds,
      createdAt: new Date().toISOString(),
      lines: request.lines.map((l) => ({ rfqLineId: allocateRfqLineId(), itemId: l.itemId, qty: l.qty })),
    }
    rfq.docNo = `RFQ-2026-${String(rfq.rfqId).padStart(5, "0")}`
    mockRfqs.push(rfq)
    return mockDelay(rfq)
  },

  addQuotation(rfqId: number, request: CreateQuotationRequest): Promise<Quotation> {
    const rfq = mockRfqs.find((x) => x.rfqId === rfqId)
    if (!rfq) return Promise.reject(new Error(`Mock RFQ ${rfqId} not found`))
    if (!rfq.vendorIds.includes(request.vendorId)) {
      return Promise.reject(new Error("This vendor was not invited to the RFQ."))
    }
    const quotation: Quotation = {
      quotationId: allocateQuotationId(),
      rfqId,
      vendorId: request.vendorId,
      createdAt: new Date().toISOString(),
      lines: request.lines,
    }
    mockQuotations.push(quotation)
    return mockDelay(quotation)
  },

  comparison(rfqId: number): Promise<RfqComparison> {
    const rfq = mockRfqs.find((x) => x.rfqId === rfqId)
    if (!rfq) return Promise.reject(new Error(`Mock RFQ ${rfqId} not found`))
    const quotations = mockQuotations.filter((q) => q.rfqId === rfqId)

    const lines: RfqComparisonLine[] = rfq.lines.map((rfqLine) => ({
      itemId: rfqLine.itemId,
      qty: rfqLine.qty,
      cells: quotations
        .map((q) => {
          const line = q.lines.find((l) => l.itemId === rfqLine.itemId)
          return line ? { vendorId: q.vendorId, unitPrice: line.unitPrice, leadDays: line.leadDays } : null
        })
        .filter((c): c is { vendorId: number; unitPrice: number; leadDays: number } => c !== null),
    }))

    return mockDelay({ rfqId, vendorIds: rfq.vendorIds, lines })
  },
}
