<script lang="ts" setup>
import { router } from '@inertiajs/vue3'
import { computed, ref, watch } from 'vue'
import AdminLayout from '@/Layouts/AdminLayout.vue'
import type { PaginatedResponse } from '@/types'

interface AuditLogUser {
  id: number
  name: string
  email: string
}

interface AuditLog {
  id: number
  user_id: number | null
  admin_id: number | null
  action: string
  resource_type: string | null
  resource_id: number | null
  ip_address: string | null
  user_agent: string | null
  changes: Record<string, unknown> | null
  created_at: string
  user: AuditLogUser | null
}

interface Filters {
  search: string
  action: string
  date_from: string
  date_to: string
}

interface Props {
  auditLogs: PaginatedResponse<AuditLog>
  actions: string[]
  filters: Filters
}

defineOptions({ layout: AdminLayout })

const props = defineProps<Props>()

const search = ref<string>(props.filters.search)
const actionFilter = ref<string>(props.filters.action)
const dateFrom = ref<string>(props.filters.date_from)
const dateTo = ref<string>(props.filters.date_to)
const expandedRows = ref<Set<number>>(new Set())

// Detail dialog state
const detailDialog = ref<boolean>(false)
const selectedLog = ref<AuditLog | null>(null)

// Export menu state
const exportMenu = ref<boolean>(false)

let searchTimeout: ReturnType<typeof setTimeout> | null = null

watch(search, (value: string) => {
  if (searchTimeout) {
    clearTimeout(searchTimeout)
  }
  searchTimeout = setTimeout(() => {
    applyFilters({ search: value })
  }, 400)
})

watch(actionFilter, (value: string) => {
  applyFilters({ action: value })
})

watch(dateFrom, (value: string) => {
  applyFilters({ date_from: value })
})

watch(dateTo, (value: string) => {
  applyFilters({ date_to: value })
})

function applyFilters(overrides: Partial<Filters> = {}): void {
  router.get('/audit-logs', {
    search: overrides.search ?? search.value,
    action: overrides.action ?? actionFilter.value,
    date_from: overrides.date_from ?? dateFrom.value,
    date_to: overrides.date_to ?? dateTo.value,
  }, {
    preserveState: true,
    replace: true,
  })
}

function toggleRow(id: number): void {
  if (expandedRows.value.has(id)) {
    expandedRows.value.delete(id)
  }
  else {
    expandedRows.value.add(id)
  }
}

function isExpanded(id: number): boolean {
  return expandedRows.value.has(id)
}

function openDetailDialog(log: AuditLog): void {
  selectedLog.value = log
  detailDialog.value = true
}

function closeDetailDialog(): void {
  detailDialog.value = false
  selectedLog.value = null
}

function resolveActionColor(action: string): string {
  if (action.startsWith('create') || action === 'register') {
    return 'success'
  }
  if (action.startsWith('update') || action.startsWith('edit')) {
    return 'info'
  }
  if (action.startsWith('delete') || action.startsWith('terminate') || action.startsWith('destroy')) {
    return 'error'
  }
  if (action.startsWith('login') || action === 'login') {
    return 'primary'
  }
  if (action.startsWith('suspend') || action.startsWith('unsuspend')) {
    return 'warning'
  }
  return 'secondary'
}

function resolveActionIcon(action: string): string {
  if (action.startsWith('create') || action === 'register') {
    return 'tabler-plus'
  }
  if (action.startsWith('update') || action.startsWith('edit')) {
    return 'tabler-pencil'
  }
  if (action.startsWith('delete') || action.startsWith('terminate') || action.startsWith('destroy')) {
    return 'tabler-trash'
  }
  if (action.startsWith('login') || action === 'login') {
    return 'tabler-login'
  }
  if (action.startsWith('suspend')) {
    return 'tabler-ban'
  }
  if (action.startsWith('unsuspend')) {
    return 'tabler-circle-check'
  }
  return 'tabler-activity'
}

function formatAction(action: string): string {
  return action
    .replace(/_/g, ' ')
    .replace(/\b\w/g, (c: string) => c.toUpperCase())
}

