// Backend content is fetched only when a request arrives.
export const dynamic = 'force-dynamic';

import Link from 'next/link';
import type { Metadata } from 'next';
import { paths } from '@justice-choice/seo-engine';
import { api } from '@/lib/api';
import { staticMetadata } from '@/lib/meta';
import { fmtNumber } from '@/lib/format';
import type { SearchResponse } from '@/lib/types';
import { LawyerListItem } from '@/components/LawyerItems';
import { SearchBox } from '@/components/SearchBox';
import { SearchFilters, type FilterValues } from '@/components/SearchFilters';
import { Pagination } from '@/components/Pagination';
import { Beacon } from '@/components/Beacon';
import { SaveSearch } from '@/components/SaveSearch';
import { ArrowRightIcon, SearchIcon, SparklesIcon, TrendingUpIcon, XIcon } from '@/components/Icons';

// Faceted search results are never indexed (§20 control faceted URLs)
export const metadata: Metadata = staticMetadata({
  title: 'Search Lawyers',
  description: 'Search the Justice Choice directory by name, city, practice area or language and filter for verified licences and experience.',
  path: '/search/',
  index: false,
});

type SP = Record<string, string | undefined>;
const KEYS = ['q', 'city', 'practiceArea', 'language', 'verified', 'minExperience', 'sort', 'country'] as const;
const SUGGESTED = ['Divorce lawyers in New York', 'Immigration lawyers in Houston', 'Criminal defense in Chicago', 'Estate planning in Miami'];

