import React, { useEffect, useMemo, useState } from "react";
import Modal from "./Modal";
import { Badge, ButtonSoft, Card } from "./ui";
import { apiGetJson } from "../api/client";
import type { ApiHealthResponse, ApiObservabilityMetricsResponse } from "../api/contracts";

export default function HealthStatusModal({
  open,
  onClose,
}: {
  open: boolean;
  onClose: () => void;
}) {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<ApiHealthResponse | null>(null);
  const [metrics, setMetrics] = useState<ApiObservabilityMetricsResponse | null>(null);
  const [error, setError] = useState<string>("");

  const envSorted = useMemo(() => {
    if (!data?.env) return [] as Array<[string, boolean]>;
    return Object.entries(data.env).sort((a, b) => a[0].localeCompare(b[0]));
  }, [data]);

  const authAllowedDomains = useMemo(() => {
    const domains = Array.isArray(data?.auth?.allowed_domains) ? data?.auth?.allowed_domains : [];
    return [...domains].sort((a, b) => String(a).localeCompare(String(b)));
  }, [data]);

  const fetchHealth = async () => {
    setLoading(true);
    setError("");
    try {
      const [healthJson, metricsJson] = await Promise.all([
        apiGetJson<ApiHealthResponse>("/api/health", { cache: "no-store" }),
        apiGetJson<ApiObservabilityMetricsResponse>("/api/observability/metrics?limit=25", { cache: "no-store" }).catch(
          () => null
        ),
      ]);
      setData(healthJson);
      setMetrics(metricsJson);
    } catch (e: any) {
      setError(e?.message || String(e));
      setData(null);
      setMetrics(null);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    if (!open) return;
    // Fetch on open.
    fetchHealth();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open]);

  const overallBadge = data?.ok ? (
    <Badge tone="green">Healthy</Badge>
  ) : (
    <Badge tone="red">Issues found</Badge>
  );

  return (
    <Modal open={open} onClose={onClose} title="System status">
      <div className="space-y-4">
        <div className="flex flex-wrap items-center justify-between gap-2">
          <div className="flex items-center gap-2">
            {data ? overallBadge : <Badge tone="slate">Unknown</Badge>}
            {data?.summary ? (
              <span className="text-sm text-slate-600">
                Required checks: {Number(data.summary.required_ok || 0)}/{Number(data.summary.required_total || 0)}
              </span>
            ) : null}
          </div>

          <div className="flex items-center gap-2">
            <ButtonSoft onClick={fetchHealth} disabled={loading}>
              {loading ? "Refreshing…" : "Refresh"}
            </ButtonSoft>
            <ButtonSoft onClick={onClose}>
              Close
            </ButtonSoft>
          </div>
        </div>

        {error ? (
          <div className="mt-panel-danger rounded-lg border p-3 text-sm">
            Failed to load status: <span className="font-mono">{error}</span>
          </div>
        ) : null}

        <Card>
          <div className="p-4">
            <div className="mb-2 text-sm font-semibold text-slate-800">Checks</div>
            {!data ? (
              <div className="text-sm text-slate-600">No data loaded yet.</div>
            ) : (
              <div className="space-y-2">
                {data.checks.map((c, idx) => (
                  <div
                    key={`${c.name}-${idx}`}
                    className="flex flex-col gap-1 rounded-md border border-slate-200 bg-white p-3"
                  >
                    <div className="flex items-center justify-between gap-2">
                      <div className="font-medium text-slate-900">{c.name}</div>
                      {c.ok ? <Badge tone="green">OK</Badge> : <Badge tone="red">Fail</Badge>}
                    </div>
                    <div className="text-sm text-slate-600">
                      {[c.kind, c.path].filter(Boolean).join(" • ")}
                    </div>
                    {c.error ? <div className="mt-text-danger text-sm">{c.error}</div> : null}
                  </div>
                ))}
              </div>
            )}
          </div>
        </Card>

        <Card>
          <div className="p-4">
            <div className="mb-2 text-sm font-semibold text-slate-800">Environment (presence only)</div>
            {!data ? (
              <div className="text-sm text-slate-600">No data loaded yet.</div>
            ) : (
              <div className="space-y-2">
                {envSorted.map(([k, present]) => (
                  <div
                    key={k}
                    className="flex items-center justify-between gap-2 rounded-md border border-slate-200 bg-white p-3"
                  >
                    <div className="font-mono text-sm text-slate-900">{k}</div>
                    {present ? <Badge tone="green">Present</Badge> : <Badge tone="amber">Missing</Badge>}
                  </div>
                ))}
              </div>
            )}
          </div>
        </Card>

        <Card>
          <div className="p-4">
            <div className="mb-2 text-sm font-semibold text-slate-800">Authentication</div>
            {!data?.auth ? (
              <div className="text-sm text-slate-600">Auth diagnostics unavailable in this response.</div>
            ) : (
              <div className="space-y-2">
                <div className="flex flex-wrap items-center gap-2">
                  {data.auth.required ? <Badge tone="amber">Auth required</Badge> : <Badge tone="slate">Auth optional</Badge>}
                  {data.auth.enabled ? <Badge tone="green">Auth enabled</Badge> : <Badge tone="red">Auth not enabled</Badge>}
                </div>
                <div className="rounded-md border border-slate-200 bg-white p-3 text-xs text-slate-700">
                  <div>
                    <span className="font-semibold text-slate-900">Issuer:</span> {data.auth.issuer || "Not configured"}
                  </div>
                  <div className="mt-1">
                    <span className="font-semibold text-slate-900">Audience:</span> {data.auth.audience || "Not configured"}
                  </div>
                  <div className="mt-1">
                    <span className="font-semibold text-slate-900">Email claim:</span> {data.auth.email_claim || "Not configured"}
                  </div>
                  <div className="mt-1">
                    <span className="font-semibold text-slate-900">Allowed domains:</span>{" "}
                    {authAllowedDomains.length ? authAllowedDomains.join(", ") : "Not configured"}
                  </div>
                </div>
                {data.auth.config_error ? (
                  <div className="mt-panel-danger rounded-md border p-3 text-xs">
                    <div className="font-semibold">Config error</div>
                    <div className="mt-1">{data.auth.config_error}</div>
                  </div>
                ) : null}
                {Array.isArray(data.auth.config_details) && data.auth.config_details.length ? (
                  <div className="mt-panel-warning rounded-md border p-3 text-xs">
                    <div className="font-semibold">Config details</div>
                    <div className="mt-2 space-y-1">
                      {data.auth.config_details.map((line, idx) => (
                        <div key={`${line}-${idx}`}>• {line}</div>
                      ))}
                    </div>
                  </div>
                ) : null}
                {Array.isArray(data.auth.config_warnings) && data.auth.config_warnings.length ? (
                  <div className="mt-panel-primary rounded-md border p-3 text-xs">
                    <div className="font-semibold">Config warnings</div>
                    <div className="mt-2 space-y-1">
                      {data.auth.config_warnings.map((line, idx) => (
                        <div key={`${line}-${idx}`}>• {line}</div>
                      ))}
                    </div>
                  </div>
                ) : null}
              </div>
            )}
          </div>
        </Card>

        {metrics ? (
          <Card>
            <div className="p-4">
              <div className="mb-2 text-sm font-semibold text-slate-800">API observability</div>
              <div className="mb-3 text-xs text-slate-600">
                Requests: {metrics.totals.requests} • Errors: {metrics.totals.errors} • Error rate:{" "}
                {(metrics.totals.error_rate * 100).toFixed(2)}%
              </div>
              <div className="space-y-2">
                {metrics.endpoints.slice(0, 8).map((m) => (
                  <div key={m.endpoint} className="rounded-md border border-slate-200 bg-white p-3">
                    <div className="flex items-center justify-between gap-2">
                      <div className="font-mono text-xs text-slate-900">{m.endpoint}</div>
                      {m.error_requests > 0 ? (
                        <Badge tone="red">{m.error_requests} errors</Badge>
                      ) : (
                        <Badge tone="green">No errors</Badge>
                      )}
                    </div>
                    <div className="mt-1 text-xs text-slate-600">
                      req={m.total_requests} • avg={m.avg_latency_ms}ms • p95={m.p95_latency_ms}ms • max={m.max_latency_ms}ms
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </Card>
        ) : null}
      </div>
    </Modal>
  );
}
