import Link from "next/link";
import { formatDateTime, formatRelativeAge } from "@/lib/utils";
import { notFound } from "next/navigation";
import type { Metadata } from "next";
import { ArrowRight, ChevronRight, MapPin } from "lucide-react";

import { catalogApi } from "@/lib/api/catalog";
import { ApiException } from "@/lib/api/client";
import type { ApiProductOffer } from "@/lib/api/types";
import SafeImage from "@/components/ui/SafeImage";
import ProductPhoto from "@/components/ui/ProductPhoto";
import NoData from "@/components/ui/NoData";
import { formatAmount, formatPrice, priceHeadline } from "@/lib/pricing/forPrice";
import PincodeCitySearch from "@/components/products/PincodeCitySearch";

type Props = {
  params: Promise<{ slug: string }>;
  searchParams: Promise<{ city?: string; state?: string }>;
};

/**
 * Cacheable so the `generateMetadata` + page pair collapses into one upstream
 * call, and tagged with the same key as the detail page so one `revalidateTag`
 * from the seller dashboard clears both. `revalidatePath` could not: this page
 * renders per `?city=` and that call ignores search params.
 */
async function loadOffers(slug: string, city?: string, state?: string) {
  try {
    return await catalogApi.productOffers(
      slug,
      { city, state },
      { next: { revalidate: 60, tags: [`product-${slug}`] } }
    );
  } catch (err) {
    if (err instanceof ApiException && err.status === 404) return null;
    throw err;
  }
}

/**
 * One offer's price block, obeying the same switches as the detail page it
 * links to: the seller decides which of ex-works / F.O.R / F.O.B this listing
 * publishes, and the card is named after whichever leads.
 *
 * The build-up line underneath only appears when both of its halves are
 * published — quoting "₹49,890 ex-works + ₹1,000 freight" under a card whose
 * seller withheld the ex-works price would hand it back.
 */
function OfferPrice({ offer, unitName }: { offer: ApiProductOffer; unitName: string }) {
  const headline = priceHeadline(
    offer.display,
    {
      exWorks: offer.ex_works_price,
      forPrice: offer.for_price,
      basic: offer.base_price,
    },
    offer.city,
    offer.price_mode
  );

  const showEx = offer.display?.show_ex_price ?? true;
  const showFor = (offer.display?.show_for_price ?? true) && offer.price_mode !== "ex_works";
  // No freight line in Ex-Works mode: there is no destination to carry it to.
  const hasFreight = showFor && offer.freight_charges > 0;

  return (
    <div className="mt-auto rounded-xl bg-gray-50 p-3">
      <div className="flex items-baseline justify-between gap-2">
        <span className="text-xs text-gray-400">{headline.label}</span>
        <span className="text-lg font-black text-[#CC1414]">
          {formatPrice(headline.amount)}
          {/* Matches `formatPrice`, which reads any falsy amount as "On
              Request" — a unit suffix on that would read as a price. */}
          {Boolean(headline.amount) && (
            <span className="text-xs font-medium text-gray-400"> / {unitName}</span>
          )}
        </span>
      </div>
      {hasFreight && (
        <p className="mt-1 text-right text-[11px] text-gray-400">
          {showEx
            ? `${formatAmount(offer.ex_works_price)} ex-works + ${formatAmount(offer.freight_charges)} freight`
            : `includes ${formatAmount(offer.freight_charges)} freight`}
        </p>
      )}
      <p className="mt-1 text-[11px] text-gray-400">
        GST {offer.gst}% &amp; other charges included
      </p>
    </div>
  );
}

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { slug } = await params;
  const payload = await loadOffers(slug);
  if (!payload) return { title: "Product Not Found – Biznie" };
  return {
    title: `${payload.product.name} – Seller Offers | Biznie`,
    description: `Compare live F.O.R prices for ${payload.product.name} from verified sellers on Biznie.`,
  };
}

