"use client";

/**
 * /trade-in/sale-share — «доля квартир дома в продаже».
 * Порог % → дома вторички, где доля квартир, выставленных на продажу, ≥ порога.
 * Сигнал для девелопера: расселение / инвест-выход / проблемный дом.
 *
 * Доступ: pilot + admin (RBAC roles.yaml: pilot paths `/trade-in/**`).
 */
import { useCallback, useMemo, useRef, useState } from "react";
import dynamic from "next/dynamic";

import "@/components/trade-in/trade-in.css";
import { SaleShareHeader } from "@/components/trade-in/SaleShareHeader";
import { SaleShareControls } from "@/components/trade-in/SaleShareControls";
import { SaleShareList } from "@/components/trade-in/SaleShareList";
import { BuildingListingsDrawer } from "@/components/trade-in/BuildingListingsDrawer";
import { useSaleShareBuildings, useSaleShareSummary } from "@/lib/sale-share-api";
import { useDebouncedValue } from "@/lib/useDebouncedValue";
import type { BuildingSaleShare, SaleShareQuery, SaleShareSort } from "@/types/sale-share";

// Карта тянет Leaflet с CDN (window.L) → грузим только в браузере.
const SaleShareMap = dynamic(
  () => import("@/components/trade-in/SaleShareMap").then((m) => m.SaleShareMap),
  {
    ssr: false,
    loading: () => (
      <div className="ss-map-wrap">
        <div className="ss-map-empty">Загрузка карты…</div>
      </div>
    ),
  },
);

function toNumOrNull(s: string): number | null {
  const t = s.trim();
  if (t === "") return null;
  const n = Number(t);
  return Number.isFinite(n) ? n : null;
}

