import Link from "next/link";
import { ArrowLeft, MapPin } from "lucide-react";
import { customerApi } from "@/lib/api/customer";
import { requireServerToken } from "@/lib/auth/server";
import { orNotFound } from "@/lib/api/notFound";
import { getSiteConfig } from "@/lib/api/site";
import type { ApiBidding, ApiLiveOffer, ApiWalletSummary } from "@/lib/api/types";
import { formatDateTime } from "@/lib/utils";
import AcceptQuotation from "./AcceptQuotation";
import RequirementSpec from "@/components/rfq/RequirementSpec";
import LiveOfferPanel from "@/components/rfq/LiveOfferPanel";
import PriceOptionBadge from "@/components/rfq/PriceOptionBadge";
import StatusBadge from "@/components/ui/StatusBadge";

type PageProps = {
  params: Promise<{ id: string }>;
};

/**
 * Statuses are free text written by the admin panel, and rows created before the
 * wording was corrected still read "Enquiry Send To Seller".
 */
function statusLabel(status: string | null | undefined): string {
  return (status ?? "—").replace(/\bSend To Seller\b/i, "Sent To Seller");
}


type AddressLike = {
  address_line_one?: string | null;
  address_line_two?: string | null;
  city?: string | null;
  state?: string | null;
  pincode?: string | null;
  pin_code?: string | null;
};

function renderAddress(a: unknown): string {
  if (!a) return "—";
  if (typeof a === "string") return a;
  const obj = (Array.isArray(a) ? a[0] : a) as AddressLike;
  const parts = [obj.address_line_one, obj.address_line_two, obj.city, obj.state, obj.pincode ?? obj.pin_code].filter(Boolean);
  return parts.length ? parts.join(", ") : "—";
}

/** Bids and wallet are supporting data: if either fails the enquiry still renders. */
async function loadBids(token: string, id: number): Promise<ApiBidding[]> {
  try {
    const r = await customerApi.enquiryBidding(token, id);
    return r.data ?? [];
  } catch {
    return [];
  }
}

async function loadWallet(token: string): Promise<ApiWalletSummary | null> {
  try {
    return await customerApi.walletSummary(token);
  } catch {
    return null;
  }
}

/**
 * The auction snapshot. Fetched alongside everything else so the live panel
 * paints populated instead of flashing a spinner, then the client takes over
 * polling from there.
 */
async function loadLive(token: string, id: number): Promise<ApiLiveOffer | null> {
  try {
    return await customerApi.enquiryLive(token, id);
  } catch {
    return null;
  }
}

/**
 * Server-rendered enquiry detail.
 *
 * The client version ran three requests in two waves: `enquiry` + `bidding`
 * after hydration, then `walletSummary` only once the accept modal mounted —
 * i.e. behind both the first fetch *and* a user click. All three are now issued
 * together during SSR, so the browser receives a fully populated page and the
 * modal opens with balances already in hand.
 */
