'use client';
import { FunctionComponent, KeyboardEvent, useState } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { Box, Chip, Collapse, Paper, Stack, Table, TableBody, TableCell, TableHead, TableRow, Typography } from '@mui/material';
import { formatShamsiDateTime } from '@/utils';
import type { AdminUserSummary, AuditLogEntry } from '@/services/admin/types';
import AppIcon from '../common/AppIcon';

export interface AuditLogRowProps {
  entry: AuditLogEntry;
  /** Resolved actor name (3.2's batch id→label lookup) — falls back to `#id` until the REQ-061 lookup resolves. */
  actorLabel?: string;
}

/** Stringify a diff value (JSON for objects, `—` for null). */
function displayValue(v: unknown): string {
  if (v == null) return '—';
  if (typeof v === 'object') return JSON.stringify(v);
  return String(v);
}

/** The actor cell's display text — the resolved name when known, else the honest `#id` fallback. */
export function actorDisplay(actorUserId: number | null, actorLabel?: string): string {
  if (actorUserId == null) return '—';
  return actorLabel ?? `#${actorUserId}`;
}

/** Resolve a batch `lookupUsers` result into the label `AuditLogRow`/`actorDisplay` expects. */
export function actorLabelFrom(userMap: Map<number, AdminUserSummary> | undefined, userId: number | null): string | undefined {
  if (userId == null) return undefined;
  return userMap?.get(userId)?.displayName;
}

/**
 * One row of the append-only audit viewer, with an expandable `changedFields` diff (old → new per field;
 * PII is server-redacted as `<redacted>`). Read-only by design — there is **no** edit/delete affordance
 * (phase §5). Presentational; the caller passes the paged entries + (once resolved) the actor's name. The
 * expand chevron rotates and the header carries `aria-expanded` + button semantics so open/closed state is
 * visible and keyboard-toggleable (ui-phase-11).
 * @component AuditLogRow
 */
const AuditLogRow: FunctionComponent<AuditLogRowProps> = ({ entry, actorLabel }) => {
  const t = useTranslations('admin');
  const locale = useLocale();
  const [open, setOpen] = useState(false);
  const fields = entry.changedFields ? Object.entries(entry.changedFields) : [];
  const hasDetail = fields.length > 0;

  const toggle = () => setOpen((v) => !v);
  const onKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      toggle();
    }
  };

  return (
    <Paper
      elevation={0}
      data-audit-id={entry.id}
      sx={{ border: '1px solid', borderColor: 'divider', borderRadius: 'var(--bal-radius-md)', overflow: 'hidden' }}
    >
      <Stack
        role={hasDetail ? 'button' : undefined}
        tabIndex={hasDetail ? 0 : undefined}
        aria-expanded={hasDetail ? open : undefined}
        direction="row"
        sx={{ gap: 2, alignItems: 'center', p: 1.5, cursor: hasDetail ? 'pointer' : 'default', flexWrap: 'wrap' }}
        onClick={hasDetail ? toggle : undefined}
        onKeyDown={hasDetail ? onKeyDown : undefined}
      >
        <Chip size="small" variant="outlined" label={`${entry.entityType} #${entry.entityId}`} />
        <Typography variant="body2" sx={{ fontWeight: 700 }}>
          {entry.action}
        </Typography>
        <Typography variant="body2" sx={{ color: 'text.secondary', flexGrow: 1 }}>
          {actorDisplay(entry.actorUserId, actorLabel)}
        </Typography>
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          {formatShamsiDateTime(entry.occurredAt, locale)}
        </Typography>
        {hasDetail ? (
          <AppIcon
            icon="expand"
            size={18}
            color="var(--bal-text-secondary)"
            style={{ transition: 'transform var(--bal-motion-fast) var(--bal-easing-standard)', transform: open ? 'rotate(180deg)' : 'none' }}
          />
        ) : null}
      </Stack>

      <Collapse in={open && hasDetail}>
        <Box sx={{ px: 1.5, pb: 1.5 }}>
          <Typography variant="caption" sx={{ color: 'text.secondary', fontWeight: 700 }}>
            {t('audit_diff_title')}
          </Typography>
          <Table size="small" sx={{ mt: 0.5 }}>
            <TableHead>
              <TableRow>
                <TableCell sx={{ color: 'text.secondary' }}>{t('audit_diff_field')}</TableCell>
                <TableCell sx={{ color: 'text.secondary' }}>{t('audit_diff_old')}</TableCell>
                <TableCell sx={{ color: 'text.secondary' }}>{t('audit_diff_new')}</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {fields.map(([field, delta]) => (
                <TableRow key={field}>
                  <TableCell sx={{ fontWeight: 500 }}>{field}</TableCell>
                  <TableCell sx={{ color: 'text.secondary' }}>{displayValue(delta.old)}</TableCell>
                  <TableCell>{displayValue(delta.new)}</TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </Box>
      </Collapse>
    </Paper>
  );
};

export default AuditLogRow;