export default async function SearchPage({ searchParams }: { searchParams: Promise<SP> }) {
  const sp = await searchParams;
  const qs = new URLSearchParams();
  for (const k of KEYS) if (sp[k]) qs.set(k, sp[k]!);
  const page = Math.max(1, Math.floor(Number(sp.page)) || 1);
  qs.set('page', String(page));
  qs.set('pageSize', '20');
  const d = await api<SearchResponse>(`/search?${qs}`, { revalidate: 60 });
  const it = d.interpreted;

  // What the query was understood as becomes explicit filter state, so the controls and the results agree
  const values: FilterValues = {
    city: sp.city ?? it?.city?.slug,
    practiceArea: sp.practiceArea ?? it?.practiceArea?.slug,
    language: sp.language ?? it?.language?.slug,
    minExperience: sp.minExperience,
    verified: sp.verified,
    sort: sp.sort,
  };
  const textQuery = it ? it.text : (sp.q ?? '');
  const nameOf = {
    city: d.facets.cities.find((c) => c.slug === values.city)?.name ?? it?.city?.name ?? values.city,
    practiceArea: d.facets.practiceAreas.find((c) => c.slug === values.practiceArea)?.name ?? it?.practiceArea?.name ?? values.practiceArea,
    language: d.facets.languages.find((c) => c.slug === values.language)?.name ?? it?.language?.name ?? values.language,
  };

  /** URL for the current state with some keys changed; any change resets to page 1 */
  const link = (patch: Partial<Record<(typeof KEYS)[number] | 'page', string | undefined>>) => {
    const n = new URLSearchParams();
    const base: Record<string, string | undefined> = { ...values, q: textQuery || undefined, country: sp.country };
    for (const k of [...KEYS, 'page'] as const) {
      const v = k in patch ? patch[k] : k === 'page' ? undefined : base[k];
      if (v && !(k === 'sort' && v === 'relevance')) n.set(k, v);
    }
    const s = n.toString();
    return s ? `/search/?${s}` : '/search/';
  };

  const chips = [
    values.city && { key: 'city', label: nameOf.city, href: link({ city: undefined }) },
    values.practiceArea && { key: 'practiceArea', label: nameOf.practiceArea, href: link({ practiceArea: undefined }) },
    values.language && { key: 'language', label: `Speaks ${nameOf.language}`, href: link({ language: undefined }) },
    values.minExperience && { key: 'minExperience', label: `${values.minExperience}+ years`, href: link({ minExperience: undefined }) },
    values.verified === 'true' && { key: 'verified', label: 'Verified only', href: link({ verified: undefined }) },
    textQuery && { key: 'q', label: `“${textQuery}”`, href: link({ q: undefined }) },
  ].filter(Boolean) as { key: string; label: string; href: string }[];

  const cityForRanking = it?.city ?? null;
  const rankingHref = cityForRanking && values.practiceArea && values.city === cityForRanking.slug ? paths.cityPractice(cityForRanking.countrySlug, cityForRanking.slug, values.practiceArea) : null;
  const first = (page - 1) * d.pageSize + 1;
  const last = Math.min(d.total, page * d.pageSize);

  return (
    <div className="mx-auto max-w-6xl px-4 py-10 sm:px-6">
      <Beacon event="search" />
      <header className="max-w-2xl">
        <p className="eyebrow">
          <SearchIcon className="h-3.5 w-3.5" /> Directory search
        </p>
        <h1 className="mt-2 font-serif text-3xl font-semibold tracking-tight sm:text-4xl">Search lawyers</h1>
        <div className="mt-5">
          <SearchBox defaultValue={sp.q ?? ''} />
        </div>
      </header>

      {it && (it.city || it.practiceArea || it.language) && (
        <div className="fade-up mt-5 flex max-w-2xl flex-wrap items-center gap-x-3 gap-y-2 rounded-xl border border-ledger/25 bg-ledger-tint px-4 py-3 text-sm text-ink-2">
          <SparklesIcon className="h-4 w-4 text-ledger" />
          <span>
            Showing{' '}
            <strong className="font-semibold text-ink">
              {[it.language && `${it.language.name}-speaking`, it.practiceArea ? `${it.practiceArea.name.toLowerCase()} lawyers` : 'lawyers', it.city && `in ${it.city.name}`].filter(Boolean).join(' ')}
            </strong>
            {it.text && (
              <>
                {' '}
                matching <strong className="font-semibold text-ink">“{it.text}”</strong>
              </>
            )}
            .
          </span>
          {rankingHref && (
            <Link href={rankingHref} className="link ml-auto inline-flex items-center gap-1">
              <TrendingUpIcon className="h-4 w-4" /> See the ranked list
            </Link>
          )}
        </div>
      )}

      <div className="mt-8 grid gap-8 lg:grid-cols-[17rem_1fr] lg:gap-10">
        <aside>
          <SearchFilters q={textQuery} values={values} facets={d.facets} labels={nameOf} clearHref={textQuery ? `/search/?q=${encodeURIComponent(textQuery)}` : '/search/'} />
        </aside>

        <section aria-live="polite" aria-busy="false" className="min-w-0">
          <div className="flex flex-wrap items-center justify-between gap-3 border-b border-rule pb-4">
            <p className="text-sm text-muted">
              {d.total > 0 ? (
                <>
                  <span className="num font-semibold text-ink">
                    {fmtNumber(first)}–{fmtNumber(last)}
                  </span>{' '}
                  of <span className="num font-semibold text-ink">{fmtNumber(d.total)}</span> {d.total === 1 ? 'lawyer' : 'lawyers'}
                </>
              ) : (
                'No lawyers found'
              )}
              <span className="num ml-2 text-xs">· {d.tookMs} ms</span>
            </p>
            {(chips.length > 0 || textQuery) && (
              <SaveSearch
                defaultName={chips.map((c) => c.label).join(', ').slice(0, 120) || 'My search'}
                query={{
                  q: textQuery || undefined,
                  country: sp.country,
                  city: values.city,
                  practiceArea: values.practiceArea,
                  language: values.language,
                  verifiedOnly: values.verified === 'true' || undefined,
                  minExperience: values.minExperience ? Number(values.minExperience) : undefined,
                }}
              />
            )}
          </div>
          {chips.length > 0 && (
            <ul className="mt-4 flex flex-wrap items-center gap-2" aria-label="Active filters">
              {chips.map((c) => (
                <li key={c.key}>
                  <Link href={c.href} className="chip chip-active pr-2" aria-label={`Remove filter ${c.label}`}>
                    {c.label}
                    <XIcon className="h-3.5 w-3.5" />
                  </Link>
                </li>
              ))}
              {chips.length > 1 && (
                <li>
                  <Link href="/search/" className="px-2 text-sm font-medium text-muted underline decoration-rule-strong hover:text-ink">
                    Clear all
                  </Link>
                </li>
              )}
            </ul>
          )}

          {d.items.length ? (
            <ul className="mt-2">
              {d.items.map((l) => (
                <LawyerListItem key={l.id} l={l} />
              ))}
            </ul>
          ) : (
            <div className="card mt-6 flex flex-col items-center px-6 py-14 text-center">
              <span className="grid h-14 w-14 place-items-center rounded-2xl bg-sunken text-muted">
                <SearchIcon className="h-7 w-7" />
              </span>
              <p className="mt-4 font-serif text-xl font-semibold">No lawyers match {chips.length ? 'these filters' : 'this search'}</p>
              <p className="mt-1 max-w-md text-ink-2">Remove a filter, check the spelling of the name, or try one of these searches.</p>
              <ul className="mt-5 flex flex-wrap justify-center gap-2">
                {SUGGESTED.map((s) => (
                  <li key={s}>
                    <Link href={`/search/?q=${encodeURIComponent(s)}`} className="chip">
                      {s} <ArrowRightIcon className="h-3.5 w-3.5" />
                    </Link>
                  </li>
                ))}
              </ul>
              {chips.length > 0 && (
                <Link href="/search/" className="btn btn-quiet btn-sm mt-6">
                  <XIcon className="h-4 w-4" /> Clear all filters
                </Link>
              )}
            </div>
          )}
          <Pagination page={page} pageCount={d.pageCount} href={(p) => link({ page: p > 1 ? String(p) : undefined })} />
        </section>
      </div>
    </div>
  );
}
