'use client';

import { useState } from 'react';
import { Activity, ChevronDown, Clock, Eye, Pencil, Plus, Trash2, User } from 'lucide-react';
import { formatDistanceToNow } from 'date-fns';

import { ListCard, ListCardAvatar, ListCardMeta } from '@/components/shared/list-card';
import { cn } from '@/lib/utils';

interface AuditEntry {
  id: string;
  userId: string | null;
  action: string;
  entityType: string;
  entityId: string | null;
  fieldChanged: string | null;
  oldValue: Record<string, unknown> | null;
  newValue: Record<string, unknown> | null;
  metadata: Record<string, unknown> | null;
  ipAddress: string | null;
  userAgent?: string | null;
  severity?: 'info' | 'warning' | 'error' | 'critical';
  source?: 'user' | 'system' | 'auth' | 'webhook' | 'cron' | 'job';
  createdAt: string;
  actor: { id: string; email: string; name: string } | null;
}

const ACTION_ACCENT: Record<string, string> = {
  create: 'bg-emerald-400',
  update: 'bg-blue-400',
  delete: 'bg-rose-400',
  viewed: 'bg-slate-300',
};

const ACTION_BADGE_COLORS: Record<string, string> = {
  create: 'bg-green-600',
  update: 'bg-blue-500',
  delete: 'bg-red-600',
  archive: 'bg-orange-500',
  restore: 'bg-teal-500',
  login: 'bg-gray-500',
  permission_denied: 'bg-red-800',
  merge: 'bg-purple-500',
  revert: 'bg-amber-500',
};

function ActionIcon({ action }: { action: string }) {
  if (action === 'create') return <Plus className="h-5 w-5" aria-hidden />;
  if (action === 'update') return <Pencil className="h-5 w-5" aria-hidden />;
  if (action === 'delete') return <Trash2 className="h-5 w-5" aria-hidden />;
  if (action === 'viewed') return <Eye className="h-5 w-5" aria-hidden />;
  return <Activity className="h-5 w-5" aria-hidden />;
}

function actionVerb(action: string): string {
  const map: Record<string, string> = {
    create: 'Created',
    update: 'Updated',
    delete: 'Deleted',
    archive: 'Archived',
    restore: 'Restored',
    login: 'Logged in',
    permission_denied: 'Permission denied',
    merge: 'Merged',
    revert: 'Reverted',
    viewed: 'Viewed',
    eoi_field_override: 'EOI field override',
    promote_to_primary: 'Contact promoted',
    eoi_spawn_yacht: 'EOI spawn yacht',
  };
  return map[action] ?? action.charAt(0).toUpperCase() + action.slice(1);
}

interface AuditLogCardProps {
  entry: AuditEntry;
}