export default async function ProductOffersPage({ params, searchParams }: Props) {
  const { slug } = await params;
  const { city, state } = await searchParams;

  const payload = await loadOffers(slug, city, state);
  if (!payload) notFound();

  const { product, offers, destinations } = payload;
  const unitName = product.unit?.name || "Ton";
  const categoryName = product.category?.name || "General";

  const detailHref = (offerId: number) => {
    const query = new URLSearchParams({ offer: String(offerId) });
    if (city) query.set("city", city);
    if (state) query.set("state", state);
    return `/products/${product.slug}?${query.toString()}`;
  };

  return (
    <div className="min-h-screen bg-gray-50">
      <div className="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
        <nav className="mb-5 flex flex-wrap items-center gap-1.5 text-xs text-gray-400">
          <Link href="/" className="hover:text-[#CC1414]">
            Home
          </Link>
          <ChevronRight size={12} />
          <Link href="/products" className="hover:text-[#CC1414]">
            Products
          </Link>
          <ChevronRight size={12} />
          <span>{categoryName}</span>
          <ChevronRight size={12} />
          <span className="font-medium text-gray-600">{product.name}</span>
        </nav>

        {/* Product header */}
        <div className="mb-6 flex flex-col gap-4 rounded-2xl border border-gray-100 bg-white p-5 shadow-sm sm:flex-row sm:items-center">
          <div className="relative h-28 w-28 shrink-0 overflow-hidden rounded-xl bg-gray-50">
            <SafeImage
              src={product.thumbnail || "/logo.png"}
              alt={product.name}
              fill
              sizes="112px"
              className="object-contain"
            />
          </div>
          <div className="flex-1">
            <span className="mb-2 inline-block rounded-full bg-gray-100 px-2.5 py-1 text-xs font-semibold text-gray-600">
              {categoryName}
            </span>
            <h1 className="text-xl font-black text-gray-900 md:text-2xl">{product.name}</h1>
            <p className="mt-1 text-sm text-gray-500">
              {offers.length > 0
                ? `${offers.length} live ${offers.length === 1 ? "offer" : "offers"} · prices include GST, loading & insurance`
                : "No live offers right now"}
              {product.min_order_qty > 0 && ` · MOQ ${product.min_order_qty} ${unitName}`}
            </p>
          </div>
          <Link
            href={`/rfq/new?product_id=${product.id}`}
            className="shrink-0 rounded-lg bg-[#CC1414] px-5 py-2.5 text-center text-sm font-semibold text-white transition hover:bg-[#a30f0f]"
          >
            Get Best Price (RFQ)
          </Link>
        </div>

        {/* Destination filter */}
        {destinations.length > 0 && (
          <div className="mb-6 rounded-2xl border border-gray-100 bg-white p-4 shadow-sm">
            <div className="mb-3 flex flex-wrap items-center justify-between gap-2">
              <p className="text-xs font-semibold text-gray-700">
                <MapPin size={13} className="mr-1 inline text-[#CC1414]" />
                Delivery city — freight is added to the F.O.R price
              </p>
              <PincodeCitySearch basePath={`/products/${product.slug}/sellers`} destinations={destinations} />
            </div>
            <div className="flex flex-wrap gap-2">
              <Link
                href={`/products/${product.slug}/sellers`}
                className={`rounded-lg border px-3 py-1.5 text-xs font-medium transition ${
                  !city
                    ? "border-[#CC1414] bg-red-50 text-[#CC1414]"
                    : "border-gray-200 bg-white text-gray-600 hover:border-gray-300"
                }`}
              >
                Ex-Works only
              </Link>
              {destinations.map((destination) => (
                <Link
                  key={`${destination.city}-${destination.state}`}
                  href={`/products/${product.slug}/sellers?city=${encodeURIComponent(
                    destination.city
                  )}&state=${encodeURIComponent(destination.state)}`}
                  className={`rounded-lg border px-3 py-1.5 text-xs font-medium transition ${
                    city === destination.city
                      ? "border-[#CC1414] bg-red-50 text-[#CC1414]"
                      : "border-gray-200 bg-white text-gray-600 hover:border-gray-300"
                  }`}
                >
                  {destination.label ?? destination.city}
                </Link>
              ))}
            </div>
          </div>
        )}

        {offers.length === 0 ? (
          <NoData
            title="No live offers"
            message="No seller has published a live price for this product yet. Raise an RFQ and our team will source quotes for you."
            action={
              <Link
                href={`/rfq/new?product_id=${product.id}`}
                className="rounded-lg bg-[#CC1414] px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-[#a30f0f]"
              >
                Raise an RFQ
              </Link>
            }
          />
        ) : (
          <div className="grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3">
            {offers.map((offer) => (
              <Link
                key={offer.id}
                href={detailHref(offer.id)}
                className="card-hover group flex flex-col overflow-hidden rounded-2xl border border-gray-100 bg-white shadow-sm"
              >
                <div className="relative aspect-square overflow-hidden bg-white">
                  <ProductPhoto
                    src={offer.thumbnail || product.thumbnail}
                    alt={offer.name}
                    sizes="(max-width: 1024px) 50vw, 33vw"
                  />
                </div>

                <div className="flex flex-1 flex-col p-5">
                  <h2 className="mb-3 truncate font-bold text-gray-900 transition-colors group-hover:text-[#CC1414]">
                    {offer.name}
                  </h2>

                  <dl className="mb-4 space-y-1.5 text-xs">
                    <div className="flex justify-between gap-3">
                      <dt className="text-gray-400">Brand</dt>
                      <dd className="truncate font-medium text-gray-700">{offer.brand || "--"}</dd>
                    </div>
                    <div className="flex justify-between gap-3">
                      <dt className="text-gray-400">Quality</dt>
                      <dd className="truncate font-medium text-gray-700">
                        {offer.quality[0] || "--"}
                      </dd>
                    </div>
                    <div className="flex justify-between gap-3">
                      <dt className="text-gray-400">Location</dt>
                      <dd className="truncate font-medium text-gray-700">
                        {offer.city ? `Ex-${offer.city}` : "--"}
                      </dd>
                    </div>
                    {offer.moq && (
                      <div className="flex justify-between gap-3">
                        <dt className="text-gray-400">MOQ</dt>
                        <dd className="truncate font-medium text-gray-700">
                          {offer.moq} {offer.moq_unit || unitName}
                        </dd>
                      </div>
                    )}
                  </dl>

                  <OfferPrice offer={offer} unitName={unitName} />

                  <div className="mt-3 flex items-center justify-between">
                    <span className="text-[11px] text-gray-400">
                      {offer.price_updated_at ? `Updated ${formatRelativeAge(offer.price_updated_at)}` : offer.last_updated ? `Updated ${offer.last_updated}` : ""}
                      {offer.valid_till && ` · Valid till ${formatDateTime(offer.valid_till)}`}
                    </span>
                    <span className="flex items-center gap-1 text-xs font-semibold text-[#CC1414] transition-all group-hover:gap-2">
                      View Details <ArrowRight size={12} />
                    </span>
                  </div>
                </div>
              </Link>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}
