"use client";

import { Suspense, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";

import type {
  AggregatedEstimate,
  TradeInEstimateInput,
} from "@/types/trade-in";
import { useEstimateMutation, useEstimate } from "@/lib/trade-in-api";
import { EstimateForm } from "@/components/trade-in/EstimateForm";
import { EstimateResult } from "@/components/trade-in/EstimateResult";
import { EstimateProgress } from "@/components/trade-in/EstimateProgress";

// ── Page ──────────────────────────────────────────────────────────────────────

function TradeInInner() {
  const router = useRouter();
  // App Router hook: reactive to URL changes and SSR-safe (no hydration mismatch).
  const urlEstimateId = useSearchParams().get("id");

  // Result from mutation (fresh) or from URL (restored)
  const [freshResult, setFreshResult] = useState<{
    estimate: AggregatedEstimate;
    input: TradeInEstimateInput;
  } | null>(null);

  // Drop the fresh result when the URL points at a different estimate so a
  // soft-navigation to another shared link doesn't keep showing the old one.
  const [freshFor, setFreshFor] = useState<string | null>(null);
  const activeFreshResult = freshFor === urlEstimateId ? freshResult : null;

  // Fetch from URL if no fresh result for the current id yet
  const restoredEstimate = useEstimate(
    activeFreshResult === null ? urlEstimateId : null,
  );

  const mutation = useEstimateMutation();

  function handleSubmit(input: TradeInEstimateInput) {
    mutation.mutate(input, {
      onSuccess: (estimate) => {
        setFreshResult({ estimate, input });
        // Bind the fresh result to its id so it's only shown while the URL
        // still points at this estimate (see activeFreshResult).
        setFreshFor(estimate.estimate_id);
        // Persist estimate_id in URL for shareable link
        router.replace(`/trade-in?id=${estimate.estimate_id}`, {
          scroll: false,
        });
      },
    });
  }

  const apiError = mutation.error?.message ?? null;

  // Determine what to render on the right side
  const restoreError = restoredEstimate.error?.message ?? null;

  const resultData: {
    estimate: AggregatedEstimate;
    input: TradeInEstimateInput;
  } | null =
    activeFreshResult ??
    (restoredEstimate.data
      ? {
          estimate: restoredEstimate.data,
          // When restoring from URL we don't have the original object parameters
          // (GET /estimate/{id} returns only AggregatedEstimate, no input snapshot).
          // Don't borrow the first analog's address or fabricate 0 m²/floor — those
          // are someone else's listing. Pass an empty input; EstimateResult must
          // hide the "Параметры объекта" block when the object params are unknown.
          // TODO(TI): expose the stored input on the GET endpoint + render real params.
          input: {
            address: "",
            area_m2: 0,
            rooms: 0,
            floor: 0,
            total_floors: 0,
          },
        }
      : null);

  return (
    <main
      style={{
        minHeight: "100vh",
        background: "#f8f9fb",
        padding: "24px 16px",
        boxSizing: "border-box",
      }}
    >
      {/* Page header */}
      <div style={{ maxWidth: 1280, margin: "0 auto 20px" }}>
        <h1
          style={{
            margin: "0 0 4px",
            fontSize: 22,
            fontWeight: 800,
            color: "#1a1d23",
          }}
        >
          Trade-In Estimator
        </h1>
        <p style={{ margin: 0, fontSize: 14, color: "#6b7280" }}>
          Оценка рыночной стоимости квартиры по аналогам и сделкам ЕКБ
        </p>
      </div>

      {/* Two-column layout */}
      <div
        style={{
          maxWidth: 1280,
          margin: "0 auto",
          display: "grid",
          gridTemplateColumns: "360px 1fr",
          gap: 20,
          alignItems: "start",
        }}
        className="trade-in-grid"
      >
        {/* Left — sticky form */}
        <div style={{ position: "sticky", top: 24 }}>
          <EstimateForm
            onSubmit={handleSubmit}
            isPending={mutation.isPending}
            error={apiError}
          />
          <EstimateProgress visible={mutation.isPending} />
        </div>

        {/* Right — result area */}
        <div>
          {resultData ? (
            <EstimateResult
              estimate={resultData.estimate}
              input={resultData.input}
            />
          ) : restoredEstimate.isLoading ? (
            <EstimateProgress visible />
          ) : restoreError ? (
            <RestoreError />
          ) : (
            <EmptyState />
          )}
        </div>
      </div>

      {/* Responsive: stack on mobile */}
      <style>{`
        @media (max-width: 767px) {
          .trade-in-grid {
            grid-template-columns: 1fr !important;
          }
          .trade-in-grid > div:first-child {
            position: static !important;
          }
        }
      `}</style>
    </main>
  );
}

// useSearchParams() в Next 15 App Router throw'ит при static rendering без
// <Suspense> boundary — поэтому оборачиваем page-level.
export default function TradeInPage() {
  return (
    <Suspense fallback={null}>
      <TradeInInner />
    </Suspense>
  );
}

function EmptyState() {
  return (
    <div
      style={{
        padding: "48px 24px",
        textAlign: "center",
        color: "#9ca3af",
        background: "#fff",
        border: "1px dashed #e6e8ec",
        borderRadius: 12,
      }}
    >
      <div style={{ fontSize: 40, marginBottom: 12 }}>🏠</div>
      <div
        style={{
          fontSize: 16,
          fontWeight: 600,
          color: "#374151",
          marginBottom: 6,
        }}
      >
        Введите параметры квартиры
      </div>
      <div style={{ fontSize: 14 }}>
        Оценка появится здесь после нажатия «Оценить»
      </div>
    </div>
  );
}

function RestoreError() {
  return (
    <div
      style={{
        padding: "48px 24px",
        textAlign: "center",
        color: "#b91c1c",
        background: "#fff",
        border: "1px solid #fca5a5",
        borderRadius: 12,
      }}
    >
      <div style={{ fontSize: 40, marginBottom: 12 }}>⚠️</div>
      <div
        style={{
          fontSize: 16,
          fontWeight: 600,
          color: "#991b1b",
          marginBottom: 6,
        }}
      >
        Ссылка устарела или не найдена
      </div>
      <div style={{ fontSize: 14, color: "#6b7280" }}>
        Оценка по этой ссылке недоступна — срок её хранения истёк. Введите
        параметры квартиры слева, чтобы рассчитать новую.
      </div>
    </div>
  );
}
