"use client";

import { Badge } from "./ui/badge";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "./ui/card";

type JsonRecord = Record<string, unknown>;

function asRecord(value: unknown): JsonRecord | null {
  return typeof value === "object" && value !== null ? (value as JsonRecord) : null;
}

function asString(value: unknown): string | null {
  return typeof value === "string" ? value : null;
}

function asNumber(value: unknown): number | null {
  return typeof value === "number" && Number.isFinite(value) ? value : null;
}

function asBoolean(value: unknown): boolean | null {
  return typeof value === "boolean" ? value : null;
}

function asStringArray(value: unknown): string[] {
  if (!Array.isArray(value)) return [];
  return value.filter((entry): entry is string => typeof entry === "string");
}

function asRecordArray(value: unknown): JsonRecord[] {
  if (!Array.isArray(value)) return [];
  return value
    .map((entry) => asRecord(entry))
    .filter((entry): entry is JsonRecord => entry !== null);
}

type TrustedOriginDebugSectionProps = {
  value: unknown;
};

export function TrustedOriginDebugSection({ value }: TrustedOriginDebugSectionProps) {
  const payload = asRecord(value);
  if (!payload) return null;

  const runtime = asRecord(payload.runtime);
  const currentRequest = asRecord(payload.currentRequest);
  const recentRejectedAttempts = asRecordArray(payload.recentRejectedAttempts);
  const rejectionCount = asNumber(payload.rejectedAttemptCount) ?? recentRejectedAttempts.length;
  const maxStoredRejectedAttempts = asNumber(payload.maxStoredRejectedAttempts);
  const note = asString(payload.note);

  return (
    <Card>
      <CardHeader>
        <CardTitle>Trusted origin rejection debugger</CardTitle>
        <CardDescription>
          Recent proxy-side `TRUSTED_ORIGINS` rejections with the delivered Origin header,
          the current allowlist, and the exact env addition that would allow the request.
        </CardDescription>
      </CardHeader>
      <CardContent className="grid gap-4">
        <div className="flex flex-wrap items-center gap-2 text-xs">
          <Badge variant={rejectionCount > 0 ? "warning" : "success"}>
            rejected attempts: {rejectionCount}
          </Badge>
          <Badge variant="secondary">
            buffer: {maxStoredRejectedAttempts ?? recentRejectedAttempts.length}
          </Badge>
          <Badge
            variant={asBoolean(currentRequest?.originPresent) ? "secondary" : "success"}
          >
            current request origin: {asBoolean(currentRequest?.originPresent) ? "present" : "none"}
          </Badge>
        </div>

        <div className="grid gap-2 rounded-xl border border-slate-200 bg-white p-4 text-sm">
          <div>
            <strong>Expected base origin:</strong>{" "}
            {asString(runtime?.baseOrigin) || asString(currentRequest?.expectedBaseOrigin) || "(none)"}
          </div>
          <div>
            <strong>Configured TRUSTED_ORIGINS raw:</strong>{" "}
            {asString(runtime?.trustedOriginsRaw) || "(empty)"}
          </div>
          <div>
            <strong>Normalized allowlist:</strong>{" "}
            {asStringArray(runtime?.trustedOrigins).join(", ") || "(none)"}
          </div>
          <div>
            <strong>Current request delivered Origin:</strong>{" "}
            {asString(currentRequest?.deliveredOrigin) ?? "(no Origin header)"}
          </div>
          <div>
            <strong>Current request source:</strong>{" "}
            {asString(currentRequest?.sourceHeader) ?? "(none)"}
          </div>
          <div>
            <strong>Current request normalized Origin:</strong>{" "}
            {asString(currentRequest?.normalizedDeliveredOrigin) ?? "(not derivable)"}
          </div>
          <div>
            <strong>Current request suggestion:</strong>{" "}
            {asString(currentRequest?.suggestedTrustedOrigin) ?? "(no suggestion)"}
          </div>
          <div className="rounded-md border border-slate-200 bg-slate-50 px-3 py-2 text-xs text-slate-700">
            {note ?? "Recent rejected attempts are stored in-memory in the active demo proxy process."}
          </div>
        </div>

        <section className="rounded-xl border border-slate-200 bg-white p-4">
          <h3 className="text-sm font-semibold text-slate-900">Recent rejected attempts</h3>
          <p className="mt-1 text-xs text-slate-500">
            Each row shows what the browser delivered, what the proxy expected, and the
            exact `TRUSTED_ORIGINS` line you can paste into `.env.local` or `.env`.
          </p>

          <div className="mt-3 overflow-x-auto">
            <table className="min-w-full table-fixed border-collapse text-xs">
              <thead>
                <tr className="bg-slate-100 text-left text-slate-700">
                  <th className="border border-slate-200 px-2 py-2">When</th>
                  <th className="border border-slate-200 px-2 py-2">Request</th>
                  <th className="border border-slate-200 px-2 py-2">Delivered</th>
                  <th className="border border-slate-200 px-2 py-2">Expected</th>
                  <th className="border border-slate-200 px-2 py-2">Suggested addition</th>
                </tr>
              </thead>
              <tbody>
                {recentRejectedAttempts.length === 0 ? (
                  <tr>
                    <td className="border border-slate-200 px-2 py-3 text-slate-500" colSpan={5}>
                      No rejected origin attempts have been recorded in this process yet.
                    </td>
                  </tr>
                ) : (
                  recentRejectedAttempts.map((entry) => {
                    const phase = asString(entry.phase) ?? "unknown";
                    const method = asString(entry.method) ?? "UNKNOWN";
                    const requestPath = asString(entry.requestPath) ?? "(unknown)";
                    const deliveredOrigin = asString(entry.deliveredOrigin);
                    const normalizedDeliveredOrigin = asString(entry.normalizedDeliveredOrigin);
                    const expectedTrustedOrigins = asStringArray(entry.expectedTrustedOrigins);
                    const suggestedTrustedOrigin = asString(entry.suggestedTrustedOrigin);
                    const suggestedEnvLine = asString(entry.suggestedTrustedOriginsEnvLine);
                    const suggestionReason = asString(entry.suggestionReason);

                    return (
                      <tr key={asString(entry.id) ?? `${phase}-${requestPath}`}>
                        <td className="border border-slate-200 px-2 py-2 align-top">
                          <div className="grid gap-1">
                            <div>{asString(entry.occurredAt) ?? "-"}</div>
                            <Badge variant={phase === "proxy_preflight" ? "warning" : "secondary"}>
                              {phase}
                            </Badge>
                          </div>
                        </td>
                        <td className="border border-slate-200 px-2 py-2 align-top">
                          <div className="grid gap-1">
                            <div>{method}</div>
                            <div className="text-[11px] text-slate-500">{requestPath}</div>
                            <div className="text-[11px] text-slate-500">
                              {asString(entry.requestUrl) ?? ""}
                            </div>
                          </div>
                        </td>
                        <td className="border border-slate-200 px-2 py-2 align-top">
                          <div className="grid gap-1">
                            <div>{deliveredOrigin ?? "(missing Origin header)"}</div>
                            <div className="text-[11px] text-slate-500">
                              normalized: {normalizedDeliveredOrigin ?? "(not derivable)"}
                            </div>
                            <div className="text-[11px] text-slate-500">
                              referer: {asString(entry.deliveredReferer) ?? asString(entry.referer) ?? "(none)"}
                            </div>
                            <div className="text-[11px] text-slate-500">
                              source: {asString(entry.sourceHeader) ?? "(none)"}
                            </div>
                          </div>
                        </td>
                        <td className="border border-slate-200 px-2 py-2 align-top">
                          <div className="grid gap-1">
                            <div>
                              base: {asString(entry.expectedBaseOrigin) ?? "(none)"}
                            </div>
                            <div>
                              {expectedTrustedOrigins.join(", ") || "(no TRUSTED_ORIGINS configured)"}
                            </div>
                            <div className="text-[11px] text-slate-500">
                              raw: {asString(entry.expectedTrustedOriginsRaw) || "(empty)"}
                            </div>
                          </div>
                        </td>
                        <td className="border border-slate-200 px-2 py-2 align-top">
                          <div className="grid gap-1">
                            <Badge variant={suggestedTrustedOrigin ? "success" : "destructive"}>
                              {suggestedTrustedOrigin ?? "no safe suggestion"}
                            </Badge>
                            <div className="rounded-md bg-slate-50 px-2 py-2 font-mono text-[11px] text-slate-700">
                              {suggestedEnvLine ?? "(no env line available)"}
                            </div>
                            <div className="text-[11px] text-slate-500">
                              {suggestionReason ?? ""}
                            </div>
                          </div>
                        </td>
                      </tr>
                    );
                  })
                )}
              </tbody>
            </table>
          </div>
        </section>
      </CardContent>
    </Card>
  );
}
