// SearchLoadingOverlay — sichtbarer Loading-Zustand während Cortex-Orchestrator
// im Hintergrund läuft.
//
// Ab v0.3 (2026-04-21): zeigt ECHTE Server-Progress-Daten aus
// scraperRuns/{runId}.progress, nicht mehr time-basierte Simulation:
//   - 4-Stufen-Funnel mit Live-Zahlen (72 → 28 → 12 → 5)
//   - natürliche deutsche Step-Namen statt Tech-Jargon
//   - rolling Activity-Stream der letzten ~6 Events
//     ("Cortex verwirft: Dach-Franchise Süd — falsche Rechtsform", etc.)
//
// Das Gefühl: "da passiert richtig was". Jeden Scroll der Activity-Liste
// erfährt der User dass Cortex gerade tief durchs Internet arbeitet.

// Step-Labels in natürlicher deutscher Sprache — kein Tech-Jargon.
const STEP_LABELS = {
  discovery:  { title: 'Firmen identifizieren',         sub: 'Top-Kandidaten aus deutschen Web-Quellen' },
  hydration:  { title: 'Firmen tiefgehend analysieren', sub: 'Websites + Impressum + Karriere + Team + News' },
  reasoning:  { title: 'Cortex bewertet',               sub: 'Claude Sonnet prüft jeden Kandidaten gegen dein Profil' },
  delivery:   { title: 'Leads zusammenstellen',         sub: 'Top-Matches werden für dich sortiert + ausgeliefert' },
  done:       { title: 'Fertig',                        sub: 'Suchlauf abgeschlossen' },
};

const STEP_ORDER = ['discovery', 'hydration', 'reasoning', 'delivery'];

function ActivityLine({ activity }) {
  const color = activity.kind === 'keep' ? 'text-emerald-700'
    : activity.kind === 'drop' ? 'text-amber-700'
    : activity.kind === 'tool' ? 'text-[#3465E3]'
    : activity.kind === 'error' ? 'text-red-700'
    : 'text-ink-muted';
  const icon = activity.kind === 'keep' ? '✓'
    : activity.kind === 'drop' ? '✗'
    : activity.kind === 'tool' ? '⚙'
    : activity.kind === 'error' ? '⚠'
    : '·';
  return (
    <div className={`flex items-start gap-2 text-[11.5px] leading-snug ${color} fade-in`}>
      <span className="flex-shrink-0 font-medium">{icon}</span>
      <span className="truncate">{activity.text}</span>
    </div>
  );
}

