<template>
  <div class="page-header">
    <h1>Audit Logs</h1>
  </div>

  <div class="filters">
    <input
      type="text"
      v-model="search"
      placeholder="Search by name or user..."
      @input="debouncedSearch"
    >
    <select v-model="filterAction" @change="loadLogs">
      <option value="">All Actions</option>
      <option value="created">Created</option>
      <option value="updated">Updated</option>
      <option value="deleted">Deleted</option>
    </select>
    <select v-model="filterEntity" @change="loadLogs">
      <option value="">All Entities</option>
      <option v-for="e in entityTypes" :key="e" :value="e">{{ e }}</option>
    </select>
  </div>

  <div class="card">
    <div class="table-container">
      <table>
        <thead>
          <tr>
            <th style="width: 180px">Timestamp</th>
            <th style="width: 90px">Action</th>
            <th style="width: 110px">Entity</th>
            <th>Name/ID</th>
            <th style="width: 118px">User</th>
            <th style="width: 108px">IP Address</th>
            <th style="width: 80px">Changes</th>
          </tr>
        </thead>
        <tbody>
          <tr v-if="loading">
            <td colspan="7" class="loading">Loading...</td>
          </tr>
          <tr v-else-if="!logs.length">
            <td colspan="7" class="empty">No audit logs found</td>
          </tr>
          <tr v-for="log in logs" :key="log.auditlogid">
            <td class="timestamp" :title="formatDateFull(log.timestamp)">{{ formatDate(log.timestamp) }}</td>
            <td>
              <span class="badge" :class="actionClass(log.action)">
                {{ log.action }}
              </span>
            </td>
            <td>{{ log.entitytype }}</td>
            <td class="name-cell" :title="log.entityname || `#${log.entityid}`">
              <router-link
                v-if="getEntityLink(log)"
                :to="getEntityLink(log)"
                class="entity-link"
              >
                {{ log.entityname || `#${log.entityid}` }}
              </router-link>
              <span v-else>{{ log.entityname || `#${log.entityid}` }}</span>
            </td>
            <td :title="log.userfullname || ''">{{ log.username || '-' }}</td>
            <td class="ip">{{ log.ipaddress || '-' }}</td>
            <td>
              <button
                v-if="log.changes && Object.keys(log.changes).length"
                class="changes-btn"
                @click="showChanges(log)"
              >
                {{ Object.keys(log.changes).length }} field(s)
              </button>
              <span v-else class="no-changes">-</span>
            </td>
          </tr>
        </tbody>
      </table>
    </div>

    <div class="pagination" v-if="totalPages > 1">
      <button :disabled="page <= 1" @click="page--; loadLogs()">Prev</button>
      <span>Page {{ page }} of {{ totalPages }}</span>
      <button :disabled="page >= totalPages" @click="page++; loadLogs()">Next</button>
    </div>
  </div>

  <!-- Changes Modal -->
  <div v-if="selectedLog" class="modal-overlay" @click.self="selectedLog = null">
    <div class="modal">
      <div class="modal-header">
        <h3>Changes - {{ selectedLog.entitytype }} {{ selectedLog.entityname }}</h3>
        <button class="close-btn" @click="selectedLog = null">&times;</button>
      </div>
      <div class="modal-body">
        <table class="changes-table">
          <thead>
            <tr>
              <th>Field</th>
              <th>Old Value</th>
              <th>New Value</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(change, field) in selectedLog.changes" :key="field">
              <td>{{ field }}</td>
              <td class="old-value">{{ formatValue(change.old) }}</td>
              <td class="new-value">{{ formatValue(change.new) }}</td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue'
import { auditLogsApi } from '../../api'

const logs = ref([])
const loading = ref(true)
const page = ref(1)
const perpage = 50
const total = ref(0)
const search = ref('')
const filterAction = ref('')
const filterEntity = ref('')
const selectedLog = ref(null)

const entityTypes = ['Asset', 'Printer', 'Computer', 'Machine', 'Network', 'Setting', 'User', 'Application', 'KnowledgeBase']

const totalPages = computed(() => Math.ceil(total.value / perpage))

let debounceTimer = null
function debouncedSearch() {
  clearTimeout(debounceTimer)
  debounceTimer = setTimeout(() => {
    page.value = 1
    loadLogs()
  }, 300)
}

