import Link from "next/link";
import { ListingCard } from "@/components/cards";
import { PageShell } from "@/components/page";
import {
  CERTS,
  GEM_ORIGINS,
  GEM_TYPES,
  PRICE_BANDS,
  SORTS,
  TREATMENTS,
  WEIGHT_BANDS,
  gemTypeLabel,
  marketHint,
  pricePerCarat,
  searchHref,
  toggleHref,
  type SearchQuery,
} from "@/lib/listings";
import { prisma } from "@/lib/prisma";
import { isWholesale } from "@/lib/roles";
import { readSession } from "@/lib/session";

type SearchParams = Promise<{
  q?: string;
  type?: string;
  origin?: string;
  treatment?: string;
  cert?: string;
  wt?: string;
  price?: string;
  sort?: string;
}>;

const FILTER_ROWS = [
  { field: "origin" as const, label: "Origin", options: GEM_ORIGINS },
  { field: "wt" as const, label: "Weight", options: WEIGHT_BANDS },
  { field: "treatment" as const, label: "Treatment", options: TREATMENTS },
  { field: "cert" as const, label: "Papers", options: CERTS },
  { field: "price" as const, label: "Asking", options: PRICE_BANDS },
];

function ChipRow({
  label,
  current,
  field,
  options,
}: {
  label: string;
  current: SearchQuery;
  field: keyof SearchQuery;
  options: readonly { value: string; label: string }[];
}) {
  return (
    <div className="search-row">
      <p>{label}</p>
      <nav aria-label={label}>
        {options.map((option) => (
          <Link
            key={option.value}
            href={toggleHref(current, field, option.value)}
            className={current[field] === option.value ? "is-on" : undefined}
          >
            {option.label}
          </Link>
        ))}
      </nav>
    </div>
  );
}

