"use client";

import Link from "next/link";
import { AppShell } from "@/components/app-shell";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import {
  useOperations,
  type OpsService,
  type OperationsSnapshot,
} from "@/lib/api/operations";

function mb(bytes: number): string {
  return `${Math.round((bytes || 0) / 1024 / 1024)}MB`;
}

function uptime(ms: number): string {
  if (!ms) return "—";
  const secs = Math.floor((Date.now() - ms) / 1000);
  if (secs < 60) return `${secs}ש׳`;
  if (secs < 3600) return `${Math.floor(secs / 60)}ד׳`;
  if (secs < 86400) return `${Math.floor(secs / 3600)}ש׳`;
  return `${Math.floor(secs / 86400)}י׳`;
}

const STATUS_VARIANT: Record<string, "default" | "secondary" | "destructive" | "outline"> = {
  online: "default",
  done: "default",
  approved: "default",
  completed: "default",
  stopped: "secondary",
  pending: "secondary",
  pending_review: "secondary",
  running: "outline",
  processing: "outline",
  failed: "destructive",
  errored: "destructive",
  manual: "destructive",
  open: "secondary",
};

function StatusBadge({ value, count }: { value: string; count?: number }) {
  return (
    <Badge variant={STATUS_VARIANT[value] ?? "outline"} className="font-normal">
      {value}
      {count !== undefined ? <span className="ms-1 font-semibold">{count}</span> : null}
    </Badge>
  );
}

const SERVICE_LABELS: Record<string, string> = {
  "legal-court-fetch-service": "שירות אחזור פסיקה (דפדפן נט המשפט)",
  "legal-court-fetch-xvfb": "צג וירטואלי (Xvfb) לדפדפן",
  "legal-court-fetch-drain": "תזמון: ניקוז תור אחזור (שעתי)",
  "legal-metadata-drain": "תזמון: חילוץ מטא-דאטה (Gemini, ×15 דק׳)",
  "legal-halacha-drain": "תזמון: חילוץ הלכות (Claude, ×שעתיים)",
  "legal-reaper": "מנקה תהליכים-יתומים (נגד דליפות זיכרון)",
  "legal-chat-service": "שירות צ׳אט אימון (גשר ל-claude CLI)",
};

function ServicesSection({ data }: { data: OperationsSnapshot }) {
  return (
    <Card className="bg-surface border-rule shadow-sm">
      <CardContent className="px-6 py-5">
        <h2 className="text-navy text-lg mb-1">שירותי רקע (pm2)</h2>
        <p className="text-ink-muted text-xs mb-4">
          דמונים ומשימות-תזמון על שרת המארח. &quot;cron&quot; = רץ לפי לוח-זמנים (מציג
          &quot;stopped&quot; בין הרצות — תקין).
        </p>
        {data.services_error ? (
          <p className="text-sm text-destructive">{data.services_error}</p>
        ) : data.services.length === 0 ? (
          <p className="text-sm text-ink-muted">אין שירותים.</p>
        ) : (
          <div className="grid gap-2 sm:grid-cols-2">
            {data.services.map((s: OpsService) => (
              <div
                key={s.name}
                className="flex items-center justify-between gap-3 rounded-md border border-rule-soft bg-rule-soft/30 px-3 py-2"
              >
                <div className="min-w-0">
                  <div className="flex items-center gap-2">
                    <StatusBadge value={s.status} />
                    {s.cron ? (
                      <span className="text-[0.7rem] text-ink-muted font-mono" dir="ltr">
                        {s.cron}
                      </span>
                    ) : null}
                  </div>
                  <div className="text-[0.78rem] text-navy truncate mt-0.5">
                    {SERVICE_LABELS[s.name] ?? s.name}
                  </div>
                  <div className="text-[0.68rem] text-ink-muted font-mono" dir="ltr">
                    {s.name}
                  </div>
                </div>
                <div className="text-end text-[0.7rem] text-ink-muted shrink-0">
                  <div>{mb(s.memory_bytes)}</div>
                  <div>↻{s.restarts}</div>
                  {!s.cron ? <div>{uptime(s.uptime_ms)}</div> : null}
                </div>
              </div>
            ))}
          </div>
        )}
      </CardContent>
    </Card>
  );
}

function StatusRow({ by }: { by: Record<string, number> }) {
  const entries = Object.entries(by).filter(([, n]) => n > 0);
  if (entries.length === 0) return <span className="text-ink-muted text-sm">ריק</span>;
  return (
    <div className="flex flex-wrap gap-1.5">
      {entries
        .sort((a, b) => b[1] - a[1])
        .map(([k, n]) => (
          <StatusBadge key={k} value={k} count={n} />
        ))}
    </div>
  );
}

function PipelineCard({
  title,
  desc,
  children,
}: {
  title: string;
  desc: string;
  children: React.ReactNode;
}) {
  return (
    <Card className="bg-surface border-rule shadow-sm">
      <CardContent className="px-5 py-4 space-y-2">
        <div>
          <h3 className="text-navy text-sm font-semibold mb-0.5">{title}</h3>
          <p className="text-ink-muted text-[0.72rem]">{desc}</p>
        </div>
        {children}
      </CardContent>
    </Card>
  );
}