function formatResourceType(type: string | null): string {
  if (!type) {
    return '-'
  }
  return type
    .replace(/_/g, ' ')
    .replace(/\b\w/g, (c: string) => c.toUpperCase())
}

function formatDateTime(dateStr: string): string {
  const date = new Date(dateStr)
  return date.toLocaleDateString('en-US', {
    month: 'short',
    day: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  })
}

function formatFieldName(field: string): string {
  return field
    .replace(/_/g, ' ')
    .replace(/\b\w/g, (c: string) => c.toUpperCase())
}

function formatValue(value: unknown): string {
  if (value === null || value === undefined) {
    return '(empty)'
  }
  if (typeof value === 'boolean') {
    return value ? 'Yes' : 'No'
  }
  if (typeof value === 'object') {
    return JSON.stringify(value, null, 2)
  }
  return String(value)
}

function hasChanges(log: AuditLog): boolean {
  return log.changes !== null && Object.keys(log.changes).length > 0
}

interface ChangesDiff {
  type: 'update' | 'create' | 'delete' | 'generic'
  before: Record<string, unknown> | null
  after: Record<string, unknown> | null
  fields: string[]
}

/**
 * Check if a value looks like an {old, new} pair used for per-field diffs.
 */
function isOldNewPair(value: unknown): value is { old: unknown, new: unknown } {
  return (
    typeof value === 'object'
    && value !== null
    && !Array.isArray(value)
    && ('old' in value || 'new' in value)
  )
}

/**
 * Detect per-field old/new format: {"plan": {"old": "Basic", "new": "Pro"}, "status": {"old": "active", "new": "suspended"}}
 * Returns true if at least one top-level value is an {old, new} pair.
 */
function isPerFieldOldNewFormat(changes: Record<string, unknown>): boolean {
  const values = Object.values(changes)
  return values.length > 0 && values.some(v => isOldNewPair(v))
}

/**
 * Parse the changes JSON into a normalized diff structure.
 *
 * Supports multiple formats found in the codebase:
 * 1. Per-field old/new: {"plan": {"old": "Basic", "new": "Pro"}, "status": {"old": "active", "new": "suspended"}}
 * 2. Top-level old/new: {"old": {"status": "active"}, "new": {"status": "suspended"}}
 * 3. Top-level before/after: {"before": {...}, "after": {...}}
 * 4. Flat key-value pairs: {"old_status": "active", "new_status": "suspended"} or {"name": "John", "email": "..."}
 */
function parseChanges(changes: Record<string, unknown> | null): ChangesDiff {
  if (!changes || Object.keys(changes).length === 0) {
    return { type: 'generic', before: null, after: null, fields: [] }
  }

  // Format 1: Per-field old/new — {"plan": {"old": "Basic", "new": "Pro"}, ...}
  if (isPerFieldOldNewFormat(changes)) {
    const before: Record<string, unknown> = {}
    const after: Record<string, unknown> = {}
    const fields: string[] = []

    for (const [field, value] of Object.entries(changes)) {
      if (isOldNewPair(value)) {
        fields.push(field)
        before[field] = value.old
        after[field] = value.new
      }
      else {
        // Non old/new field mixed in — treat as unchanged context
        fields.push(field)
        before[field] = value
        after[field] = value
      }
    }

    return { type: 'update', before, after, fields }
  }

  // Format 2: Top-level old/new — {"old": {...}, "new": {...}}
  const hasOld = 'old' in changes && changes.old !== null && typeof changes.old === 'object'
  const hasNew = 'new' in changes && changes.new !== null && typeof changes.new === 'object'

  if (hasOld || hasNew) {
    const before = hasOld ? (changes.old as Record<string, unknown>) : null
    const after = hasNew ? (changes.new as Record<string, unknown>) : null
    const fieldSet = new Set<string>([
      ...(before ? Object.keys(before) : []),
      ...(after ? Object.keys(after) : []),
    ])
    const fields = [...fieldSet]

    if (hasOld && hasNew) {
      return { type: 'update', before, after, fields }
    }
    if (hasNew && !hasOld) {
      return { type: 'create', before: null, after, fields }
    }
    if (hasOld && !hasNew) {
      return { type: 'delete', before, after: null, fields }
    }
  }

  // Format 3: Top-level before/after — {"before": {...}, "after": {...}}
  const hasBefore = 'before' in changes && changes.before !== null && typeof changes.before === 'object'
  const hasAfter = 'after' in changes && changes.after !== null && typeof changes.after === 'object'

  if (hasBefore || hasAfter) {
    const before = hasBefore ? (changes.before as Record<string, unknown>) : null
    const after = hasAfter ? (changes.after as Record<string, unknown>) : null
    const fieldSet = new Set<string>([
      ...(before ? Object.keys(before) : []),
      ...(after ? Object.keys(after) : []),
    ])
    const fields = [...fieldSet]

    if (hasBefore && hasAfter) {
      return { type: 'update', before, after, fields }
    }
    if (hasAfter && !hasBefore) {
      return { type: 'create', before: null, after, fields }
    }
    if (hasBefore && !hasAfter) {
      return { type: 'delete', before, after: null, fields }
    }
  }

  // Format 4: Flat key-value pairs — treat as generic data display
  return { type: 'generic', before: null, after: changes, fields: Object.keys(changes) }
}