export default async function SearchPage({ searchParams }: { searchParams: SearchParams }) {
  const raw = await searchParams;
  const session = await readSession();
  const query: SearchQuery = {
    q: raw.q?.trim() || "",
    type: GEM_TYPES.some((item) => item.value === raw.type) ? raw.type : "",
    origin: GEM_ORIGINS.some((item) => item.value === raw.origin) ? raw.origin : "",
    treatment: TREATMENTS.some((item) => item.value === raw.treatment) ? raw.treatment : "",
    cert: CERTS.some((item) => item.value === raw.cert) ? raw.cert : "",
    wt: WEIGHT_BANDS.some((item) => item.value === raw.wt) ? raw.wt : "",
    price: PRICE_BANDS.some((item) => item.value === raw.price) ? raw.price : "",
    sort: SORTS.some((item) => item.value === raw.sort) ? raw.sort : "",
  };

  const listings = await prisma.listing.findMany({
    include: { seller: { include: { profile: true } } },
  });

  const visible = listings.filter((listing) => !listing.wholesaleOnly || isWholesale(session));
  const weight = WEIGHT_BANDS.find((item) => item.value === query.wt);
  const price = PRICE_BANDS.find((item) => item.value === query.price);
  const term = (query.q || "").toLowerCase();

  const matchesFilters = (listing: (typeof visible)[number], skip?: keyof SearchQuery) => {
    if (skip !== "type" && query.type && listing.gemType !== query.type) return false;
    if (skip !== "origin" && query.origin && listing.origin !== query.origin) return false;
    if (skip !== "treatment" && query.treatment && listing.treatment !== query.treatment) return false;
    if (skip !== "cert" && query.cert && listing.certification !== query.cert) return false;
    if (skip !== "wt" && weight && (listing.weightCt < weight.min || listing.weightCt >= weight.max)) return false;
    if (skip !== "price" && price && (listing.askingPrice < price.min || listing.askingPrice >= price.max)) return false;
    if (term) {
      const blob = [
        listing.title,
        listing.gemType,
        listing.origin,
        listing.color,
        listing.treatment,
        listing.clarity,
        listing.certification,
        listing.seller.name,
        listing.seller.profile?.company,
      ]
        .join(" ")
        .toLowerCase();
      if (!blob.includes(term)) return false;
    }
    return true;
  };

  const matches = visible.filter((listing) => matchesFilters(listing)).sort((a, b) => {
    if (query.sort === "ppc") {
      return pricePerCarat(a.askingPrice, a.weightCt) - pricePerCarat(b.askingPrice, b.weightCt);
    }
    if (query.sort === "weight") return b.weightCt - a.weightCt;
    return a.askingPrice - b.askingPrice;
  });

  const typeCounts = Object.fromEntries(
    [{ value: "", label: "All" }, ...GEM_TYPES].map((item) => [
      item.value || "all",
      visible.filter((listing) => (!item.value || listing.gemType === item.value) && matchesFilters(listing, "type")).length,
    ]),
  );

  const ppc = matches.map((listing) => pricePerCarat(listing.askingPrice, listing.weightCt));
  const avgPpc = ppc.length ? Math.round(ppc.reduce((sum, n) => sum + n, 0) / ppc.length) : 0;

  const active = [
    query.type ? { key: "type" as const, label: gemTypeLabel(query.type) } : null,
    query.origin ? { key: "origin" as const, label: query.origin } : null,
    weight ? { key: "wt" as const, label: weight.label } : null,
    query.treatment ? { key: "treatment" as const, label: query.treatment } : null,
    query.cert ? { key: "cert" as const, label: query.cert } : null,
    price ? { key: "price" as const, label: price.label } : null,
    query.q ? { key: "q" as const, label: `“${query.q}”` } : null,
  ].filter(Boolean) as { key: keyof SearchQuery; label: string }[];

  return (
    <PageShell
      wide
      eyebrow="Inventory"
      title="Find the stone"
      lede="Filter the tray by type, origin, weight, treatment, and papers. Request opens a deal room — no boutique checkout in this mockup."
    >
      <div className="dir-toolbar search-toolbar">
        <form className="dir-search" action="/search">
          {query.type ? <input type="hidden" name="type" value={query.type} /> : null}
          {query.origin ? <input type="hidden" name="origin" value={query.origin} /> : null}
          {query.treatment ? <input type="hidden" name="treatment" value={query.treatment} /> : null}
          {query.cert ? <input type="hidden" name="cert" value={query.cert} /> : null}
          {query.wt ? <input type="hidden" name="wt" value={query.wt} /> : null}
          {query.price ? <input type="hidden" name="price" value={query.price} /> : null}
          {query.sort ? <input type="hidden" name="sort" value={query.sort} /> : null}
          <input
            name="q"
            defaultValue={query.q}
            placeholder="Unheated blue sapphire, 3 ct, GRS…"
            aria-label="Search stones"
          />
          <button className="eg-btn eg-btn-solid" type="submit">
            Find
          </button>
        </form>

        <nav className="floor-tabs dir-tabs" aria-label="Filter by gem type">
          <Link href={searchHref({ ...query, type: "" })} className={!query.type ? "is-on" : undefined}>
            All
            <small>{typeCounts.all}</small>
          </Link>
          {GEM_TYPES.map((item) => (
            <Link
              key={item.value}
              href={toggleHref(query, "type", item.value)}
              className={query.type === item.value ? "is-on" : undefined}
            >
              {item.label}
              <small>{typeCounts[item.value]}</small>
            </Link>
          ))}
        </nav>

        <div className="search-spec">
          {FILTER_ROWS.map((row) => (
            <ChipRow key={row.field} label={row.label} current={query} field={row.field} options={row.options} />
          ))}
        </div>
      </div>

      {active.length ? (
        <div className="search-active">
          {active.map((chip) => (
            <Link key={chip.key} href={toggleHref(query, chip.key, query[chip.key] || "")}>
              {chip.label} ×
            </Link>
          ))}
          <Link href="/search" className="search-clear">
            Clear
          </Link>
        </div>
      ) : null}

      <div className="dir-count">
        <div>
          <h2>{query.type ? gemTypeLabel(query.type) : "On the tray"}</h2>
          <p>
            {matches.length} {matches.length === 1 ? "lot" : "lots"}
            {query.origin ? ` · ${query.origin}` : ""}
          </p>
        </div>
        <nav className="search-sort" aria-label="Sort lots">
          {SORTS.map((item) => (
            <Link
              key={item.value || "asking"}
              href={searchHref({ ...query, sort: item.value })}
              className={(query.sort || "") === item.value ? "is-on" : undefined}
            >
              {item.label}
            </Link>
          ))}
        </nav>
      </div>

      {matches.length ? (
        <div className="search-insight">
          <div>
            <p className="eg-label">Avg asking / ct</p>
            <p>${avgPpc.toLocaleString()}</p>
          </div>
          <div>
            <p className="eg-label">Sellers</p>
            <p>{new Set(matches.map((listing) => listing.sellerId)).size}</p>
          </div>
          <div>
            <p className="eg-label">Market band</p>
            <p>
              ${Math.min(...matches.map((listing) => listing.marketLow)).toLocaleString()}–$
              {Math.max(...matches.map((listing) => listing.marketHigh)).toLocaleString()}
            </p>
          </div>
        </div>
      ) : (
        <p className="dir-empty">No stones in this tray. Clear a filter or try another origin.</p>
      )}

      {matches.length ? (
        <div className="dir-grid">
          {matches.map((listing) => (
            <ListingCard
              key={listing.id}
              href={`/search/${listing.id}`}
              title={listing.title}
              imageUrl={listing.imageUrl}
              gemType={gemTypeLabel(listing.gemType)}
              origin={listing.origin}
              color={listing.color}
              treatment={listing.treatment}
              certification={listing.certification}
              weightCt={listing.weightCt}
              askingPrice={listing.askingPrice}
              seller={listing.seller.name}
              wholesale={listing.wholesaleOnly}
              availability={listing.availability}
              hint={marketHint(listing.askingPrice, listing.marketLow, listing.marketHigh)}
            />
          ))}
        </div>
      ) : null}
    </PageShell>
  );
}
