"use client";
/**
* Section6Forecast — "6. Прогноз" (958-B3 / §22).
*
* Renders the async §22 demand/supply forecast, scenarios and confidence on the
* Site Finder analysis screen. Self-fetches via useParcelForecastQuery, which
* POLLs GET /api/v1/parcels/{cad}/forecast every 4s until status === "ready"
* (the forecast is enqueued by useParcelAnalyzeQuery on page mount — render-only
* here, no trigger).
*
* Layout mirrors Section1-5: dark HeadlineBar + section root id="section-6".
* exec_summary banner (headline + verdict + KPI row)
* 6.1 Прогноз по горизонтам → ForecastHorizonsBlock
* 6.2 Сценарии → ScenariosBlock
* 6.3 Уверенность → ForecastConfidenceBlock
* advisory disclaimer (footer)
*/
import { LineChart } from "lucide-react";
import { HeadlineBar } from "@/components/ui/HeadlineBar";
import { KpiCard } from "@/components/site-finder/KpiCard";
import { useParcelForecastQuery } from "@/lib/site-finder-api";
import type { ForecastReport } from "@/types/forecast";
import { ForecastHorizonsBlock } from "./ForecastHorizonsBlock";
import { ScenariosBlock } from "./ScenariosBlock";
import { ForecastConfidenceBlock } from "./ForecastConfidenceBlock";
import { CONFIDENCE_RU, deficitVariant, fmtNum } from "./forecast-helpers";
interface Props {
cad: string;
/**
* Horizon chosen in the analysis-screen HorizonSelector (6 / 12 / 18). When
* set it takes priority over the report-derived horizon so the user's choice
* instantly drives which horizon is treated as the target (client-side), even
* before the recomputed forecast finishes (see AnalysisPageContent comment).
*/
selectedHorizon?: number;
}
const ADVISORY_DISCLAIMER =
"Оценка advisory — не основание для инвест-решения.";
const SCROLL_MARGIN = 72;
// KpiCard color enum (site-finder variant) mapped from Badge variant words.
function kpiColorForDeficit(deficitIndex: number): "green" | "red" | "neutral" {
const v = deficitVariant(deficitIndex);
if (v === "success") return "green";
if (v === "danger") return "red";
return "neutral";
}
// ── Section6Forecast ─────────────────────────────────────────────────────────
export function Section6Forecast({ cad, selectedHorizon }: Props) {
const { data, isLoading, error } = useParcelForecastQuery(cad);
const isPending =
isLoading || (data != null && data.status !== "ready") || data == null;
// ── Pending: forecast still computing (poll in flight) ─────────────────────
if (isPending && !error) {
return (
{exec.verdict}
{ADVISORY_DISCLAIMER}