export function AuditLogCard({ entry }: AuditLogCardProps) {
  const [expanded, setExpanded] = useState(false);
  const accentClass = ACTION_ACCENT[entry.action] ?? 'bg-slate-300';
  const badgeColor = ACTION_BADGE_COLORS[entry.action] ?? 'bg-gray-500';
  const hasDetail =
    Boolean(entry.oldValue) ||
    Boolean(entry.newValue) ||
    Boolean(entry.metadata) ||
    Boolean(entry.userAgent);

  const entityTitle = `${entry.entityType.charAt(0).toUpperCase()}${entry.entityType.slice(1)}${
    entry.entityId ? ` ${entry.entityId.slice(0, 8)}…` : ''
  }`;

  const actorName = entry.actor?.name ?? (entry.userId ? `${entry.userId.slice(0, 8)}…` : 'system');

  // Changed-fields chip line: prefer fieldChanged (single field), then newValue keys
  let changedFields: string[] = [];
  if (entry.fieldChanged) {
    changedFields = [entry.fieldChanged];
  } else if (entry.newValue) {
    changedFields = Object.keys(entry.newValue);
  }
  const visibleFields = changedFields.slice(0, 3);
  const overflowCount = changedFields.length - visibleFields.length;

  return (
    <ListCard
      ariaLabel={`Audit: ${actionVerb(entry.action)} ${entityTitle}`}
      accentClassName={accentClass}
    >
      <div className="flex items-start gap-3">
        <ListCardAvatar icon={<ActionIcon action={entry.action} />} />
        <div className="min-w-0 flex-1">
          {/* Title: entity type + short ID */}
          <h3 className="truncate text-base font-semibold tracking-tight text-foreground">
            {entityTitle}
          </h3>

          {/* Subtitle: action verb + actor */}
          <p className="mt-0.5 inline-flex items-center gap-1 truncate text-sm text-muted-foreground">
            <User className="h-3.5 w-3.5 shrink-0 text-muted-foreground/70" aria-hidden />
            <span className="truncate">
              {actionVerb(entry.action)} by {actorName}
            </span>
          </p>

          {/* Timestamp + IP meta line */}
          <div className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs text-muted-foreground">
            <ListCardMeta icon={<Clock className="h-3 w-3" aria-hidden />}>
              {formatDistanceToNow(new Date(entry.createdAt), { addSuffix: true })}
            </ListCardMeta>
            {entry.ipAddress ? <span className="font-mono text-xs">{entry.ipAddress}</span> : null}
            {entry.severity && entry.severity !== 'info' ? (
              <span className="uppercase font-semibold tracking-wide text-xs">
                {entry.severity}
              </span>
            ) : null}
          </div>

          {/* Action badge + changed-fields chips */}
          <div className="mt-1.5 flex flex-wrap items-center gap-x-2 gap-y-1">
            <span
              className={cn(
                'inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium text-white',
                badgeColor,
              )}
            >
              {entry.action}
            </span>

            {visibleFields.length > 0 ? (
              <>
                {visibleFields.map((field) => (
                  <span
                    key={field}
                    className="inline-flex items-center rounded-full bg-secondary px-2 py-0.5 text-xs text-secondary-foreground"
                  >
                    {field}
                  </span>
                ))}
                {overflowCount > 0 ? (
                  <span className="text-xs text-muted-foreground">+{overflowCount}</span>
                ) : null}
              </>
            ) : null}

            {hasDetail ? (
              <button
                type="button"
                onClick={() => setExpanded((v) => !v)}
                className="ml-auto inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs text-muted-foreground hover:bg-muted hover:text-foreground"
                aria-expanded={expanded}
              >
                <ChevronDown
                  className={cn(
                    'h-3 w-3 transition-transform',
                    expanded ? 'rotate-180' : 'rotate-0',
                  )}
                  aria-hidden
                />
                {expanded ? 'Hide details' : 'Show details'}
              </button>
            ) : null}
          </div>

          {expanded && hasDetail ? (
            <div className="mt-3 space-y-2 rounded-md border bg-muted/30 p-3 text-xs">
              {entry.oldValue ? (
                <details>
                  <summary className="cursor-pointer font-semibold text-muted-foreground">
                    Old value
                  </summary>
                  <pre className="mt-1 max-h-64 overflow-auto rounded bg-background p-2 font-mono text-xs">
                    {JSON.stringify(entry.oldValue, null, 2)}
                  </pre>
                </details>
              ) : null}
              {entry.newValue ? (
                <details open>
                  <summary className="cursor-pointer font-semibold text-muted-foreground">
                    New value
                  </summary>
                  <pre className="mt-1 max-h-64 overflow-auto rounded bg-background p-2 font-mono text-xs">
                    {JSON.stringify(entry.newValue, null, 2)}
                  </pre>
                </details>
              ) : null}
              {entry.metadata ? (
                <details>
                  <summary className="cursor-pointer font-semibold text-muted-foreground">
                    Metadata
                  </summary>
                  <pre className="mt-1 max-h-64 overflow-auto rounded bg-background p-2 font-mono text-xs">
                    {JSON.stringify(entry.metadata, null, 2)}
                  </pre>
                </details>
              ) : null}
              {entry.userAgent || entry.ipAddress ? (
                <dl className="grid grid-cols-[120px_1fr] gap-x-2 gap-y-0.5">
                  {entry.ipAddress ? (
                    <>
                      <dt className="font-semibold text-muted-foreground">IP address</dt>
                      <dd className="font-mono">{entry.ipAddress}</dd>
                    </>
                  ) : null}
                  {entry.userAgent ? (
                    <>
                      <dt className="font-semibold text-muted-foreground">User agent</dt>
                      <dd className="truncate font-mono" title={entry.userAgent}>
                        {entry.userAgent}
                      </dd>
                    </>
                  ) : null}
                </dl>
              ) : null}
            </div>
          ) : null}
        </div>
      </div>
    </ListCard>
  );
}