function SearchLoadingOverlay({ state, onClose }) {
  const [, setTick] = useState(0);
  useEffect(() => {
    if (!state) return;
    const id = setInterval(() => setTick((t) => t + 1), 1000);
    return () => clearInterval(id);
  }, [state]);

  if (!state) return null;

  const elapsedSec = Math.floor((Date.now() - state.startedAt) / 1000);
  const elapsedMin = Math.floor(elapsedSec / 60);
  const displayElapsed = elapsedMin > 0 ? `${elapsedMin}min ${elapsedSec % 60}s` : `${elapsedSec}s`;

  // Progress block from server — or fallback to the time-based heuristic
  // for the brief window between "run started" and "first progress-write".
  const progress = state.progress || null;
  const currentStepKey = progress?.currentStep
    ?? (elapsedSec < 30 ? 'discovery'
      : elapsedSec < 90 ? 'hydration'
      : elapsedSec < 300 ? 'reasoning'
      : 'delivery');
  const currentStepIdx = STEP_ORDER.indexOf(currentStepKey);

  // Rolling activity — take last ~6 entries, newest on top
  const activity = (progress?.recentActivity ?? []).slice(-6).reverse();

  // Funnel numbers — nur echte live-ticking Werte zeigen.
  //
  // Achtung (2026-04-21): Früher hatten wir einen Fallback
  //   `candidatesHydrated ?? candidatesAfterDedup`
  // — das war ein UX-Bug: beim Hydration-Start stand in der UI 23 ("alle
  // identifizierten"), sobald der erste Kandidat fertig analysiert war
  // schrieb der Server `candidatesHydrated: 1` und die Zahl sprang von
  // 23 auf 1 runter. Janik: "wie kann das sein?". Fix: Fallback raus,
  // bis echte Werte kommen zeigen wir "—" (via RollingNumber). Der Step
  // "vertieft analysiert" ist semantisch exakt candidatesHydrated — keine
  // Lüge mehr.
  const nScan = progress?.candidatesScanned ?? null;
  const nVertieft = progress?.candidatesHydrated ?? null;
  const nReas = progress?.candidatesReasoned ?? null;
  const nDeliver = progress?.candidatesDelivered ?? state.leadsFound ?? 0;

  return (
    <div
      className="fixed inset-0 z-[100] flex items-center justify-center p-4 fade-in"
      style={{ background: 'rgba(11, 15, 25, 0.72)', backdropFilter: 'blur(8px)' }}
    >
      <div className="bg-white rounded-2xl w-full max-w-[580px] overflow-hidden fade-in-scale">
        {/* Hero */}
        <div
          className="px-8 py-6 text-center"
          style={{
            background: 'linear-gradient(107.45deg, #1479FC 18.94%, #B880FC 123.42%)',
          }}
        >
          <div className="inline-flex items-center justify-center w-12 h-12 rounded-full bg-white/20 mb-2 pulse-glow">
            <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24 2.5 2.5 0 0 1 1.98-3A2.5 2.5 0 0 1 9.5 2Z"/>
              <path d="M14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24 2.5 2.5 0 0 0-1.98-3A2.5 2.5 0 0 0 14.5 2Z"/>
            </svg>
          </div>
          <div className="text-white text-[19px] font-semibold tracking-tight">
            Cortex sucht für dich
          </div>
          <div className="text-white/85 text-[12.5px] mt-1">
            Zeit seit Start: <span className="tabular-nums">{displayElapsed}</span>
            {typeof nScan === 'number' && (
              <span> · <RollingNumber className="tabular-nums font-semibold" value={nScan}/> Firmen im Fokus</span>
            )}
          </div>
        </div>

        {/* Funnel */}
        <div className="px-6 py-4 border-b border-line grid grid-cols-4 gap-2 text-center">
          <FunnelStat label="Identifiziert" value={nScan}/>
          <FunnelStat label="Vertieft analysiert" value={nVertieft}/>
          <FunnelStat label="Bewertet" value={nReas}/>
          <FunnelStat label="Bereit" value={nDeliver} highlight/>
        </div>

        {/* Phases */}
        <div className="px-6 pt-4 pb-3 space-y-2.5">
          {STEP_ORDER.map((key, i) => {
            const isDone = i < currentStepIdx;
            const isActive = i === currentStepIdx;
            const label = STEP_LABELS[key];
            return (
              <div key={key} className="flex items-start gap-3">
                <div className="mt-0.5 flex-shrink-0">
                  {isDone && (
                    <div className="w-5 h-5 rounded-full bg-emerald-500 flex items-center justify-center">
                      <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
                        <path d="M20 6 9 17l-5-5"/>
                      </svg>
                    </div>
                  )}
                  {isActive && (
                    <div className="w-5 h-5 rounded-full border-2 border-brand-500 border-t-transparent" style={{ animation: 'spinSlow 0.9s linear infinite' }}/>
                  )}
                  {!isDone && !isActive && (
                    <div className="w-5 h-5 rounded-full border-2 border-line"/>
                  )}
                </div>
                <div className="flex-1 min-w-0">
                  <div className={`text-[13px] font-medium ${isDone ? 'text-ink-muted line-through' : isActive ? 'text-ink' : 'text-ink-soft'}`}>
                    {label.title}
                  </div>
                  <div className={`text-[11px] ${isActive ? 'text-ink-muted' : 'text-ink-soft'}`}>{label.sub}</div>
                </div>
              </div>
            );
          })}
        </div>

        {/* Live-Stream */}
        {activity.length > 0 && (
          <div className="mx-6 mb-4 rounded-md border border-line bg-surface/60 px-4 py-3">
            <div className="text-[10.5px] uppercase tracking-[0.08em] text-ink-soft font-medium mb-2 flex items-center gap-1.5">
              <span className="w-1.5 h-1.5 rounded-full bg-[#3465E3] pulse-dot"/>
              Cortex arbeitet live
            </div>
            <div className="space-y-1">
              {activity.map((a, i) => <ActivityLine key={`${a.ts}-${i}`} activity={a}/>)}
            </div>
          </div>
        )}

        {/* Close */}
        <div className="px-6 pb-5">
          <button
            type="button"
            onClick={onClose}
            className="w-full py-2.5 rounded-lg text-[13px] font-medium text-ink-muted hover:text-ink border border-line hover:bg-surface"
          >
            Im Hintergrund weiterlaufen lassen
          </button>
          <div className="text-[10.5px] text-ink-soft text-center mt-2">
            Du kannst weiterarbeiten — Cortex meldet sich wenn neue Leads bereit sind.
          </div>
        </div>
      </div>
    </div>
  );
}

function FunnelStat({ label, value, highlight }) {
  // RollingNumber interpoliert sichtbar von prev→value in ~280-900ms mit
  // ease-out-quart. Das fühlt sich natürlich an, auch wenn der Server in
  // Batches schreibt (z.B. 0 → 8 in einem einzigen updateProgress-Call).
  return (
    <div>
      <RollingNumber
        className={`text-[18px] font-semibold tabular-nums block ${highlight ? 'text-emerald-700' : 'text-ink'}`}
        value={value}/>
      <div className="text-[10px] uppercase tracking-[0.04em] text-ink-soft leading-tight">
        {label}
      </div>
    </div>
  );
}
