import { ProductCard } from "@/components/store/product-card";
import type { Metadata } from "next";
import { headers } from "next/headers";
import { searchSanityProducts } from "@/lib/sanity/queries";
import { getResolvedSiteText } from "@/lib/site-text-server";
import { text } from "@/lib/site-text";
import { consumeMetricRateLimit, getApiMetricsSnapshot, getClientKeyFromHeaders, recordMetricAllowed, recordMetricBlocked } from "@/lib/api-metrics";

const SEARCH_MIN_QUERY_LENGTH = 4;
const SEARCH_MAX_QUERY_LENGTH = 80;

export const metadata: Metadata = {
  title: "Recherche",
  robots: { index: false, follow: false },
};

type Props = {
  searchParams: Promise<{ q?: string }>;
};

function normalizeQuery(query: string) {
  return query.replace(/\s+/g, " ").trim().slice(0, SEARCH_MAX_QUERY_LENGTH);
}

function logSearchPageMetrics(message: string, details: Record<string, unknown>) {
  console.info("[search-page]", message, details);
}

function trackBlockedSearch(details: { ip: string; query: string; queryLength: number; resetInSeconds: number }) {
  const blocked = recordMetricBlocked("searchPage", details.query);
  logSearchPageMetrics("rate_limited", {
    blocked,
    ...details,
  });
}

function trackAllowedSearch(details: { query: string; results: number }) {
  const allowed = recordMetricAllowed("searchPage", details.query);
  const snapshot = getApiMetricsSnapshot();

  if (allowed % 20 === 0) {
    logSearchPageMetrics("traffic_snapshot", {
      allowed,
      blocked: snapshot.metrics.searchPage.blocked,
      ...details,
    });
  }
}

export default async function RecherchePage({ searchParams }: Props) {
  const params = await searchParams;
  const query = normalizeQuery(params.q || "");
  const headersList = await headers();
  const clientKey = getClientKeyFromHeaders({
    forwardedFor: headersList.get("x-forwarded-for"),
    realIp: headersList.get("x-real-ip"),
  });
  const rateLimit = consumeMetricRateLimit("searchPage", clientKey);
  const shouldSearch = query.length >= SEARCH_MIN_QUERY_LENGTH && rateLimit.allowed;
  const [products, siteText] = await Promise.all([
    shouldSearch ? searchSanityProducts(query, 60) : Promise.resolve([]),
    getResolvedSiteText(),
  ]);

  if (query && !rateLimit.allowed) {
    trackBlockedSearch({
      ip: clientKey,
      query,
      queryLength: query.length,
      resetInSeconds: rateLimit.resetInSeconds,
    });
  } else if (shouldSearch) {
    trackAllowedSearch({ query, results: products.length });
  }

  return (
    <div className="space-y-8">
      <header className="rounded-[1.9rem] border border-[#ffdede] bg-[linear-gradient(135deg,#fffafa_0%,#fff0f0_55%,#ffe7e7_100%)] p-6 shadow-[0_20px_42px_rgba(49,18,18,0.1)] md:p-8">
        <p className="text-xs font-semibold uppercase tracking-[0.18em] text-[var(--accent-3)]">{text(siteText, "search.page.eyebrow")}</p>
        <h1 className="mt-2 font-serif text-5xl text-[var(--foreground)] md:text-6xl">{text(siteText, "search.page.title")}</h1>
        <form action="/recherche" method="GET" role="search" className="mt-5 flex w-full max-w-2xl items-center gap-2">
          <label htmlFor="search-page-input" className="sr-only">
            {text(siteText, "search.label")}
          </label>
          <input
            id="search-page-input"
            name="q"
            type="search"
            defaultValue={query}
            placeholder={text(siteText, "search.page.placeholder")}
            className="h-11 w-full rounded-full border border-[#ffd8d8] bg-white px-4 text-sm text-[var(--foreground)] outline-none placeholder:text-[var(--muted)]"
          />
          <button
            type="submit"
            className="inline-flex h-11 items-center justify-center rounded-full bg-[var(--accent-3)] px-5 text-xs font-semibold uppercase tracking-[0.12em] text-white transition hover:bg-[var(--accent-2)]"
          >
            {text(siteText, "search.submit")}
          </button>
        </form>
      </header>

      {!query ? (
        <p className="rounded-2xl border border-[#ffe1e1] bg-[var(--surface)] p-5 text-sm text-[var(--muted)]">
          {text(siteText, "search.page.emptyInput")}
        </p>
      ) : null}

      {query && query.length < SEARCH_MIN_QUERY_LENGTH ? (
        <p className="rounded-2xl border border-[#ffe1e1] bg-[var(--surface)] p-5 text-sm text-[var(--muted)]">
          Saisissez au moins {SEARCH_MIN_QUERY_LENGTH} caractères pour lancer une recherche.
        </p>
      ) : null}

      {query && !rateLimit.allowed ? (
        <p className="rounded-2xl border border-[#ffe1e1] bg-[var(--surface)] p-5 text-sm text-[var(--muted)]">
          Trop de recherches ont été lancées depuis cette adresse. Patientez une minute puis réessayez.
        </p>
      ) : null}

      {shouldSearch ? (
        <p className="text-sm text-[var(--muted)]">
          {products.length} {text(siteText, "search.page.resultsSuffix")}
          {products.length > 1 ? "s" : ""} pour <span className="font-semibold text-[var(--foreground)]">&quot;{query}&quot;</span>.
        </p>
      ) : null}

      {shouldSearch && products.length === 0 ? (
        <p className="rounded-2xl border border-[#ffe1e1] bg-[var(--surface)] p-5 text-sm text-[var(--muted)]">
          {text(siteText, "search.page.noMatch")}
        </p>
      ) : null}

      {products.length > 0 ? (
        <section className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          {products.map((product, index) => (
            <ProductCard key={product._id} product={product} index={index} />
          ))}
        </section>
      ) : null}
    </div>
  );
}
