"use client";

/**
 * SourcesProgress — карточка «Шаг B · Агрегация».
 *
 * Ростер источников берётся из source-registry (листинговые + Росреестр),
 * а НЕ из хардкода — #2211. Источник n1 полностью выключен (#2204) → в реестре его нет.
 * Статусы выводятся из реального `estimate.sources_used` / `countBySource` /
 * `actual_deals`; источник без вклада честно показывает «нет данных».
 */
import type { AggregatedEstimate } from "@/types/trade-in";
import { LIVE_LISTING_SOURCES } from "@/lib/source-registry";

interface Props {
  estimate: AggregatedEstimate | null;
  isPending: boolean;
}

interface SourceRow {
  key: string;
  label: string;
  dotClass: string;
  status: "done" | "loading" | "error" | "idle";
  count?: number;
}

export function SourcesProgress({ estimate, isPending }: Props) {
  // Маппинг реальных данных из estimate на строки-источники
  const used = new Set(estimate?.sources_used ?? []);
  const isDone = estimate !== null && !isPending;

  // Считаем сколько лотов из какого источника
  const countBySource: Record<string, number> = {};
  if (estimate) {
    for (const a of estimate.analogs) {
      if (a.source) {
        countBySource[a.source] = (countBySource[a.source] ?? 0) + 1;
      }
    }
  }

  // Листинговые источники — из реестра.
  const listingRows: SourceRow[] = LIVE_LISTING_SOURCES.map((s) => ({
    key: s.id,
    label: s.label,
    dotClass: s.dot,
    status: used.has(s.id) ? "done" : isPending ? "loading" : "idle",
    count: countBySource[s.id],
  }));

  const rows: SourceRow[] = [
    ...listingRows,
    {
      key: "rosreestr",
      label: "Росреестр (внутр.)",
      dotClass: "rosreestr",
      status:
        isDone && (estimate?.actual_deals.length ?? 0) > 0
          ? "done"
          : isPending
            ? "loading"
            : "idle",
      count: estimate?.actual_deals.length,
    },
  ];

  const doneCount = rows.filter((r) => r.status === "done").length;
  const totalCount = rows.length;
  const overallPct = isDone ? 100 : Math.min(95, (doneCount / totalCount) * 100 + (isPending ? 10 : 0));

  return (
    <article className="card progress-card">
      <div className="card-head">
        <div>
          <div className="section-kicker">Шаг B · Агрегация</div>
          <h2>Сбор данных по квартире</h2>
        </div>
        <div className="card-meta">
          <div className="num-done">
            <span data-tnum>{doneCount}</span>
            <span className="total"> / {totalCount}</span> источников
          </div>
        </div>
      </div>

      <div className="card-body">
        <div className="progress-summary">
          <span className="lead">
            {isPending
              ? "Идёт параллельный запрос — Celery group, timeout 30 сек."
              : isDone
                ? "Готово. Частичные результаты доступны при недоступных источниках."
                : "Введите параметры квартиры и нажмите «Оценить»."}
          </span>
          <div className="progress-overall">
            <div className="bar" style={{ width: `${overallPct}%` }} />
          </div>
        </div>

        <div className="progress-list">
          {rows.map((r) => (
            <div key={r.key} className={`progress-row is-${r.status}`}>
              <span className={`status-icon ${r.status}`}>
                {r.status === "done" && (
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
                    <polyline points="20 6 9 17 4 12" />
                  </svg>
                )}
                {r.status === "loading" && (
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M21 12a9 9 0 1 1-6.219-8.56" />
                  </svg>
                )}
                {r.status === "error" && (
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
                    <line x1="18" y1="6" x2="6" y2="18" />
                    <line x1="6" y1="6" x2="18" y2="18" />
                  </svg>
                )}
                {r.status === "idle" && (
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                    <circle cx="12" cy="12" r="9" />
                  </svg>
                )}
              </span>
              <span className="src-name">{r.label}</span>
              <span className="src-bar">
                <i
                  style={{
                    // @ts-expect-error CSS custom prop
                    "--p": r.status === "done" ? "100%" : r.status === "loading" ? "60%" : "0%",
                  }}
                />
              </span>
              <span
                className="src-value"
                style={{ color: r.status === "error" ? "var(--danger)" : undefined }}
              >
                {r.status === "done" && r.count !== undefined && (
                  <>
                    <b>{r.count} лотов</b>
                  </>
                )}
                {r.status === "done" && r.count === undefined && <b>готово</b>}
                {r.status === "loading" && "сбор..."}
                {r.status === "error" && "timeout — нет ответа"}
                {r.status === "idle" && (
                  <span style={{ color: "var(--muted-2)" }}>
                    {isDone ? "нет данных" : "ожидает запрос"}
                  </span>
                )}
              </span>
            </div>
          ))}
        </div>
      </div>

      <div className="card-foot">
        <span>при недоступности источника частичный результат не блокируется</span>
      </div>
    </article>
  );
}