function isFieldChanged(before: Record<string, unknown> | null, after: Record<string, unknown> | null, field: string): boolean {
  if (!before || !after) {
    return false
  }
  return JSON.stringify(before[field]) !== JSON.stringify(after[field])
}

function countChangedFields(log: AuditLog): number {
  const diff = parseChanges(log.changes)
  if (diff.type === 'generic') {
    return diff.fields.length
  }
  if (diff.type === 'create' || diff.type === 'delete') {
    return diff.fields.length
  }
  // For updates, count only fields that actually changed
  return diff.fields.filter(f => isFieldChanged(diff.before, diff.after, f)).length
}

function clearFilters(): void {
  search.value = ''
  actionFilter.value = ''
  dateFrom.value = ''
  dateTo.value = ''
  applyFilters({ search: '', action: '', date_from: '', date_to: '' })
}

const hasActiveFilters = computed<boolean>(() => {
  return search.value !== '' || actionFilter.value !== '' || dateFrom.value !== '' || dateTo.value !== ''
})

function buildExportUrl(format: 'csv' | 'json'): string {
  const params = new URLSearchParams()
  params.set('format', format)
  if (search.value) {
    params.set('search', search.value)
  }
  if (actionFilter.value) {
    params.set('action', actionFilter.value)
  }
  if (dateFrom.value) {
    params.set('date_from', dateFrom.value)
  }
  if (dateTo.value) {
    params.set('date_to', dateTo.value)
  }
  return `/audit-logs/export?${params.toString()}`
}

function exportData(format: 'csv' | 'json'): void {
  exportMenu.value = false
  window.location.href = buildExportUrl(format)
}
</script>

