import { useQuery } from "@tanstack/react-query";
import { http } from "../api/http";

type AppHealth = { ok: true };
type DbHealth = { ok: true; nowISO: string; latencyMs: number };

export default function HealthPage() {
  const app = useQuery({
    queryKey: ["health"],
    queryFn: () => http<AppHealth>("/health"),
  });

  const db = useQuery({
    queryKey: ["health", "db"],
    queryFn: () => http<DbHealth>("/health/db"),
  });

  const appStatus = getStatus(app.isLoading, !!app.data?.ok, !!app.error);
  const dbStatus = getStatus(db.isLoading, !!db.data?.ok, !!db.error);

  return (
    <div className="flex justify-center py-10">
      <div className="card w-full max-w-xl space-y-6">
        <header className="space-y-1">
          <h2 className="section-title">System Health</h2>
          <p className="muted text-sm">
            Quick status for the SkyMoney API and database. Use this when debugging issues or latency.
          </p>
        </header>

        {/* Status overview */}
        <div className="grid gap-4 md:grid-cols-2">
          <HealthCard
            label="API"
            status={appStatus}
            description="Core application and auth endpoints."
            details={
              <>
                <StatusLine
                  label="Status"
                  value={labelForStatus(appStatus)}
                />
                {app.error && (
                  <StatusLine
                    label="Error"
                    value={
                      app.error instanceof Error
                        ? app.error.message
                        : "Unknown error"
                    }
                  />
                )}
              </>
            }
            onRetry={!app.isLoading ? () => app.refetch() : undefined}
          />

          <HealthCard
            label="Database"
            status={dbStatus}
            description="Primary PostgreSQL connection and latency."
            details={
              <>
                <StatusLine
                  label="Status"
                  value={labelForStatus(dbStatus)}
                />
                <StatusLine
                  label="Latency"
                  value={
                    db.data?.latencyMs != null
                      ? `${db.data.latencyMs} ms`
                      : db.isLoading
                      ? "Measuring…"
                      : "—"
                  }
                />
                <StatusLine
                  label="Server time"
                  value={
                    db.data?.nowISO
                      ? new Date(db.data.nowISO).toLocaleString()
                      : db.isLoading
                      ? "Loading…"
                      : "—"
                  }
                />
                {db.error && (
                  <StatusLine
                    label="Error"
                    value={
                      db.error instanceof Error
                        ? db.error.message
                        : "Unknown error"
                    }
                  />
                )}
              </>
            }
            onRetry={!db.isLoading ? () => db.refetch() : undefined}
          />
        </div>

        {/* Raw data (tiny, for debugging) */}
        <section className="border rounded-xl p-3 space-y-2 bg-[--color-panel]">
          <div className="row items-center">
            <span className="text-xs uppercase tracking-[0.2em] muted">
              Debug
            </span>
            <span className="ml-auto text-xs muted">
              Useful for logs / screenshots
            </span>
          </div>
          <pre className="text-xs whitespace-pre-wrap break-all muted">
            API: {app.isLoading ? "Loading…" : JSON.stringify(app.data ?? { ok: false })}{"\n"}
            DB: {db.isLoading ? "Loading…" : JSON.stringify(db.data ?? { ok: false })}
          </pre>
        </section>
      </div>
    </div>
  );
}

type Status = "checking" | "up" | "down";

function getStatus(
  isLoading: boolean,
  ok: boolean,
  hasError: boolean,
): Status {
  if (isLoading) return "checking";
  if (ok && !hasError) return "up";
  return "down";
}

function labelForStatus(status: Status) {
  if (status === "checking") return "Checking…";
  if (status === "up") return "Operational";
  return "Unavailable";
}

function HealthCard({
  label,
  status,
  description,
  details,
  onRetry,
}: {
  label: string;
  status: Status;
  description: string;
  details: React.ReactNode;
  onRetry?: () => void;
}) {
  return (
    <section className="border rounded-xl p-4 bg-[--color-panel] space-y-3">
      <div className="row items-center gap-2">
        <div className="space-y-1">
          <div className="text-sm font-semibold">{label}</div>
          <p className="text-xs muted">{description}</p>
        </div>
        <StatusPill status={status} className="ml-auto" />
      </div>

      <div className="space-y-1 text-xs">{details}</div>

      {onRetry && (
        <div className="row mt-2">
          <button type="button" className="btn text-xs ml-auto" onClick={onRetry}>
            Recheck
          </button>
        </div>
      )}
    </section>
  );
}

function StatusPill({
  status,
  className = "",
}: {
  status: Status;
  className?: string;
}) {
  let text = "";
  let tone = "";

  switch (status) {
    case "checking":
      text = "Checking…";
      tone = "bg-amber-500/10 text-amber-100 border border-amber-500/40";
      break;
    case "up":
      text = "OK";
      tone = "bg-emerald-500/10 text-emerald-200 border border-emerald-500/40";
      break;
    case "down":
      text = "Down";
      tone = "bg-red-500/10 text-red-100 border border-red-500/40";
      break;
  }

  return (
    <span className={`badge text-xs ${tone} ${className}`}>
      <span className="inline-block w-2 h-2 rounded-full mr-1 bg-current" />
      {text}
    </span>
  );
}

function StatusLine({ label, value }: { label: string; value: string }) {
  return (
    <div className="row text-xs">
      <span className="muted">{label}</span>
      <span className="ml-auto text-right">{value}</span>
    </div>
  );
}
