"use client";

import { useEffect, useState } from "react";

type Phase = "scraping" | "enriching" | "emails" | "topping" | "done";

interface JobStatus {
  status: "running" | "complete" | "failed";
  totalLeads: number;
  emailsFound: number;
  error?: string | null;
  results?: LeadResult[];
}

export interface LeadResult {
  id: string;
  companyName: string | null;
  domain: string | null;
  contactName: string | null;
  contactTitle: string | null;
  email: string | null;
  linkedinUrl: string | null;
  address: string | null;
  phone: string | null;
  createdAt: string;
  isNew: boolean;
}

interface LoadingCardProps {
  jobId: string;
  targetCount: number;
  query: string;
  region: string;
  onDone: (leads: LeadResult[], warning?: string) => void;
  onError: (message: string) => void;
}

const STEPS = [
  { id: "scraping" as Phase, label: "Unternehmen gefunden" },
  { id: "enriching" as Phase, label: "Kontakte ermitteln" },
  { id: "emails" as Phase, label: "E-Mails suchen" },
  { id: "done" as Phase, label: "Fertig" },
];

function getPhase(s: JobStatus): Phase {
  if (s.status === "complete") return "done";
  if (s.emailsFound > 0) return "emails";
  if (s.totalLeads > 0) return "enriching";
  return "scraping";
}

function stepState(step: Phase, currentPhase: Phase): "done" | "active" | "pending" {
  const order: Phase[] = ["scraping", "enriching", "emails", "done"];
  const stepIdx = order.indexOf(step);
  const currentIdx = order.indexOf(currentPhase);
  if (stepIdx < currentIdx) return "done";
  if (stepIdx === currentIdx) return "active";
  return "pending";
}

const PHASE_MIN: Record<Phase, number> = {
  scraping: 3,
  enriching: 35,
  emails: 60,
  topping: 88,
  done: 100,
};