export default async function EnquiryDetailPage({ params }: PageProps) {
  const { id } = await params;
  const token = await requireServerToken(`/rfq/${id}`);
  const enquiryId = Number(id);

  const [enq, bids, wallet, live, site] = await Promise.all([
    // Another company's RFQ id → the 404 page, not "Something went wrong".
    orNotFound(customerApi.enquiry(token, enquiryId)),
    loadBids(token, enquiryId),
    loadWallet(token),
    loadLive(token, enquiryId),
    // The booking / cancellation rule shown at checkout (4.1).
    getSiteConfig({ next: { revalidate: 300 } }),
  ]);

  if (!enq) return null;

  const isOrdered = (enq.status ?? "").toLowerCase() === "ordered";

  return (
    <div className="space-y-4">
      <Link href="/rfq" className="inline-flex items-center gap-1 text-sm text-gray-600 hover:text-[#CC1414]">
        <ArrowLeft className="h-4 w-4" /> Back to enquiries
      </Link>

      <div className="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-100">
        <div className="flex flex-wrap items-start justify-between gap-4">
          <div>
            <h1 className="text-2xl font-bold text-gray-900">{enq.product?.name ?? "Enquiry"}</h1>
            <p className="text-sm text-gray-500">Reference: {enq.unique_id}</p>
            <p className="text-sm text-gray-500">
              Brand: {enq.brand?.name ?? "—"} · From: {enq.origin_city ?? "—"}
            </p>
            {enq.price_option && (
              <p className="mt-1 flex flex-wrap items-center gap-1.5 text-sm text-gray-500">
                Price option: <PriceOptionBadge value={enq.price_option} showHint />
              </p>
            )}
            {enq.order_id && (
              <p className="mt-1 text-sm text-emerald-700">
                Order placed: <Link href={enq.order_db_id ? `/orders/${enq.order_db_id}` : "/orders"} className="font-medium underline">{enq.order_id}</Link>
              </p>
            )}
          </div>
          <StatusBadge kind="rfq" code={enq.status_code} label={enq.status_label ?? statusLabel(enq.status)} className="px-3 py-1" />
        </div>
      </div>

      {/* The live auction: progress, best F.O.R price, and the order button.
          Absent only on enquiries raised before bidding existed, which still
          fall through to the quotation list below. */}
      {live && <LiveOfferPanel enquiryId={enquiryId} initial={live} wallet={wallet} bookingPolicy={site.legal.bookingPolicy} />}

      {/* What the buyer asked for — sizes, quantities, quality, packaging. */}
      <RequirementSpec
        variation={enq.variation}
        quality={enq.quality}
        packaging={enq.packaging_charge}
      />

      {/* The individual quotations behind that best price.
          Collapsed by default once the live panel is carrying the headline:
          leaving both expanded put two competing "accept" paths on one screen. */}
      {bids.length > 0 ? (
        <details className="group rounded-xl bg-white shadow-sm ring-1 ring-gray-100" open={!live}>
          <summary className="flex cursor-pointer items-center justify-between gap-3 p-6 text-lg font-semibold text-gray-900 marker:content-['']">
            All Quotations Received
            <span className="text-xs font-normal text-gray-500">
              {bids.length} response{bids.length === 1 ? "" : "s"} · click to {live ? "expand" : "collapse"}
            </span>
          </summary>
          <div className="px-6 pb-6">
            <AcceptQuotation bids={bids} wallet={wallet} enquiryId={enquiryId} disabled={isOrdered} bookingPolicy={site.legal.bookingPolicy} />
          </div>
        </details>
      ) : (
        !live && (
          <div className="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-100">
            <h2 className="mb-4 text-lg font-semibold text-gray-900">Quotations Received</h2>
            <div className="rounded-lg bg-gray-50 p-6 text-center text-sm text-gray-500">
              Awaiting seller responses. We&apos;ll notify you when quotations arrive.
            </div>
          </div>
        )
      )}

      <div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
        <Card title="Purpose">{enq.purpose ?? "—"}</Card>
        <Card title="Description">{enq.description ?? "—"}</Card>
        <Card title="Payment Mode">
          {enq.payment_mode ?? "—"} {enq.credit_day ? `(${enq.credit_day} days)` : ""}
        </Card>
        <Card title="Price Range">{enq.price ?? "—"}</Card>
        <Card title="Billing Address" icon={<MapPin className="h-4 w-4" />}>
          {renderAddress(enq.billing_address)}
        </Card>
        <Card title="Delivery Address" icon={<MapPin className="h-4 w-4" />}>
          {renderAddress(enq.delivery_address)}
        </Card>
      </div>

      {Array.isArray(enq.history) && enq.history.length > 0 && (
        <div className="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-100">
          <h2 className="mb-3 text-sm font-semibold uppercase tracking-wide text-gray-500">Timeline</h2>
          <ol className="space-y-2 text-sm">
            {(enq.history as Array<{ status: string; created_at: string }>).map((h, i) => (
              <li key={i} className="flex items-center gap-3">
                <span className="h-2 w-2 rounded-full bg-[#CC1414]" />
                <span className="font-medium text-gray-900">{statusLabel(h.status)}</span>
                {/* IST-pinned: formatted on the server now, so an unpinned
                    formatter would render the container's timezone. */}
                <span className="text-xs text-gray-500">{formatDateTime(h.created_at)}</span>
              </li>
            ))}
          </ol>
        </div>
      )}
    </div>
  );
}

function Card({ title, children, icon }: { title: string; children: React.ReactNode; icon?: React.ReactNode }) {
  return (
    <div className="rounded-xl bg-white p-5 shadow-sm ring-1 ring-gray-100">
      <div className="mb-2 flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wide text-gray-500">
        {icon}
        {title}
      </div>
      <div className="break-words text-sm text-gray-700">{children}</div>
    </div>
  );
}