export default function OperationsPage() {
  const { data, isLoading, error } = useOperations();

  return (
    <AppShell>
      <section className="space-y-6">
        <header>
          <nav className="text-[0.78rem] text-ink-muted mb-1">
            <Link href="/" className="hover:text-gold-deep">בית</Link>
            <span aria-hidden> · </span>
            <span className="text-navy">תפעול</span>
          </nav>
          <h1 className="text-navy mb-0">תפעול — מה רץ ברקע</h1>
          <p className="text-ink-muted text-sm mt-1 max-w-3xl">
            כל מה שמוריד ומנתח אוטומטית: שירותי-המארח, משימות-התזמון, ותורי-העבודה.
            מתרענן כל 5 שניות.
          </p>
        </header>

        {error ? (
          <Card className="bg-surface border-rule">
            <CardContent className="px-6 py-5 text-sm text-destructive">
              שגיאה בטעינת מצב התפעול: {String(error)}
            </CardContent>
          </Card>
        ) : isLoading || !data ? (
          <div className="space-y-4">
            <Skeleton className="h-40 w-full" />
            <Skeleton className="h-40 w-full" />
          </div>
        ) : (
          <>
            <ServicesSection data={data} />

            <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
              <PipelineCard
                title="אחזור פסיקה (X13)"
                desc="הורדה אוטומטית מנט-המשפט / פורטל-העליון → קורפוס"
              >
                <StatusRow by={data.pipelines.court_fetch.by_status} />
              </PipelineCard>

              <PipelineCard
                title="חילוץ מטא-דאטה"
                desc="Gemini Flash — שם/תקציר/תגיות לכל פסיקה"
              >
                <StatusRow by={data.pipelines.metadata_extraction.by_status} />
                <p className="text-[0.72rem] text-ink-muted">
                  בתור לחילוץ: {data.pipelines.metadata_extraction.queued}
                </p>
              </PipelineCard>

              <PipelineCard
                title="חילוץ הלכות"
                desc="Claude — הלכות מכל פסיקה (→ אישור יו״ר)"
              >
                <StatusRow by={data.pipelines.halacha_extraction.by_status} />
                <p className="text-[0.72rem] text-ink-muted">
                  בתור לחילוץ: {data.pipelines.halacha_extraction.queued}
                </p>
              </PipelineCard>

              <PipelineCard
                title="אישור הלכות (שער יו״ר)"
                desc="הלכות שחולצו, ממתינות להכרעת דפנה ב-/approvals"
              >
                <StatusRow by={data.pipelines.halacha_review.by_status} />
              </PipelineCard>

              <PipelineCard
                title="פסיקה חסרה"
                desc="פערים בקורפוס — נסגרים אוטומטית כשנקלטים"
              >
                <StatusRow by={data.pipelines.missing_precedents.by_status} />
              </PipelineCard>

              <PipelineCard
                title="יומונים (רדאר)"
                desc="מצביעים על פסקי-דין → מזניקים אחזור אוטומטי"
              >
                <p className="text-sm text-navy">
                  {data.pipelines.digests.linked}/{data.pipelines.digests.total} מקושרים
                  לפסיקה
                </p>
              </PipelineCard>
            </div>

            <div className="grid gap-4 lg:grid-cols-2">
              <Card className="bg-surface border-rule shadow-sm">
                <CardContent className="px-5 py-4">
                  <h3 className="text-navy text-sm font-semibold mb-2">
                    אחזורים אחרונים (תור)
                  </h3>
                  <div className="space-y-1.5">
                    {data.pipelines.court_fetch.recent.map((j) => (
                      <div
                        key={j.case_number_norm}
                        className="flex items-start justify-between gap-2 text-[0.78rem] border-b border-rule-soft pb-1.5 last:border-0"
                      >
                        <div className="min-w-0">
                          <StatusBadge value={j.status} />
                          <span className="text-navy ms-2">
                            {j.citation_raw?.slice(0, 48) || j.case_number_norm}
                          </span>
                          {j.error ? (
                            <div className="text-ink-muted text-[0.68rem] truncate">
                              {j.error.slice(0, 80)}
                            </div>
                          ) : null}
                        </div>
                        <span className="text-ink-muted text-[0.66rem] shrink-0" dir="ltr">
                          {(j.tier || "").slice(0, 7)}
                        </span>
                      </div>
                    ))}
                  </div>
                </CardContent>
              </Card>

              <Card className="bg-surface border-rule shadow-sm">
                <CardContent className="px-5 py-4">
                  <h3 className="text-navy text-sm font-semibold mb-2">
                    נקלטו לאחרונה (מבתי-משפט)
                  </h3>
                  <div className="space-y-1.5">
                    {data.pipelines.ingested_recent.map((r) => (
                      <div
                        key={r.case_number}
                        className="text-[0.78rem] text-navy border-b border-rule-soft pb-1.5 last:border-0 truncate"
                      >
                        {r.case_number}
                        <span className="text-ink-muted text-[0.66rem] ms-2" dir="ltr">
                          {r.created_at?.slice(0, 16).replace("T", " ")}
                        </span>
                      </div>
                    ))}
                    {data.pipelines.ingested_recent.length === 0 ? (
                      <p className="text-ink-muted text-sm">עדיין אין.</p>
                    ) : null}
                  </div>
                </CardContent>
              </Card>
            </div>
          </>
        )}
      </section>
    </AppShell>
  );
}