export function LoadingCard({ jobId, targetCount, query, region, onDone, onError }: LoadingCardProps) {
  const [phase, setPhase] = useState<Phase>("scraping");
  const [totalLeads, setTotalLeads] = useState(0);
  const [emailsFound, setEmailsFound] = useState(0);
  const [progressWidth, setProgressWidth] = useState(3);
  const [isTopping, setIsTopping] = useState(false);
  const [optimizedQuery, setOptimizedQuery] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;
    let crawlInterval: ReturnType<typeof setInterval> | null = null;
    let pollTimeout: ReturnType<typeof setTimeout> | null = null;
    let currentJobId = jobId;
    let toppingActive = false;
    let mapsLeads: LeadResult[] = [];

    // Progress only ever moves forward
    function advanceBar(to: number) {
      setProgressWidth(prev => Math.max(prev, to));
    }

    crawlInterval = setInterval(() => {
      if (cancelled) return;
      setProgressWidth(prev => {
        const cap = toppingActive ? 96 : 88;
        if (prev >= cap) return prev;
        return prev + 0.4;
      });
    }, 200);

    async function startSerpSupplement(foundCount: number) {
      toppingActive = true;
      setIsTopping(true);
      setPhase("topping");
      advanceBar(88);

      try {
        const res = await fetch("/api/search/supplement", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ query, region, targetCount, foundCount }),
        });
        if (!res.ok) throw new Error("supplement start failed");
        const data = await res.json() as { jobId: string; optimizedQuery: string; usedAI: boolean };
        currentJobId = data.jobId;
        if (data.optimizedQuery) setOptimizedQuery(data.optimizedQuery);
        pollTimeout = setTimeout(poll, 2500);
      } catch {
        // Supplement failed — complete with Maps results only
        if (!cancelled) {
          setProgressWidth(100);
          setPhase("done");
          setTimeout(() => { if (!cancelled) onDone(mapsLeads); }, 800);
        }
      }
    }

    async function poll() {
      if (cancelled) return;
      try {
        const res = await fetch(`/api/jobs/${currentJobId}/status`);
        if (!res.ok) throw new Error("fetch failed");
        const data = await res.json() as JobStatus;

        if (!cancelled) {
          if (!toppingActive) {
            setTotalLeads(data.totalLeads);
            setEmailsFound(data.emailsFound);
            const p = getPhase(data);
            setPhase(p);
            advanceBar(PHASE_MIN[p]);
          }

          if (data.status === "complete") {
            const leads = (data.results ?? []) as LeadResult[];

            if (!toppingActive && data.totalLeads < targetCount) {
              // Maps returned fewer than requested → supplement with optimized SERP
              mapsLeads = leads;
              if (crawlInterval) clearInterval(crawlInterval);
              crawlInterval = setInterval(() => {
                if (cancelled) return;
                setProgressWidth(prev => prev >= 96 ? prev : prev + 0.3);
              }, 200);
              await startSerpSupplement(data.totalLeads);
            } else {
              // All done
              if (crawlInterval) clearInterval(crawlInterval);

              let finalLeads: LeadResult[];
              if (toppingActive) {
                // Deduplicate Maps + SERP by domain
                const seenDomains = new Set(mapsLeads.map(l => l.domain).filter(Boolean));
                const newLeads = leads.filter(l => !l.domain || !seenDomains.has(l.domain));
                finalLeads = [...mapsLeads, ...newLeads];
              } else {
                finalLeads = leads;
              }

              // The poll often catches status=complete before observing the
              // "emails" phase mid-run (Anymailfinder sets emailsFound then
              // immediately sets complete in back-to-back DB writes).
              // Always flash through "E-Mails suchen" so the step is visible.
              if (!toppingActive) {
                setPhase("emails");
                advanceBar(PHASE_MIN["emails"]);
                await new Promise(r => setTimeout(r, 500));
                if (cancelled) return;
              }

              setTotalLeads(finalLeads.length);
              setProgressWidth(100);
              setPhase("done");
              setTimeout(() => { if (!cancelled) onDone(finalLeads); }, 800);
            }
          } else if (data.status === "failed") {
            if (crawlInterval) clearInterval(crawlInterval);
            const partialLeads = (data.results ?? []) as LeadResult[];
            if (toppingActive) {
              // SERP failed — complete with Maps results
              setProgressWidth(100);
              setPhase("done");
              setTimeout(() => { if (!cancelled) onDone(mapsLeads); }, 800);
            } else if (partialLeads.length > 0) {
              // Job failed mid-way (e.g. Anymailfinder 402) but Maps results exist → show them
              setProgressWidth(100);
              setPhase("done");
              setTimeout(() => { if (!cancelled) onDone(partialLeads, data.error ?? undefined); }, 800);
            } else {
              onError(data.error ?? "Unbekannter Fehler");
            }
          } else {
            pollTimeout = setTimeout(poll, 2500);
          }
        }
      } catch {
        if (!cancelled) {
          pollTimeout = setTimeout(poll, 3000);
        }
      }
    }

    poll();

    return () => {
      cancelled = true;
      if (crawlInterval) clearInterval(crawlInterval);
      if (pollTimeout) clearTimeout(pollTimeout);
    };
  }, [jobId]); // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <div
      style={{
        background: "#111118",
        border: "1px solid #1e1e2e",
        borderRadius: 12,
        padding: 24,
        marginTop: 16,
      }}
    >
      {/* Header */}
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
        <span style={{ fontSize: 13, fontWeight: 500, color: "#ffffff" }}>
          {isTopping ? "Ergebnisse werden ergänzt" : "Ergebnisse werden gesucht"}
        </span>
        <span style={{ fontSize: 12, color: "#9ca3af" }}>
          {totalLeads > 0 || emailsFound > 0
            ? `${emailsFound} E-Mails · ${totalLeads} Unternehmen`
            : "Wird gestartet…"}
        </span>
      </div>

      {/* Progress bar — only ever moves forward */}
      <div
        style={{
          height: 5,
          borderRadius: 3,
          background: "#1e1e2e",
          overflow: "hidden",
          marginBottom: 16,
        }}
      >
        <div
          style={{
            height: "100%",
            width: `${progressWidth}%`,
            background: "linear-gradient(90deg, #3b82f6, #8b5cf6)",
            borderRadius: 3,
            transition: phase === "done" ? "width 0.5s ease" : "width 0.12s linear",
          }}
        />
      </div>

      {/* Steps */}
      <div style={{ display: "flex", gap: 20, marginBottom: 16, flexWrap: "wrap" }}>
        {STEPS.map((step) => {
          const state = isTopping ? "done" : stepState(step.id, phase);
          return (
            <div key={step.id} style={{ display: "flex", alignItems: "center", gap: 6 }}>
              <div
                style={{
                  width: 6,
                  height: 6,
                  borderRadius: 3,
                  background: state === "done" ? "#22c55e" : state === "active" ? "#3b82f6" : "#2e2e3e",
                  animation: state === "active" ? "pulse 1.5s infinite" : "none",
                }}
              />
              <span
                style={{
                  fontSize: 12,
                  color: state === "done" ? "#22c55e" : state === "active" ? "#ffffff" : "#6b7280",
                }}
              >
                {step.label}
              </span>
            </div>
          );
        })}
        {isTopping && (
          <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
            <div style={{ width: 6, height: 6, borderRadius: 3, background: "#3b82f6", animation: "pulse 1.5s infinite" }} />
            <span style={{ fontSize: 12, color: "#ffffff" }}>Ergebnisse auffüllen</span>
          </div>
        )}
      </div>

      {/* Optimized query hint */}
      {isTopping && optimizedQuery && (
        <div style={{ display: "flex", alignItems: "center", gap: 6, marginBottom: 14, fontSize: 11, color: "#6b7280" }}>
          <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="#8b5cf6" strokeWidth="2.5">
            <path d="M9.663 17h4.673M12 3v1m6.364 1.636-.707.707M21 12h-1M4 12H3m3.343-5.657-.707-.707m2.828 9.9a5 5 0 1 1 7.072 0l-.548.547A3.374 3.374 0 0 0 14 18.469V19a2 2 0 1 1-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/>
          </svg>
          KI-optimierte Suche:&nbsp;
          <span style={{ color: "#9ca3af", fontStyle: "italic" }}>„{optimizedQuery}"</span>
        </div>
      )}

      {/* Warning banner */}
      <div
        style={{
          borderLeft: "3px solid #f59e0b",
          background: "rgba(245,158,11,0.08)",
          padding: "10px 14px",
          borderRadius: 8,
          fontSize: 12,
          color: "#9ca3af",
        }}
      >
        ⚠️ Bitte diesen Tab nicht schließen, während die Suche läuft.
      </div>

      <style>{`
        @keyframes pulse {
          0%, 100% { opacity: 1; }
          50% { opacity: 0.3; }
        }
      `}</style>
    </div>
  );
}
