"use client";

/**
 * Trade-In страница в стиле gendsgn.ru/tradein.html mockup.
 * С basePath=/trade-in user видит её на gendsgn.ru/trade-in/.
 * Использует CSS из /components/trade-in/trade-in.css.
 */
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { useQueryClient } from "@tanstack/react-query";

import "@/components/trade-in/trade-in.css";
import type { AggregatedEstimate, TradeInEstimateInput, HouseType, RepairState } from "@/types/trade-in";
import { useEstimateMutation, useEstimate } from "@/lib/trade-in-api";
import { HTTPError } from "@/lib/api";
import { EstimateForm } from "@/components/trade-in/EstimateForm";
import { Topbar } from "@/components/trade-in/Topbar";
import { SourcesProgress } from "@/components/trade-in/SourcesProgress";
import { HeroSummary } from "@/components/trade-in/HeroSummary";
import { IMVBenchmark } from "@/components/trade-in/IMVBenchmark";
import { CianValuationCard } from "@/components/trade-in/CianValuationCard";
import { HouseInfoCard } from "@/components/trade-in/HouseInfoCard";
import { PlacementHistoryCard } from "@/components/trade-in/PlacementHistoryCard";
import { HouseAnalyticsSection } from "@/components/trade-in/HouseAnalyticsSection";
import { PhotoUpload } from "@/components/trade-in/PhotoUpload";
import { ListingsCard } from "@/components/trade-in/ListingsCard";
import { DealsCard } from "@/components/trade-in/DealsCard";
import { StreetDealsCard } from "@/components/trade-in/StreetDealsCard";
import { MapCard } from "@/components/trade-in/MapCard";
import { DistributionCard } from "@/components/trade-in/DistributionCard";
import { PriceTrendCard } from "@/components/trade-in/PriceTrendCard";
import { ExposureCard } from "@/components/trade-in/ExposureCard";
import { OfferCard } from "@/components/trade-in/OfferCard";
import { WhatIfPanel } from "@/components/trade-in/WhatIfPanel";
import { TestPresets } from "@/components/trade-in/TestPresets";
import { useEstimateImvBenchmark, useEstimateHouses } from "@/lib/trade-in-api";
import { useQuota } from "@/lib/useQuota";
import { useBrand, useActiveBrandSlug } from "@/lib/useBrand";
import { LIVE_LISTING_SOURCES } from "@/lib/source-registry";

// #2211 находка 7: список источников объявлений выводится из source-registry
// (источник n1 полностью выключен #2204 → его тут больше нет), а не хардкодится числом.
const LISTING_SOURCE_NAMES = LIVE_LISTING_SOURCES.map((s) => s.label).join(", ");

function useEstimateId() {
  if (typeof window === "undefined") return null;
  const params = new URLSearchParams(window.location.search);
  return params.get("id");
}