export default function SaleSharePage() {
  // Порог + фильтры (raw controlled state).
  const [minPct, setMinPct] = useState(5);
  const [city, setCity] = useState("");
  const [priceMin, setPriceMin] = useState("");
  const [priceMax, setPriceMax] = useState("");
  const [yearMin, setYearMin] = useState("");
  const [yearMax, setYearMax] = useState("");
  const [houseType, setHouseType] = useState("");
  const [sort, setSort] = useState<SaleShareSort>("share_desc");
  // Окно метрики: «сейчас» (активные сейчас) или «за 45 дней».
  const [window, setWindow] = useState<"now" | "45d">("now");
  // Клиентский фильтр «мин. объявлений в доме» (см. filteredBuildings ниже).
  const [minCount, setMinCount] = useState<number>(0);

  // Выбранный дом (drawer) + наведённый дом (sync со списком/картой).
  const [selected, setSelected] = useState<BuildingSaleShare | null>(null);
  const [hoveredHouseId, setHoveredHouseId] = useState<number | null>(null);

  // Дебаунс текстовых/числовых вводов и слайдера — не дёргаем API на keystroke.
  const debMinPct = useDebouncedValue(minPct, 250);
  const debCity = useDebouncedValue(city, 400);
  const debPriceMin = useDebouncedValue(priceMin, 400);
  const debPriceMax = useDebouncedValue(priceMax, 400);
  const debYearMin = useDebouncedValue(yearMin, 400);
  const debYearMax = useDebouncedValue(yearMax, 400);

  // Сорт, уходящий в API, зависит от окна: при «45 дней» share/active мапятся
  // на 45-дневные метрики (остальные — цена/экспозиция — без изменений).
  const apiSort: SaleShareSort = useMemo(() => {
    if (window !== "45d") return sort;
    if (sort === "share_desc") return "share_45d_desc";
    if (sort === "active_desc") return "count_45d_desc";
    return sort;
  }, [sort, window]);

  const query: SaleShareQuery = useMemo(
    () => ({
      min_pct: debMinPct,
      city: debCity.trim() || null,
      price_min: toNumOrNull(debPriceMin),
      price_max: toNumOrNull(debPriceMax),
      year_min: toNumOrNull(debYearMin),
      year_max: toNumOrNull(debYearMax),
      house_type: houseType || null,
      sort: apiSort,
      limit: 200,
    }),
    [debMinPct, debCity, debPriceMin, debPriceMax, debYearMin, debYearMax, houseType, apiSort],
  );

  const summaryQ = useSaleShareSummary();
  const buildingsQ = useSaleShareBuildings(query);
  const buildings = useMemo(() => buildingsQ.data ?? [], [buildingsQ.data]);

  // Клиентский фильтр «мин. объявлений в доме» — намеренно НЕ серверный:
  // не трогаем query-key/бэкенд, фильтруем уже загруженный список по окну.
  // Счётчик null трактуем как 0; minCount === 0 → фильтр выключен.
  const filteredBuildings = useMemo(() => {
    if (minCount <= 0) return buildings;
    return buildings.filter((b) => {
      const count = (window === "45d" ? b.listings_45d : b.active_secondary) ?? 0;
      return count >= minCount;
    });
  }, [buildings, minCount, window]);

  // Стабильные колбэки (маркеры карты замыкают их при отрисовке).
  const buildingsRef = useRef<BuildingSaleShare[]>(filteredBuildings);
  buildingsRef.current = filteredBuildings;
  const handleSelect = useCallback((houseId: number) => {
    setSelected(buildingsRef.current.find((b) => b.house_id === houseId) ?? null);
  }, []);
  const handleHover = useCallback((houseId: number | null) => {
    setHoveredHouseId(houseId);
  }, []);

  // distinct house_type из текущей выборки (+ выбранный, чтобы не исчезал).
  const houseTypeOptions = useMemo(() => {
    const set = new Set<string>();
    for (const b of buildings) if (b.house_type) set.add(b.house_type);
    if (houseType) set.add(houseType);
    return [...set].sort();
  }, [buildings, houseType]);

  const summary = summaryQ.data;
  const noDenominator = summary !== undefined && summary.buildings_with_denominator === 0;
  const selectedHouseId = selected?.house_id ?? null;

  return (
    <>
      <SaleShareHeader />

      <main className="page">
        <div className="crumbs">
          <em>Главная</em> <span>›</span> <em>Поиск домов</em> <span>›</span> Доля квартир
          в продаже
        </div>

        <div className="page-title">
          <div>
            <h1>Доля квартир дома в продаже</h1>
            <p className="page-subtitle" style={{ marginTop: 8 }}>
              Дома вторичного рынка, где доля квартир, выставленных на продажу, превышает
              порог. Высокая доля — сигнал девелоперу: расселение, массовый инвест-выход
              или проблемный дом. Выберите порог % и изучите адреса на карте и в списке.
            </p>
          </div>
        </div>

        {/* Coverage-баннер */}
        {summary && (
          <div className={`ss-banner${noDenominator ? " is-warn" : ""}`} role="status">
            {noDenominator ? (
              <>
                <b>Данные о количестве квартир ещё загружаются</b> (реестр ГАР). Доля в
                продаже считается как «активные объявления ÷ число квартир дома» — список
                появится, когда загрузчик реестра отработает.
              </>
            ) : (
              <>
                Процент посчитан для <b>{summary.buildings_with_denominator}</b> из{" "}
                <b>{summary.total_secondary_buildings}</b> домов (
                {summary.coverage_pct.toFixed(1)}%). По остальным ещё не загружен реестр
                квартир (ГАР).
              </>
            )}
          </div>
        )}

        <div className="result-col" style={{ marginTop: 22 }}>
          <SaleShareControls
            summary={summary}
            minPct={minPct}
            onMinPct={setMinPct}
            city={city}
            onCity={setCity}
            priceMin={priceMin}
            onPriceMin={setPriceMin}
            priceMax={priceMax}
            onPriceMax={setPriceMax}
            yearMin={yearMin}
            onYearMin={setYearMin}
            yearMax={yearMax}
            onYearMax={setYearMax}
            houseType={houseType}
            onHouseType={setHouseType}
            houseTypeOptions={houseTypeOptions}
            sort={sort}
            onSort={setSort}
            window={window}
            onWindow={setWindow}
            minCount={minCount}
            onMinCount={setMinCount}
          />

          <article className="card">
            <div className="card-head">
              <div>
                <div className="section-kicker">Карта</div>
                <h2>Дома на карте</h2>
              </div>
              <div className="card-meta">
                <div className="ss-legend">
                  <span>низкая</span>
                  <span className="ss-legend-bar" aria-hidden="true" />
                  <span>высокая доля</span>
                </div>
              </div>
            </div>
            <SaleShareMap
              buildings={filteredBuildings}
              selectedHouseId={selectedHouseId}
              hoveredHouseId={hoveredHouseId}
              onSelect={handleSelect}
              onHover={handleHover}
            />
          </article>

          <SaleShareList
            buildings={filteredBuildings}
            sort={sort}
            onSort={setSort}
            selectedHouseId={selectedHouseId}
            hoveredHouseId={hoveredHouseId}
            onSelect={handleSelect}
            onHover={handleHover}
            isLoading={buildingsQ.isPending}
            isError={buildingsQ.isError}
            minPct={minPct}
            window={window}
          />
        </div>
      </main>

      {selected && (
        <BuildingListingsDrawer building={selected} onClose={() => setSelected(null)} />
      )}

      <footer className="page-foot">
        <div>
          Поиск домов ·{" "}
          <span className="mono">доля квартир в продаже · вторичный рынок ЕКБ</span>
        </div>
      </footer>
    </>
  );
}