async function loadLogs() {
  loading.value = true
  try {
    const params = {
      page: page.value,
      perpage
    }
    if (search.value) params.search = search.value
    if (filterAction.value) params.action = filterAction.value
    if (filterEntity.value) params.entitytype = filterEntity.value

    const { data } = await auditLogsApi.list(params)
    logs.value = data.data
    total.value = data.meta.total
  } catch (e) {
    console.error('Failed to load audit logs:', e)
  } finally {
    loading.value = false
  }
}

function formatDate(isoString) {
  if (!isoString) return '-'
  const d = new Date(isoString)
  // compact for the fixed-width column; the cell title carries the full form
  return d.toLocaleString(undefined, {
    year: 'numeric', month: 'numeric', day: 'numeric',
    hour: 'numeric', minute: '2-digit'
  })
}

function formatDateFull(isoString) {
  if (!isoString) return ''
  return new Date(isoString).toLocaleString()
}

function actionClass(action) {
  switch (action) {
    case 'created': return 'badge-success'
    case 'updated': return 'badge-warning'
    case 'deleted': return 'badge-danger'
    default: return ''
  }
}

function getEntityLink(log) {
  if (!log.entityid) return null
  const type = log.entitytype?.toLowerCase()
  switch (type) {
    case 'printer': return `/printers/${log.entityid}`
    case 'computer': return `/pcs/${log.entityid}`
    case 'machine': return `/machines/${log.entityid}`
    case 'asset': return `/assets/${log.entityid}`
    case 'application': return `/applications/${log.entityid}`
    case 'knowledgebase': return `/kb/${log.entityid}`
    default: return null
  }
}

function showChanges(log) {
  selectedLog.value = log
}

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

onMounted(loadLogs)
</script>

<style scoped>
.filters {
  display: flex;
  gap: 1rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}

.filters input,
.filters select {
  padding: 0.5rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg-card);
  color: var(--text);
}

.filters input {
  min-width: 250px;
}

.timestamp {
  font-size: 0.85rem;
  color: var(--text-light);
  white-space: nowrap;
}

.ip {
  font-family: monospace;
  font-size: 0.85rem;
}

.badge {
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  font-size: 0.8rem;
  text-transform: capitalize;
}

.badge-success { background: var(--success); color: white; }
.badge-warning { background: var(--warning); color: #000; }
.badge-danger { background: var(--danger); color: white; }

.entity-link {
  color: var(--link);
  text-decoration: none;
}

.entity-link:hover {
  text-decoration: underline;
}

.changes-btn {
  padding: 0.2rem 0.5rem;
  font-size: 0.8rem;
  background: var(--primary);
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.changes-btn:hover {
  background: var(--primary-dark);
}

/* Size columns to their content and let the container scroll horizontally
   (global .table-container is overflow-x:auto) instead of fixed widths that
   ellipsis-clip Timestamp/User/IP off-screen on a narrow main pane. Only the
   free-form Name/ID cell is bounded, so one long value cannot blow the table
   width out; its full text stays in the title tooltip. */
.table-container > table {
  min-width: 100%;
}
.name-cell {
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.no-changes {
  color: var(--text-light);
}

.loading, .empty {
  text-align: center;
  color: var(--text-light);
  padding: 2rem;
}

/* Modal */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal {
  /* SOLID, not var(--bg-card) - translucent in dark mode over the overlay. */
  background: var(--bg-card-solid);
  border: 1px solid var(--border);
  border-radius: 8px;
  min-width: 500px;
  max-width: 90vw;
  max-height: 80vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem;
  border-bottom: 1px solid var(--border);
}

.modal-header h3 {
  margin: 0;
  font-size: 1rem;
}

.close-btn {
  background: none;
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
  color: var(--text-light);
  padding: 0;
  line-height: 1;
}

.close-btn:hover {
  color: var(--text);
}

.modal-body {
  padding: 1rem;
  overflow-y: auto;
}

.changes-table {
  width: 100%;
  border-collapse: collapse;
}

.changes-table th,
.changes-table td {
  padding: 0.5rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
}

.changes-table th {
  background: var(--bg);
  font-weight: 600;
}

.old-value {
  color: var(--danger);
  text-decoration: line-through;
}

.new-value {
  color: var(--success);
}
</style>