<template>
  <div>
    <!-- Page Header -->
    <div class="d-flex align-center justify-space-between mb-6">
      <div>
        <div class="text-h4 font-weight-bold">
          Audit Logs
        </div>
        <div class="text-body-2 text-medium-emphasis">
          Track all system activity and administrative actions
        </div>
      </div>
      <div class="d-flex align-center gap-3">
        <!-- Export Dropdown -->
        <VMenu v-model="exportMenu" location="bottom end">
          <template #activator="{ props: menuProps }">
            <VBtn
              v-bind="menuProps"
              variant="outlined"
              color="primary"
              size="small"
              prepend-icon="tabler-download"
            >
              Export
              <VIcon icon="tabler-chevron-down" end size="14" />
            </VBtn>
          </template>
          <VList density="compact" min-width="160">
            <VListItem @click="exportData('csv')">
              <template #prepend>
                <VIcon icon="tabler-file-spreadsheet" size="18" />
              </template>
              <VListItemTitle>Export as CSV</VListItemTitle>
            </VListItem>
            <VListItem @click="exportData('json')">
              <template #prepend>
                <VIcon icon="tabler-file-code" size="18" />
              </template>
              <VListItemTitle>Export as JSON</VListItemTitle>
            </VListItem>
          </VList>
        </VMenu>

        <VChip color="primary" variant="tonal" size="small">
          {{ auditLogs.total }} entries
        </VChip>
      </div>
    </div>

    <!-- Filters -->
    <VCard class="mb-6">
      <VCardText>
        <VRow>
          <VCol cols="12" md="4">
            <VTextField
              v-model="search"
              prepend-inner-icon="tabler-search"
              placeholder="Search by user, action, IP..."
              variant="outlined"
              density="compact"
              clearable
              hide-details
            />
          </VCol>
          <VCol cols="12" md="2">
            <VSelect
              v-model="actionFilter"
              :items="[{ title: 'All Actions', value: '' }, ...actions.map(a => ({ title: formatAction(a), value: a }))]"
              variant="outlined"
              density="compact"
              hide-details
            />
          </VCol>
          <VCol cols="12" md="2">
            <VTextField
              v-model="dateFrom"
              type="date"
              label="From"
              variant="outlined"
              density="compact"
              hide-details
            />
          </VCol>
          <VCol cols="12" md="2">
            <VTextField
              v-model="dateTo"
              type="date"
              label="To"
              variant="outlined"
              density="compact"
              hide-details
            />
          </VCol>
          <VCol cols="12" md="2" class="d-flex align-center">
            <VBtn
              v-if="hasActiveFilters"
              variant="text"
              color="secondary"
              size="small"
              @click="clearFilters"
            >
              <VIcon icon="tabler-x" start />
              Clear
            </VBtn>
          </VCol>
        </VRow>
      </VCardText>
    </VCard>

    <!-- Audit Logs Table -->
    <VCard>
      <VCardText v-if="auditLogs.data.length === 0" class="text-center py-12">
        <VIcon icon="tabler-clipboard-off" size="48" color="disabled" class="mb-2" />
        <div class="text-medium-emphasis">
          No audit log entries found.
        </div>
      </VCardText>

      <VTable v-else density="comfortable" hover>
        <thead>
          <tr>
            <th style="width: 40px;" />
            <th>Timestamp</th>
            <th>User</th>
            <th>Action</th>
            <th>Resource Type</th>
            <th>Resource ID</th>
            <th>IP Address</th>
            <th style="width: 40px;" />
          </tr>
        </thead>
        <tbody>
          <template v-for="log in auditLogs.data" :key="log.id">
            <tr
              :class="{ 'cursor-pointer': hasChanges(log) }"
              @click="hasChanges(log) ? toggleRow(log.id) : undefined"
            >
              <td>
                <VBadge
                  v-if="hasChanges(log)"
                  :content="countChangedFields(log)"
                  color="primary"
                  :offset-x="-2"
                  :offset-y="-2"
                >
                  <VBtn
                    variant="text"
                    size="x-small"
                    :icon="isExpanded(log.id) ? 'tabler-chevron-down' : 'tabler-chevron-right'"
                    @click.stop="toggleRow(log.id)"
                  />
                </VBadge>
              </td>
              <td class="text-body-2">
                {{ formatDateTime(log.created_at) }}
              </td>
              <td>
                <div v-if="log.user" class="d-flex align-center gap-2">
                  <VAvatar color="primary" variant="tonal" size="30">
                    <span class="text-caption font-weight-medium">
                      {{ log.user.name.charAt(0).toUpperCase() }}
                    </span>
                  </VAvatar>
                  <div>
                    <div class="text-body-2 font-weight-medium">
                      {{ log.user.name }}
                    </div>
                    <div class="text-caption text-medium-emphasis">
                      {{ log.user.email }}
                    </div>
                  </div>
                </div>
                <VChip v-else size="small" variant="tonal" color="secondary">
                  System
                </VChip>
              </td>
              <td>
                <VChip
                  :color="resolveActionColor(log.action)"
                  size="small"
                  variant="tonal"
                >
                  <VIcon :icon="resolveActionIcon(log.action)" start size="14" />
                  {{ formatAction(log.action) }}
                </VChip>
              </td>
              <td class="text-body-2">
                {{ formatResourceType(log.resource_type) }}
              </td>
              <td class="text-body-2">
                {{ log.resource_id ?? '-' }}
              </td>
              <td class="text-body-2 text-medium-emphasis">
                {{ log.ip_address ?? '-' }}
              </td>
              <td>
                <VBtn
                  v-if="hasChanges(log)"
                  variant="text"
                  size="x-small"
                  icon="tabler-eye"
                  color="primary"
                  @click.stop="openDetailDialog(log)"
                />
              </td>
            </tr>
            <!-- Expanded row: inline diff preview -->
            <tr v-if="isExpanded(log.id) && hasChanges(log)">
              <td colspan="8" class="pa-0">
                <div class="pa-4 bg-surface-variant">
                  <div class="d-flex align-center justify-space-between mb-3">
                    <div class="text-caption font-weight-semibold">
                      Changes
                    </div>
                    <VBtn
                      variant="text"
                      size="x-small"
                      color="primary"
                      @click.stop="openDetailDialog(log)"
                    >
                      <VIcon icon="tabler-arrows-maximize" start size="14" />
                      View Full Diff
                    </VBtn>
                  </div>

                  <!-- Inline diff for before/after -->
                  <template v-if="parseChanges(log.changes).type === 'update'">
                    <VTable density="compact" class="rounded border">
                      <thead>
                        <tr>
                          <th class="text-caption" style="width: 25%;">
                            Field
                          </th>
                          <th class="text-caption" style="width: 37.5%;">
                            Before
                          </th>
                          <th class="text-caption" style="width: 37.5%;">
                            After
                          </th>
                        </tr>
                      </thead>
                      <tbody>
                        <tr
                          v-for="field in parseChanges(log.changes).fields"
                          :key="field"
                          :class="{ 'bg-warning-lighten-5': isFieldChanged(parseChanges(log.changes).before, parseChanges(log.changes).after, field) }"
                        >
                          <td class="text-caption font-weight-medium">
                            {{ formatFieldName(field) }}
                          </td>
                          <td class="text-caption">
                            <span :class="{ 'text-error text-decoration-line-through': isFieldChanged(parseChanges(log.changes).before, parseChanges(log.changes).after, field) }">
                              {{ formatValue(parseChanges(log.changes).before?.[field]) }}
                            </span>
                          </td>
                          <td class="text-caption">
                            <span :class="{ 'text-success font-weight-medium': isFieldChanged(parseChanges(log.changes).before, parseChanges(log.changes).after, field) }">
                              {{ formatValue(parseChanges(log.changes).after?.[field]) }}
                            </span>
                          </td>
                        </tr>
                      </tbody>
                    </VTable>
                  </template>

                  <!-- Create: show new values only -->
                  <template v-else-if="parseChanges(log.changes).type === 'create'">
                    <VChip size="x-small" color="success" variant="tonal" class="mb-2">
                      New Values
                    </VChip>
                    <VTable density="compact" class="rounded border">
                      <thead>
                        <tr>
                          <th class="text-caption" style="width: 30%;">
                            Field
                          </th>
                          <th class="text-caption">
                            Value
                          </th>
                        </tr>
                      </thead>
                      <tbody>
                        <tr v-for="field in parseChanges(log.changes).fields" :key="field">
                          <td class="text-caption font-weight-medium">
                            {{ formatFieldName(field) }}
                          </td>
                          <td class="text-caption text-success">
                            {{ formatValue(parseChanges(log.changes).after?.[field]) }}
                          </td>
                        </tr>
                      </tbody>
                    </VTable>
                  </template>

                  <!-- Delete: show deleted values only -->
                  <template v-else-if="parseChanges(log.changes).type === 'delete'">
                    <VChip size="x-small" color="error" variant="tonal" class="mb-2">
                      Deleted Values
                    </VChip>
                    <VTable density="compact" class="rounded border">
                      <thead>
                        <tr>
                          <th class="text-caption" style="width: 30%;">
                            Field
                          </th>
                          <th class="text-caption">
                            Value
                          </th>
                        </tr>
                      </thead>
                      <tbody>
                        <tr v-for="field in parseChanges(log.changes).fields" :key="field">
                          <td class="text-caption font-weight-medium">
                            {{ formatFieldName(field) }}
                          </td>
                          <td class="text-caption text-error text-decoration-line-through">
                            {{ formatValue(parseChanges(log.changes).before?.[field]) }}
                          </td>
                        </tr>
                      </tbody>
                    </VTable>
                  </template>

                  <!-- Generic: flat key-value data -->
                  <template v-else>
                    <VChip size="x-small" color="secondary" variant="tonal" class="mb-2">
                      Data
                    </VChip>
                    <VTable density="compact" class="rounded border">
                      <thead>
                        <tr>
                          <th class="text-caption" style="width: 30%;">
                            Field
                          </th>
                          <th class="text-caption">
                            Value
                          </th>
                        </tr>
                      </thead>
                      <tbody>
                        <tr v-for="field in parseChanges(log.changes).fields" :key="field">
                          <td class="text-caption font-weight-medium">
                            {{ formatFieldName(field) }}
                          </td>
                          <td class="text-caption">
                            {{ formatValue(parseChanges(log.changes).after?.[field] ?? log.changes?.[field]) }}
                          </td>
                        </tr>
                      </tbody>
                    </VTable>
                  </template>
                </div>
              </td>
            </tr>
          </template>
        </tbody>
      </VTable>

      <!-- Pagination -->
      <VCardText v-if="auditLogs.last_page > 1" class="d-flex align-center justify-center pt-4">
        <VPagination
          :model-value="Math.ceil((auditLogs.from || 1) / 25)"
          :length="auditLogs.last_page"
          :total-visible="7"
          rounded
          @update:model-value="(page: number) => router.get('/audit-logs', { search: search, action: actionFilter, date_from: dateFrom, date_to: dateTo, page }, { preserveState: true })"
        />
      </VCardText>
    </VCard>

    <!-- Detail Dialog -->
    <VDialog
      v-model="detailDialog"
      max-width="800"
      scrollable
    >
      <VCard v-if="selectedLog">
        <VCardTitle class="d-flex align-center justify-space-between pa-5">
          <div class="d-flex align-center gap-3">
            <VAvatar :color="resolveActionColor(selectedLog.action)" variant="tonal" size="40">
              <VIcon :icon="resolveActionIcon(selectedLog.action)" size="20" />
            </VAvatar>
            <div>
              <div class="text-h6">
                {{ formatAction(selectedLog.action) }}
              </div>
              <div class="text-caption text-medium-emphasis">
                {{ formatDateTime(selectedLog.created_at) }}
              </div>
            </div>
          </div>
          <VBtn icon="tabler-x" variant="text" size="small" @click="closeDetailDialog" />
        </VCardTitle>

        <VDivider />

        <VCardText class="pa-5">
          <!-- Log Metadata -->
          <VRow class="mb-5">
            <VCol cols="12" sm="6">
              <div class="text-caption text-medium-emphasis mb-1">
                User
              </div>
              <div v-if="selectedLog.user" class="d-flex align-center gap-2">
                <VAvatar color="primary" variant="tonal" size="28">
                  <span class="text-caption font-weight-medium">
                    {{ selectedLog.user.name.charAt(0).toUpperCase() }}
                  </span>
                </VAvatar>
                <div>
                  <div class="text-body-2 font-weight-medium">
                    {{ selectedLog.user.name }}
                  </div>
                  <div class="text-caption text-medium-emphasis">
                    {{ selectedLog.user.email }}
                  </div>
                </div>
              </div>
              <VChip v-else size="small" variant="tonal" color="secondary">
                System
              </VChip>
            </VCol>
            <VCol cols="6" sm="3">
              <div class="text-caption text-medium-emphasis mb-1">
                Resource Type
              </div>
              <div class="text-body-2">
                {{ formatResourceType(selectedLog.resource_type) }}
              </div>
            </VCol>
            <VCol cols="6" sm="3">
              <div class="text-caption text-medium-emphasis mb-1">
                Resource ID
              </div>
              <div class="text-body-2">
                {{ selectedLog.resource_id ?? '-' }}
              </div>
            </VCol>
          </VRow>

          <VRow class="mb-5">
            <VCol cols="12" sm="6">
              <div class="text-caption text-medium-emphasis mb-1">
                IP Address
              </div>
              <div class="text-body-2">
                {{ selectedLog.ip_address ?? '-' }}
              </div>
            </VCol>
            <VCol cols="12" sm="6">
              <div class="text-caption text-medium-emphasis mb-1">
                User Agent
              </div>
              <div class="text-caption" style="word-break: break-all;">
                {{ selectedLog.user_agent ?? '-' }}
              </div>
            </VCol>
          </VRow>

          <VDivider class="mb-5" />

          <!-- Changes Diff View -->
          <div v-if="hasChanges(selectedLog)">
            <div class="text-subtitle-1 font-weight-semibold mb-4">
              State Changes
            </div>

            <!-- Update: before/after diff -->
            <template v-if="parseChanges(selectedLog.changes).type === 'update'">
              <VRow>
                <!-- Before Column -->
                <VCol cols="12" md="6">
                  <VCard variant="outlined" color="error">
                    <VCardTitle class="text-body-1 pa-3 d-flex align-center gap-2">
                      <VIcon icon="tabler-minus" size="16" color="error" />
                      Before
                    </VCardTitle>
                    <VDivider />
                    <VCardText class="pa-0">
                      <VTable density="compact">
                        <tbody>
                          <tr
                            v-for="field in parseChanges(selectedLog.changes).fields"
                            :key="field"
                          >
                            <td class="text-caption font-weight-medium" style="width: 40%;">
                              {{ formatFieldName(field) }}
                            </td>
                            <td class="text-caption">
                              <span
                                :class="{
                                  'text-error text-decoration-line-through': isFieldChanged(parseChanges(selectedLog.changes).before, parseChanges(selectedLog.changes).after, field),
                                }"
                              >
                                {{ formatValue(parseChanges(selectedLog.changes).before?.[field]) }}
                              </span>
                            </td>
                          </tr>
                        </tbody>
                      </VTable>
                    </VCardText>
                  </VCard>
                </VCol>

                <!-- After Column -->
                <VCol cols="12" md="6">
                  <VCard variant="outlined" color="success">
                    <VCardTitle class="text-body-1 pa-3 d-flex align-center gap-2">
                      <VIcon icon="tabler-plus" size="16" color="success" />
                      After
                    </VCardTitle>
                    <VDivider />
                    <VCardText class="pa-0">
                      <VTable density="compact">
                        <tbody>
                          <tr
                            v-for="field in parseChanges(selectedLog.changes).fields"
                            :key="field"
                          >
                            <td class="text-caption font-weight-medium" style="width: 40%;">
                              {{ formatFieldName(field) }}
                            </td>
                            <td class="text-caption">
                              <span
                                :class="{
                                  'text-success font-weight-medium': isFieldChanged(parseChanges(selectedLog.changes).before, parseChanges(selectedLog.changes).after, field),
                                }"
                              >
                                {{ formatValue(parseChanges(selectedLog.changes).after?.[field]) }}
                              </span>
                            </td>
                          </tr>
                        </tbody>
                      </VTable>
                    </VCardText>
                  </VCard>
                </VCol>
              </VRow>

              <!-- Changed fields summary -->
              <VAlert type="info" variant="tonal" density="compact" class="mt-4">
                <div class="text-caption">
                  <strong>Changed fields:</strong>
                  {{ parseChanges(selectedLog.changes).fields.filter(f => isFieldChanged(parseChanges(selectedLog.changes).before, parseChanges(selectedLog.changes).after, f)).join(', ') || 'None' }}
                </div>
              </VAlert>
            </template>

            <!-- Create: new values -->
            <template v-else-if="parseChanges(selectedLog.changes).type === 'create'">
              <VAlert type="success" variant="tonal" density="compact" class="mb-4">
                <div class="text-caption">
                  New record created with the following values:
                </div>
              </VAlert>
              <VCard variant="outlined" color="success">
                <VCardTitle class="text-body-1 pa-3 d-flex align-center gap-2">
                  <VIcon icon="tabler-plus" size="16" color="success" />
                  New Values
                </VCardTitle>
                <VDivider />
                <VCardText class="pa-0">
                  <VTable density="compact">
                    <tbody>
                      <tr
                        v-for="field in parseChanges(selectedLog.changes).fields"
                        :key="field"
                      >
                        <td class="text-caption font-weight-medium" style="width: 40%;">
                          {{ formatFieldName(field) }}
                        </td>
                        <td class="text-caption text-success">
                          {{ formatValue(parseChanges(selectedLog.changes).after?.[field]) }}
                        </td>
                      </tr>
                    </tbody>
                  </VTable>
                </VCardText>
              </VCard>
            </template>

            <!-- Delete: deleted values -->
            <template v-else-if="parseChanges(selectedLog.changes).type === 'delete'">
              <VAlert type="error" variant="tonal" density="compact" class="mb-4">
                <div class="text-caption">
                  Record deleted. Previous values:
                </div>
              </VAlert>
              <VCard variant="outlined" color="error">
                <VCardTitle class="text-body-1 pa-3 d-flex align-center gap-2">
                  <VIcon icon="tabler-minus" size="16" color="error" />
                  Deleted Values
                </VCardTitle>
                <VDivider />
                <VCardText class="pa-0">
                  <VTable density="compact">
                    <tbody>
                      <tr
                        v-for="field in parseChanges(selectedLog.changes).fields"
                        :key="field"
                      >
                        <td class="text-caption font-weight-medium" style="width: 40%;">
                          {{ formatFieldName(field) }}
                        </td>
                        <td class="text-caption text-error text-decoration-line-through">
                          {{ formatValue(parseChanges(selectedLog.changes).before?.[field]) }}
                        </td>
                      </tr>
                    </tbody>
                  </VTable>
                </VCardText>
              </VCard>
            </template>

            <!-- Generic: flat key-value data -->
            <template v-else>
              <VCard variant="outlined">
                <VCardTitle class="text-body-1 pa-3 d-flex align-center gap-2">
                  <VIcon icon="tabler-list-details" size="16" />
                  Recorded Data
                </VCardTitle>
                <VDivider />
                <VCardText class="pa-0">
                  <VTable density="compact">
                    <tbody>
                      <tr
                        v-for="field in parseChanges(selectedLog.changes).fields"
                        :key="field"
                      >
                        <td class="text-caption font-weight-medium" style="width: 40%;">
                          {{ formatFieldName(field) }}
                        </td>
                        <td class="text-caption">
                          {{ formatValue(parseChanges(selectedLog.changes).after?.[field] ?? selectedLog.changes?.[field]) }}
                        </td>
                      </tr>
                    </tbody>
                  </VTable>
                </VCardText>
              </VCard>

              <!-- Also show raw JSON in a collapsible section -->
              <VExpansionPanels class="mt-4" variant="accordion">
                <VExpansionPanel title="Raw JSON">
                  <VExpansionPanelText>
                    <pre class="text-caption rounded pa-3 bg-surface-variant" style="white-space: pre-wrap; word-break: break-all; max-height: 300px; overflow-y: auto;">{{ JSON.stringify(selectedLog.changes, null, 2) }}</pre>
                  </VExpansionPanelText>
                </VExpansionPanel>
              </VExpansionPanels>
            </template>
          </div>

          <!-- No changes -->
          <div v-else class="text-center py-6">
            <VIcon icon="tabler-file-off" size="36" color="disabled" class="mb-2" />
            <div class="text-medium-emphasis text-body-2">
              No change data recorded for this action.
            </div>
          </div>
        </VCardText>

        <VDivider />

        <VCardActions class="pa-4">
          <VSpacer />
          <VBtn variant="tonal" color="secondary" @click="closeDetailDialog">
            Close
          </VBtn>
        </VCardActions>
      </VCard>
    </VDialog>
  </div>
</template>
