import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AlertTriangle, Database, Trash2 } from "lucide-react";
import { RoleGuard } from "../../components/auth/RoleGuard";
import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import {
  fetchOrySSOTSystemStatus,
  flushIdentityCache,
} from "../../lib/adminApi";
import { t } from "../../lib/i18n";
import { getAdminDateLocale } from "../../lib/locale";

function formatDateTime(value?: string) {
  if (!value) return "-";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return new Intl.DateTimeFormat(getAdminDateLocale(), {
    dateStyle: "medium",
    timeStyle: "medium",
  }).format(date);
}

function StatusBadge({ ready, status }: { ready: boolean; status: string }) {
  if (ready) {
    return (
      <Badge variant="success">
        {t("ui.admin.ory_ssot.status.ready", "ready")}
      </Badge>
    );
  }
  if (status === "failed") {
    return (
      <Badge variant="warning">
        {t("ui.admin.ory_ssot.status.failed", "failed")}
      </Badge>
    );
  }
  return (
    <Badge variant="secondary">
      {status ? status : t("ui.admin.ory_ssot.status.not_ready", "not ready")}
    </Badge>
  );
}

export function UserProjectionContent({
  embedded = false,
}: {
  embedded?: boolean;
}) {
  const queryClient = useQueryClient();
  const { data, isLoading, isError, error } = useQuery({
    queryKey: ["ory-ssot-system-status"],
    queryFn: fetchOrySSOTSystemStatus,
  });

  const flushMutation = useMutation({
    mutationFn: flushIdentityCache,
    onSuccess: async () => {
      await queryClient.invalidateQueries({
        queryKey: ["ory-ssot-system-status"],
      });
    },
  });

  const handleFlush = () => {
    const confirmed = window.confirm(
      t(
        "msg.admin.ory_ssot.flush_confirm",
        "Flush only Redis identity cache keys?",
      ),
    );
    if (confirmed) flushMutation.mutate();
  };

  const projection = data?.userProjection;
  const identityCache = data?.identityCache;

  const header = (
    <header
      className={
        embedded
          ? "flex flex-shrink-0 flex-wrap items-start justify-between gap-4"
          : "flex flex-shrink-0 flex-wrap items-start justify-between gap-4 sticky top-[-2.5rem] z-20 -mt-4 bg-background/95 pb-2 pt-4 backdrop-blur"
      }
    >
      <div className="flex min-w-0 items-start gap-3">
        <div className="mt-1 flex h-10 w-10 shrink-0 items-center justify-center rounded-xl border border-primary/15 bg-primary/10 text-primary">
          <Database size={20} />
        </div>
        <div className="space-y-2">
          <h2 className="text-3xl font-semibold">
            {t("ui.admin.ory_ssot.title", "Ory SSOT System")}
          </h2>
          <p className="text-sm text-muted-foreground">
            {t(
              "msg.admin.ory_ssot.subtitle",
              "Review Kratos source-of-truth and Redis identity cache status separately.",
            )}
          </p>
        </div>
      </div>
      <Button
        type="button"
        variant="destructive"
        onClick={handleFlush}
        disabled={flushMutation.isPending}
      >
        <Trash2 size={16} />
        {t(
          "ui.admin.ory_ssot.actions.flush_identity_cache",
          "Redis cache flush",
        )}
      </Button>
    </header>
  );

  const body = (
    <>
      {isError ? (
        <section className="rounded-lg border border-destructive/30 bg-destructive/10 p-4 text-sm text-destructive">
          {(error as Error)?.message ||
            t(
              "msg.admin.ory_ssot.load_error",
              "Failed to load Ory SSOT system status.",
            )}
        </section>
      ) : null}

      {flushMutation.data ? (
        <section className="rounded-lg border border-emerald-200 bg-emerald-50 p-4 text-sm text-emerald-800 dark:border-emerald-900 dark:bg-emerald-950/40 dark:text-emerald-200">
          {t(
            "msg.admin.ory_ssot.flush_success",
            "Flushed {{count}} Redis identity cache keys.",
            { count: flushMutation.data.flushedKeys },
          )}
        </section>
      ) : null}

      {flushMutation.error ? (
        <section className="rounded-lg border border-destructive/30 bg-destructive/10 p-4 text-sm text-destructive">
          {(flushMutation.error as Error)?.message ||
            t(
              "msg.admin.ory_ssot.flush_error",
              "Redis identity cache flush failed.",
            )}
        </section>
      ) : null}

      <section className="rounded-lg border border-border bg-card p-5">
        <div className="flex items-center gap-3 border-b border-border pb-4">
          <div>
            <h3 className="text-lg font-bold">
              {t(
                "ui.admin.ory_ssot.projection_card.title",
                "Backend user read model",
              )}
            </h3>
            <p className="text-sm text-muted-foreground">
              {t(
                "ui.admin.ory_ssot.projection_card.description",
                "PostgreSQL read model status used by admin search and statistics.",
              )}
            </p>
          </div>
        </div>

        {isLoading ? (
          <div className="py-8 text-sm text-muted-foreground">
            {t("ui.admin.ory_ssot.loading", "Loading")}
          </div>
        ) : (
          <dl className="grid gap-4 py-5 sm:grid-cols-2 lg:grid-cols-4">
            <div>
              <dt className="text-sm text-muted-foreground">
                {t("ui.admin.ory_ssot.summary.status", "Status")}
              </dt>
              <dd className="mt-1">
                <StatusBadge
                  ready={projection?.ready ?? false}
                  status={projection?.status ?? "unknown"}
                />
              </dd>
            </div>
            <div>
              <dt className="text-sm text-muted-foreground">
                {t("ui.admin.ory_ssot.summary.local_users", "Local users")}
              </dt>
              <dd className="mt-1 text-xl font-semibold tabular-nums">
                {projection?.projectedUsers ?? 0}
              </dd>
            </div>
            <div>
              <dt className="text-sm text-muted-foreground">
                {t(
                  "ui.admin.ory_ssot.summary.last_synced",
                  "Last read-model refresh",
                )}
              </dt>
              <dd className="mt-1 text-sm">
                {formatDateTime(projection?.lastSyncedAt)}
              </dd>
            </div>
            <div>
              <dt className="text-sm text-muted-foreground">
                {t("ui.admin.ory_ssot.summary.updated_at", "Updated at")}
              </dt>
              <dd className="mt-1 text-sm">
                {formatDateTime(projection?.updatedAt)}
              </dd>
            </div>
          </dl>
        )}

        {projection?.lastError ? (
          <div className="flex gap-2 rounded-lg border border-amber-200 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-900 dark:bg-amber-950/40 dark:text-amber-200">
            <AlertTriangle className="mt-0.5 shrink-0" size={16} />
            <span>{projection.lastError}</span>
          </div>
        ) : null}
      </section>

      <section className="rounded-lg border border-border bg-card p-5">
        <div className="flex items-center gap-3 border-b border-border pb-4">
          <div>
            <h3 className="text-lg font-bold">
              {t("ui.admin.ory_ssot.cache_card.title", "Redis identity cache")}
            </h3>
            <p className="text-sm text-muted-foreground">
              {t(
                "ui.admin.ory_ssot.cache_card.description",
                "Redis mirror/cache status for Kratos identity list and lookup operations.",
              )}
            </p>
          </div>
        </div>

        {isLoading ? (
          <div className="py-8 text-sm text-muted-foreground">
            {t("ui.admin.ory_ssot.loading", "Loading")}
          </div>
        ) : (
          <dl className="grid gap-4 py-5 sm:grid-cols-2 lg:grid-cols-4">
            <div>
              <dt className="text-sm text-muted-foreground">
                {t("ui.admin.ory_ssot.summary.status", "Status")}
              </dt>
              <dd className="mt-1">
                <StatusBadge
                  ready={
                    Boolean(identityCache?.redisReady) &&
                    identityCache?.status === "ready"
                  }
                  status={identityCache?.status ?? "unknown"}
                />
              </dd>
            </div>
            <div>
              <dt className="text-sm text-muted-foreground">
                {t(
                  "ui.admin.ory_ssot.summary.observed_identities",
                  "Observed identities",
                )}
              </dt>
              <dd className="mt-1 text-xl font-semibold tabular-nums">
                {identityCache?.observedCount ?? 0}
              </dd>
            </div>
            <div>
              <dt className="text-sm text-muted-foreground">
                {t("ui.admin.ory_ssot.summary.cache_keys", "Cache keys")}
              </dt>
              <dd className="mt-1 text-xl font-semibold tabular-nums">
                {identityCache?.keyCount ?? 0}
              </dd>
            </div>
            <div>
              <dt className="text-sm text-muted-foreground">
                {t(
                  "ui.admin.ory_ssot.summary.last_refreshed",
                  "Last refreshed",
                )}
              </dt>
              <dd className="mt-1 text-sm">
                {formatDateTime(identityCache?.lastRefreshedAt)}
              </dd>
            </div>
          </dl>
        )}

        {identityCache?.lastError ? (
          <div className="flex gap-2 rounded-lg border border-amber-200 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-900 dark:bg-amber-950/40 dark:text-amber-200">
            <AlertTriangle className="mt-0.5 shrink-0" size={16} />
            <span>{identityCache.lastError}</span>
          </div>
        ) : null}
      </section>
    </>
  );

  if (embedded) {
    return (
      <div className="space-y-4 pb-6">
        {header}
        {body}
      </div>
    );
  }

  return (
    <main className="space-y-6 flex flex-col h-[calc(100vh-theme(spacing.32))]">
      {header}
      {body}
    </main>
  );
}

export default function UserProjectionPage() {
  return (
    <RoleGuard
      roles={["super_admin"]}
      fallback={
        <main className="p-6 md:p-8">
          <section className="rounded-lg border border-border bg-card p-5">
            <h2 className="text-lg font-semibold">
              {t("ui.admin.ory_ssot.forbidden.title", "Access denied")}
            </h2>
            <p className="mt-2 text-sm text-muted-foreground">
              {t(
                "msg.admin.ory_ssot.forbidden.description",
                "This screen is only available to super_admin users.",
              )}
            </p>
          </section>
        </main>
      }
    >
      <UserProjectionContent />
    </RoleGuard>
  );
}
