import { Badge, EmptyState, TableShell, Td, Th } from "@/components/ui";
import { formatDateTime } from "@/components/status";
import type { AuditLog } from "@/types";

/** Read-only audit viewer (SPEC 28, 32). Audit rows can never be edited. */

const ACTION_TONES: Record<string, "neutral" | "brand" | "success" | "warning" | "danger" | "info"> = {
  STUDENT_CREATED: "success",
  STUDENT_UPDATED: "info",
  STUDENT_ARCHIVED: "warning",
  STUDENT_RESTORED: "info",
  CURRICULUM_AUTO_ASSIGNED: "info",
  CURRICULUM_MANUALLY_OVERRIDDEN: "warning",
  ASSESSMENT_CHANGED: "brand",
  ASSESSMENT_BULK_CHANGED: "brand",
  EQUIVALENCY_CHANGED: "warning",
  NON_UNIT_PROGRESS_CHANGED: "info",
  CURRICULUM_PUBLISHED: "success",
  CURRICULUM_STRUCTURE_CHANGED: "danger",
  CURRICULUM_ARCHIVED: "warning",
  CURRICULUM_IMPORTED: "success",
  CURRICULUM_TYPE_MAPPED: "warning",
  BULK_IMPORT_EXECUTED: "brand",
  RULE_CREATED: "success",
  RULE_UPDATED: "info",
  RULE_DELETED: "danger",
  USER_CREATED: "success",
  USER_UPDATED: "info",
  SETTINGS_UPDATED: "warning",
  SIGN_IN: "neutral",
  SIGN_OUT: "neutral",
};

function humanizeAction(action: string): string {
  return action
    .toLowerCase()
    .replaceAll("_", " ")
    .replace(/^./, (c) => c.toUpperCase());
}

function summarizeJson(json: string | null): string | null {
  if (!json) return null;
  try {
    const parsed = JSON.parse(json) as Record<string, unknown>;
    const entries = Object.entries(parsed)
      .filter(([, value]) => value !== null && value !== undefined && value !== "")
      .slice(0, 6)
      .map(([key, value]) => {
        const text = typeof value === "object" ? JSON.stringify(value) : String(value);
        return `${key}: ${text.length > 60 ? `${text.slice(0, 60)}…` : text}`;
      });
    return entries.length > 0 ? entries.join(" · ") : null;
  } catch {
    return null;
  }
}

export function AuditTable({
  entries,
  showEntity = true,
  emptyTitle = "No audit entries yet",
  emptyDescription,
}: {
  entries: AuditLog[];
  showEntity?: boolean;
  emptyTitle?: string;
  emptyDescription?: string;
}) {
  if (entries.length === 0) {
    return <EmptyState title={emptyTitle} description={emptyDescription} />;
  }

  return (
    <TableShell>
      <thead>
        <tr>
          <Th className="w-44">When</Th>
          <Th className="w-48">Action</Th>
          <Th className="w-48">Actor</Th>
          {showEntity ? <Th className="w-40">Entity</Th> : null}
          <Th>Change</Th>
        </tr>
      </thead>
      <tbody>
        {entries.map((entry) => {
          const before = summarizeJson(entry.before_json);
          const after = summarizeJson(entry.after_json);
          return (
            <tr key={entry.id} className="align-top hover:bg-ink-50">
              <Td className="whitespace-nowrap text-[12px] text-ink-500">{formatDateTime(entry.created_at)}</Td>
              <Td>
                <Badge tone={ACTION_TONES[entry.action] ?? "neutral"}>{humanizeAction(entry.action)}</Badge>
              </Td>
              <Td className="text-[12px] text-ink-600">{entry.actor_email ?? "system"}</Td>
              {showEntity ? (
                <Td className="text-[12px] text-ink-500">{entry.entity_type.replaceAll("_", " ")}</Td>
              ) : null}
              <Td className="text-[12px] leading-relaxed">
                {entry.reason ? (
                  <p className="mb-1 text-ink-700">
                    <span className="font-medium">Reason:</span> {entry.reason}
                  </p>
                ) : null}
                {before ? (
                  <p className="text-ink-500">
                    <span className="font-medium text-ink-600">From</span> {before}
                  </p>
                ) : null}
                {after ? (
                  <p className="text-ink-700">
                    <span className="font-medium">To</span> {after}
                  </p>
                ) : null}
                {!before && !after && !entry.reason ? <span className="text-ink-400">—</span> : null}
              </Td>
            </tr>
          );
        })}
      </tbody>
    </TableShell>
  );
}
