---
/**
 * /near-you — location-based deal discovery page.
 *
 * SSR (no prerender). Renders NearYouIsland client:visible.
 * noindex when any filter param is active (SEO rule 10 — filter URLs not indexed).
 * Canonical is always the clean /near-you path.
 */
import { getFilterData } from '@/server/db/queries/filter-data';
import { getDealsFacetCounts, HISTO_BUCKETS } from '@/server/db/queries/deals-facets';
import { dehydrateForIsland } from '@/lib/query/ssr';
import type { PrefetchFn } from '@/lib/query/ssr';
import { buildFacetKey } from '@/lib/deals/facet-key';
import { makeNearYouCodec } from '@/lib/url/codecs/nearYouCodec';
import type { FilterData } from '@/features/search/useCachedFilterData';
import PublicAppShell from '@/layouts/PublicAppShell.astro';
import { NearYouIsland } from '@/features/near-you';
import { he } from '@/lib/i18n/he';
import { en } from '@/lib/i18n/en';

const db = Astro.locals.services.db;
interface Props {
  locale: 'he' | 'en';
}

const { locale } = Astro.props;

let priceCeiling = 2000;
let initialNearYouState = makeNearYouCodec({ locale, priceCeiling }).parse({
  pathname: Astro.url.pathname,
  search: Astro.url.search,
});
let initialFilterData: FilterData | undefined;
let initialFacets: Awaited<ReturnType<typeof getDealsFacetCounts>> | undefined;
let facetCatSlug: string | undefined;
let facetType: (typeof initialNearYouState.dealTypes)[number] | undefined;
let facetTagSlugs: string[] = [];
let facetPriceMin: number | undefined;
let facetPriceMax: number | undefined;

if (db) {
  try {
    const filterData = await getFilterData(db, locale);
    priceCeiling = filterData.otherFilters.priceCeiling;
    const priceFloor = filterData.otherFilters.priceFloor;
    initialNearYouState = makeNearYouCodec({ locale, priceCeiling }).parse({
      pathname: Astro.url.pathname,
      search: Astro.url.search,
    });
    facetCatSlug = initialNearYouState.categoryId
      ? filterData.categories.find((c) => c.id === initialNearYouState.categoryId)?.slug
      : undefined;
    facetType =
      initialNearYouState.dealTypes.length === 1 ? initialNearYouState.dealTypes[0] : undefined;
    facetTagSlugs = initialNearYouState.tagIds
      .map((id) => filterData.topTags.find((t) => t.id === id)?.slug)
      .filter((s): s is string => !!s);
    facetPriceMin =
      initialNearYouState.minPrice > priceFloor ? initialNearYouState.minPrice : undefined;
    facetPriceMax =
      initialNearYouState.maxPrice > 0 && initialNearYouState.maxPrice < priceCeiling
        ? initialNearYouState.maxPrice
        : undefined;
    initialFilterData = filterData;
    initialFacets = await getDealsFacetCounts(db, {
      catId: initialNearYouState.categoryId,
      type: facetType,
      tagIds: initialNearYouState.tagIds.length > 0 ? initialNearYouState.tagIds : undefined,
      cityCode: initialNearYouState.cityCode ?? undefined,
      locale,
      histoMin: priceFloor,
      histoMax: priceCeiling,
      histoBuckets: HISTO_BUCKETS,
      priceMin: facetPriceMin,
      priceMax: facetPriceMax,
    }).catch(() => undefined);
  } catch {
    // fall back to defaults above
  }
}

const prefetchFns: PrefetchFn[] = [
  async (qc) => {
    if (initialFilterData) {
      qc.setQueryData(['filterData', locale], initialFilterData);
    }
  },
];
if (initialFacets) {
  prefetchFns.push(async (qc) => {
    qc.setQueryData(
      buildFacetKey({
        locale,
        catSlug: facetCatSlug,
        type: facetType,
        tagSlugs: facetTagSlugs,
        cityCode: initialNearYouState.cityCode ?? undefined,
        priceMin: facetPriceMin,
        priceMax: facetPriceMax,
      }),
      initialFacets,
    );
  });
}

const { dehydratedState } = await dehydrateForIsland(prefetchFns);
const dict = locale === 'en' ? en : he;
const origin = Astro.site?.origin ?? Astro.url.origin;
const canonical = `${origin}/near-you`;

// noindex when any filter param beyond the basic city is set
const sp = Astro.url.searchParams;
const paramCount = [...sp.keys()].length;
// city-only = index; any other filter or combinations = noindex
const noindex = paramCount > 1 || (paramCount === 1 && !sp.has('city'));

const title = dict.near_you.title + ' - Multideal';
const description = dict.near_you.page_description;

// GEO structured data for local-pack eligibility (Israel-wide aggregator).
// When a city is specified via ?city=, the placeName could be refined client-side,
// but the static IL country-level data covers the base case for Google local-pack.
const nearYouJsonLd: Record<string, unknown> = {
  '@context': 'https://schema.org',
  '@type': 'WebPage',
  name: title,
  description,
  url: canonical,
  mainEntity: {
    '@type': 'ItemList',
    name: dict.near_you.jsonld_name,
    description: dict.near_you.jsonld_description,
  },
};
---

<PublicAppShell
  title={title}
  description={description}
  canonical={canonical}
  locale={locale}
  noindex={noindex}
  jsonLd={nearYouJsonLd}
  geoRegion="IL"
  geoPlaceName="ישראל"
  geoPosition="31.0461;34.8516"
  currentPath="/near-you"
>
  <main id="main">
    <h1 class="sr-only">{dict.near_you.title}</h1>
    <NearYouIsland
      locale={locale}
      initialUrlState={initialNearYouState}
      initialFilterData={initialFilterData}
      priceCeiling={priceCeiling}
      {dehydratedState}
      client:visible
    />
  </main>
</PublicAppShell>