export default function TradeInPage() {
  const router = useRouter();
  const queryClient = useQueryClient();
  const quota = useQuota();

  // #657 white-label: «отдельная страничка под Практику» = re-skin того же
  // UI при ?brand=praktika. Бренд резолвится из ?brand= slug (см. useBrand.ts).
  const { data: brand } = useBrand();
  const activeBrandSlug = useActiveBrandSlug();

  // Переопределяем CSS-переменные палитры в рантайме + вешаем .brand-active
  // (переключает --font-sans на Manrope, см. trade-in.css). Cleanup снимает
  // overrides → без ?brand= дефолтный UI полностью нетронут (no-op).
  useEffect(() => {
    const root = document.documentElement;
    if (!brand) return;
    // Бренд-цвета идут в CSS custom-property без доверия (#766: подменённый бренд
    // → CSS-инъекция). Применяем только валидный hex / rgb()/hsl(); иначе дефолт.
    const COLOR_RE = /^#[0-9a-fA-F]{3,8}$|^(rgb|hsl)a?\([\d.,%\s/]+\)$/;
    if (COLOR_RE.test(brand.primary_color)) {
      root.style.setProperty("--accent", brand.primary_color); // зелёный (бренд)
    }
    if (COLOR_RE.test(brand.accent_color)) {
      root.style.setProperty("--accent-2", brand.accent_color); // циан (акцент)
    }
    root.classList.add("brand-active");
    return () => {
      root.style.removeProperty("--accent");
      root.style.removeProperty("--accent-2");
      root.classList.remove("brand-active");
    };
  }, [brand]);

  const blocked = quota.data
    ? !quota.data.unlimited && quota.data.remaining <= 0
    : false;
  const remainingQuota =
    quota.data && !quota.data.unlimited ? quota.data.remaining : null;
  const limitQuota =
    quota.data && !quota.data.unlimited ? quota.data.limit : null;

  const [freshResult, setFreshResult] = useState<{
    estimate: AggregatedEstimate;
    input: TradeInEstimateInput;
  } | null>(null);

  const urlEstimateId = useEstimateId();
  const restoredEstimate = useEstimate(
    freshResult === null ? urlEstimateId : null,
  );

  const mutation = useEstimateMutation();

  const currentEstimateId =
    freshResult?.estimate.estimate_id ?? urlEstimateId;
  const imvBenchmark = useEstimateImvBenchmark(currentEstimateId);
  const houses = useEstimateHouses(currentEstimateId);

  function handleSubmit(input: TradeInEstimateInput) {
    mutation.mutate(input, {
      onSuccess: (estimate) => {
        setFreshResult({ estimate, input });
        // basePath auto-prefixes — passing "/" returns user to /trade-in/?id=...
        router.replace(`/?id=${estimate.estimate_id}`, { scroll: false });
        void queryClient.invalidateQueries({ queryKey: ["trade-in", "quota"] });
      },
    });
  }

  const apiError = mutation.error?.message ?? null;
  const resultData =
    freshResult ??
    (restoredEstimate.data
      ? {
          estimate: restoredEstimate.data,
          input: {
            address: restoredEstimate.data.target_address ?? "—",
            area_m2: 0,
            rooms: restoredEstimate.data.analogs[0]?.rooms ?? 0,
            floor: 0,
            total_floors: 0,
          } as TradeInEstimateInput,
        }
      : null);

  // #822: restore по ?id= — отражаем загрузку/ошибку вместо молчаливого
  // empty-state. Backend отдаёт 404 на missing/owner-mismatch/expired.
  const restoreActive = urlEstimateId !== null && freshResult === null;
  const restoreError = restoreActive && restoredEstimate.isError;
  const restoreLoading = restoreActive && restoredEstimate.isPending;
  const restoreNotFound =
    restoreError &&
    restoredEstimate.error instanceof HTTPError &&
    restoredEstimate.error.status === 404;

  // Надёжный input для «Что-если»: предпочитаем поля самой оценки (есть и при
  // restore по ?id=, где resultData.input — stub с нулями), откатываемся на input.
  // address/rooms обязательны для payload — берём из estimate, иначе из input.
  const whatIfInput: TradeInEstimateInput | null = resultData
    ? {
        ...resultData.input,
        address: resultData.estimate.target_address ?? resultData.input.address,
        rooms: resultData.estimate.rooms ?? resultData.input.rooms,
        area_m2: resultData.estimate.area_m2 ?? resultData.input.area_m2,
        floor: resultData.estimate.floor ?? resultData.input.floor,
        total_floors: resultData.estimate.total_floors ?? resultData.input.total_floors,
        year_built: resultData.estimate.year_built ?? resultData.input.year_built,
        house_type: resultData.estimate.house_type ?? resultData.input.house_type,
        repair_state: resultData.estimate.repair_state ?? resultData.input.repair_state,
        has_balcony: resultData.estimate.has_balcony ?? resultData.input.has_balcony,
      }
    : null;
  // Гейтим панель: нужен валидный адрес + площадь, иначе recompute-payload невалиден.
  const whatIfReady =
    whatIfInput !== null &&
    whatIfInput.address.trim().length >= 3 &&
    whatIfInput.area_m2 > 10;

  function handleResubmit(patch: { house_type?: HouseType; repair_state?: RepairState }) {
    if (!resultData) return;
    const enrichedInput: TradeInEstimateInput = { ...resultData.input, ...patch };
    handleSubmit(enrichedInput);
  }

  const isPending = mutation.isPending;

  return (
    <>
      <Topbar active="estimate" />

      <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 }}>
              Агрегируем источники объявлений ({LISTING_SOURCE_NAMES}) и реальные сделки Росреестра.
              Время сбора — <span className="num">10–30 сек</span>.
            </p>
          </div>
          <div className="page-meta">
            <span className="pill">
              <span className="dot" />
              <span>Отчёт</span>{" "}
              <span className="mono">
                {resultData?.estimate.estimate_id.slice(0, 8) ?? "—"}
              </span>
            </span>
            <span className="pill">
              <span className="dot muted" />
              <span>Дата</span>{" "}
              <span className="mono">
                {/* #2211 находка 6: дата создания оценки (created_at), а НЕ момент
                    открытия страницы. Для восстановленных из истории отчётов
                    new Date() показывал бы «сегодня» вместо реальной даты расчёта.
                    Fallback на now() только если оценки/поля ещё нет (пустой экран,
                    старый кеш без created_at). */}
                {new Date(
                  resultData?.estimate.created_at ?? Date.now(),
                ).toLocaleDateString("ru-RU", {
                  day: "2-digit",
                  month: "2-digit",
                  year: "numeric",
                })}
              </span>
            </span>
            {resultData && (
              <span className="pill">
                <span className="dot warn" />
                <span>Действителен до</span>{" "}
                <span className="mono">
                  {new Date(resultData.estimate.expires_at).toLocaleDateString("ru-RU", {
                    day: "2-digit",
                    month: "2-digit",
                    year: "numeric",
                  })}
                </span>
              </span>
            )}
          </div>
        </div>

        <div className="layout">
          {/* Sticky form left */}
          <aside className="form-card">
            <EstimateForm
              onSubmit={handleSubmit}
              isPending={isPending}
              error={apiError}
              blocked={blocked}
              remaining={remainingQuota}
              limit={limitQuota}
            />
          </aside>

          {/* Result column */}
          <section className="result-col">
            <SourcesProgress
              estimate={resultData?.estimate ?? null}
              isPending={isPending}
            />

            {/* Тестовые пресеты — показываем только когда нет результата */}
            {!resultData && !isPending && (
              <TestPresets onPick={(data) => handleSubmit(data)} />
            )}

            {resultData ? (
              <>
                {whatIfReady && whatIfInput && (
                  <WhatIfPanel
                    baseEstimate={resultData.estimate}
                    baseInput={whatIfInput}
                  />
                )}
                <HeroSummary
                  estimate={resultData.estimate}
                  input={resultData.input}
                  onResubmit={handleResubmit}
                  isResubmitting={isPending}
                />
                <IMVBenchmark
                  benchmark={imvBenchmark.data}
                  isLoading={imvBenchmark.isPending}
                />
                <CianValuationCard data={resultData.estimate.cian_valuation} />
                <HouseInfoCard
                  houses={houses.data}
                  isLoading={houses.isPending}
                />
                {currentEstimateId && (
                  <PlacementHistoryCard estimateId={currentEstimateId} />
                )}
                {currentEstimateId && (
                  <HouseAnalyticsSection estimateId={currentEstimateId} />
                )}
                <PhotoUpload estimateId={resultData.estimate.estimate_id} />
                <ListingsCard estimate={resultData.estimate} estimateId={currentEstimateId ?? undefined} />
                <DealsCard estimate={resultData.estimate} />
                <StreetDealsCard estimate={resultData.estimate} />
                {/* ANALYTICS cards — каждая с graceful guard «render only if data present» */}
                <MapCard estimate={resultData.estimate} />
                <DistributionCard estimate={resultData.estimate} />
                <PriceTrendCard estimate={resultData.estimate} />
                <ExposureCard estimate={resultData.estimate} />
                <OfferCard estimate={resultData.estimate} brandSlug={activeBrandSlug} />
              </>
            ) : restoreError ? (
              <article className="card">
                <div className="card-body" style={{ padding: "48px 24px", textAlign: "center" }}>
                  <h3 style={{ fontSize: 16, fontWeight: 600, marginBottom: 6 }}>
                    {restoreNotFound
                      ? "Отчёт не найден или недоступен"
                      : "Не удалось загрузить отчёт"}
                  </h3>
                  <p style={{ color: "var(--muted)", fontSize: 14, marginBottom: 16 }}>
                    {restoreNotFound
                      ? "Ссылка устарела, отчёт удалён или у вас нет к нему доступа."
                      : "Произошла ошибка при загрузке отчёта. Попробуйте ещё раз."}
                  </p>
                  <button
                    type="button"
                    className="btn btn-primary"
                    onClick={() => router.replace("/")}
                  >
                    Новая оценка
                  </button>
                </div>
              </article>
            ) : restoreLoading ? (
              <article className="card">
                <div className="card-body" style={{ padding: "48px 24px", textAlign: "center" }}>
                  <p style={{ color: "var(--muted)", fontSize: 14 }}>
                    Загрузка отчёта…
                  </p>
                </div>
              </article>
            ) : (
              <article className="card">
                <div className="card-body" style={{ padding: "48px 24px", textAlign: "center" }}>
                  <div style={{ fontSize: 40, marginBottom: 12 }}>🏠</div>
                  <h3 style={{ fontSize: 16, fontWeight: 600, marginBottom: 6 }}>
                    Введите параметры квартиры
                  </h3>
                  <p style={{ color: "var(--muted)", fontSize: 14 }}>
                    Заполните форму слева или выберите тестовую квартиру выше.
                  </p>
                </div>
              </article>
            )}
          </section>
        </div>
      </main>

      <footer className="page-foot">
        <div>
          Мера · MVP ·{" "}
          <span className="mono">data: Avito + Cian + Yandex + Росреестр</span>
        </div>
        <div style={{ display: "flex", gap: 18 }}>
          <a href="#">Документация</a>
          <a href="#">API</a>
          <a href="#">Источники данных</a>
        </div>
      </footer>
    </>
  );
}
