<script setup>
import { ref, reactive, onMounted } from 'vue'
import * as auditApi from '@/api/audit'
import Button from '@/components/ui/Button.vue'
import Skeleton from '@/components/ui/Skeleton.vue'
import EmptyState from '@/components/ui/EmptyState.vue'
import {
  AUDIT_ACTIONS,
  PHI_ACCESS_TYPES,
  actionLabel,
  accessTypeLabel,
  formatAuditTimestamp,
  formatJsonBlock,
  defaultFromDate,
  defaultToDate,
  toIsoOffset,
} from '@/composables/auditFormat'

const activeTab = ref('audit')
const loading = ref(true)
const error = ref('')
const page = ref(1)
const pageSize = 50
const totalPages = ref(1)
const totalCount = ref(0)
const items = ref([])
const expandedId = ref(null)

const filters = reactive({
  from: defaultFromDate(),
  to: defaultToDate(),
  entityType: '',
  action: '',
  accessType: '',
  patientId: '',
  userId: '',
})

async function load() {
  loading.value = true
  error.value = ''
  try {
    const common = {
      from: toIsoOffset(filters.from),
      to: toIsoOffset(filters.to),
      page: page.value,
      pageSize,
    }
    const result = activeTab.value === 'audit'
      ? await auditApi.fetchAuditLogs({
          ...common,
          entityType: filters.entityType || undefined,
          action: filters.action || undefined,
          userId: filters.userId || undefined,
        })
      : await auditApi.fetchPhiAccessLogs({
          ...common,
          accessType: filters.accessType || undefined,
          patientId: filters.patientId || undefined,
          userId: filters.userId || undefined,
        })
    items.value = result.items ?? []
    totalPages.value = result.totalPages ?? 1
    totalCount.value = result.totalCount ?? 0
  } catch (err) {
    error.value = err.message
    items.value = []
  } finally {
    loading.value = false
  }
}

function applyFilters() {
  page.value = 1
  expandedId.value = null
  load()
}

function switchTab(tab) {
  activeTab.value = tab
  page.value = 1
  expandedId.value = null
  load()
}

function toggleExpand(id) {
  expandedId.value = expandedId.value === id ? null : id
}

function prevPage() {
  if (page.value > 1) {
    page.value -= 1
    load()
  }
}

function nextPage() {
  if (page.value < totalPages.value) {
    page.value += 1
    load()
  }
}

onMounted(load)
</script>

<template>
  <div>
    <div class="mb-4">
      <h1 class="text-xl font-bold dark:text-white">Audit Logs</h1>
      <p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
        Browse clinical audit events and PHI access history for compliance review.
      </p>
    </div>

    <div class="mb-4 flex gap-2 border-b border-gray-200 dark:border-gray-700">
      <button
        type="button"
        class="border-b-2 px-4 py-2 text-sm font-medium transition"
        :class="activeTab === 'audit'
          ? 'border-blue-600 text-blue-600 dark:border-blue-400 dark:text-blue-400'
          : 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200'"
        @click="switchTab('audit')"
      >
        Clinical audit
      </button>
      <button
        type="button"
        class="border-b-2 px-4 py-2 text-sm font-medium transition"
        :class="activeTab === 'phi'
          ? 'border-blue-600 text-blue-600 dark:border-blue-400 dark:text-blue-400'
          : 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200'"
        @click="switchTab('phi')"
      >
        PHI access
      </button>
    </div>

    <form
      class="mb-4 grid gap-4 rounded-lg border border-gray-200 p-4 dark:border-gray-700 sm:grid-cols-2 lg:grid-cols-4"
      @submit.prevent="applyFilters"
    >
      <div>
        <label class="mb-2 block text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
          From
        </label>
        <input
          v-model="filters.from"
          type="datetime-local"
          class="w-full rounded border border-gray-300 px-4 py-2 text-sm dark:border-gray-600 dark:bg-gray-800 dark:text-white"
        >
      </div>
      <div>
        <label class="mb-2 block text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
          To
        </label>
        <input
          v-model="filters.to"
          type="datetime-local"
          class="w-full rounded border border-gray-300 px-4 py-2 text-sm dark:border-gray-600 dark:bg-gray-800 dark:text-white"
        >
      </div>

      <template v-if="activeTab === 'audit'">
        <div>
          <label class="mb-2 block text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
            Entity type
          </label>
          <input
            v-model="filters.entityType"
            type="text"
            placeholder="e.g. Patient"
            class="w-full rounded border border-gray-300 px-4 py-2 text-sm dark:border-gray-600 dark:bg-gray-800 dark:text-white"
          >
        </div>
        <div>
          <label class="mb-2 block text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
            Action
          </label>
          <select
            v-model="filters.action"
            class="w-full rounded border border-gray-300 px-4 py-2 text-sm dark:border-gray-600 dark:bg-gray-800 dark:text-white"
          >
            <option value="">All actions</option>
            <option v-for="opt in AUDIT_ACTIONS" :key="opt.value" :value="opt.value">
              {{ opt.label }}
            </option>
          </select>
        </div>
      </template>

      <template v-else>
        <div>
          <label class="mb-2 block text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
            Patient ID
          </label>
          <input
            v-model="filters.patientId"
            type="text"
            placeholder="UUID"
            class="w-full rounded border border-gray-300 px-4 py-2 text-sm dark:border-gray-600 dark:bg-gray-800 dark:text-white"
          >
        </div>
        <div>
          <label class="mb-2 block text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
            Access type
          </label>
          <select
            v-model="filters.accessType"
            class="w-full rounded border border-gray-300 px-4 py-2 text-sm dark:border-gray-600 dark:bg-gray-800 dark:text-white"
          >
            <option value="">All types</option>
            <option v-for="opt in PHI_ACCESS_TYPES" :key="opt.value" :value="opt.value">
              {{ opt.label }}
            </option>
          </select>
        </div>
      </template>

      <div>
        <label class="mb-2 block text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
          User ID
        </label>
        <input
          v-model="filters.userId"
          type="text"
          placeholder="UUID"
          class="w-full rounded border border-gray-300 px-4 py-2 text-sm dark:border-gray-600 dark:bg-gray-800 dark:text-white"
        >
      </div>

      <div class="flex items-end sm:col-span-2 lg:col-span-1">
        <Button type="submit" size="sm">Apply filters</Button>
      </div>
    </form>

    <p v-if="error" class="mb-4 text-sm text-red-600 dark:text-red-400">{{ error }}</p>

    <Skeleton v-if="loading" :rows="8" />
    <EmptyState v-else-if="items.length === 0" message="No log entries match the current filters" />

    <template v-else>
      <div class="overflow-x-auto rounded-lg border border-gray-200 dark:border-gray-700">
        <table class="min-w-full divide-y divide-gray-200 text-sm dark:divide-gray-700">
          <thead class="bg-gray-50 dark:bg-gray-800">
            <tr class="text-left text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">
              <th class="px-4 py-3">Time</th>
              <th v-if="activeTab === 'audit'" class="px-4 py-3">Action</th>
              <th v-else class="px-4 py-3">Access type</th>
              <th class="px-4 py-3">User</th>
              <th v-if="activeTab === 'audit'" class="px-4 py-3">Entity</th>
              <th v-else class="px-4 py-3">Patient</th>
              <th v-if="activeTab === 'phi'" class="px-4 py-3">Resource</th>
              <th class="px-4 py-3" />
            </tr>
          </thead>
          <tbody class="divide-y divide-gray-200 dark:divide-gray-700">
            <template v-for="entry in items" :key="entry.id">
              <tr>
                <td class="px-4 py-3 text-gray-700 dark:text-gray-300">
                  {{ formatAuditTimestamp(activeTab === 'audit' ? entry.createdAt : entry.accessedAt) }}
                </td>
                <td class="px-4 py-3 text-gray-700 dark:text-gray-300">
                  {{ activeTab === 'audit' ? actionLabel(entry.action) : accessTypeLabel(entry.accessType) }}
                </td>
                <td class="px-4 py-3 text-gray-700 dark:text-gray-300">
                  {{ entry.userDisplayName ?? '—' }}
                </td>
                <td v-if="activeTab === 'audit'" class="px-4 py-3 text-gray-700 dark:text-gray-300">
                  <span class="font-medium">{{ entry.entityType }}</span>
                  <span class="block font-mono text-xs text-gray-500 dark:text-gray-400">{{ entry.entityId }}</span>
                </td>
                <td v-else class="px-4 py-3 font-mono text-xs text-gray-700 dark:text-gray-300">
                  {{ entry.patientId ?? '—' }}
                </td>
                <td v-if="activeTab === 'phi'" class="px-4 py-3 text-gray-700 dark:text-gray-300">
                  {{ entry.resourcePath }}
                </td>
                <td class="px-4 py-3 text-right">
                  <Button
                    v-if="activeTab === 'audit' && (entry.previousValueJson || entry.newValueJson)"
                    size="sm"
                    variant="secondary"
                    @click="toggleExpand(entry.id)"
                  >
                    {{ expandedId === entry.id ? 'Hide' : 'Details' }}
                  </Button>
                </td>
              </tr>
              <tr v-if="activeTab === 'audit' && expandedId === entry.id">
                <td colspan="6" class="bg-gray-50 px-4 py-4 dark:bg-gray-800/50">
                  <div class="grid gap-4 lg:grid-cols-2">
                    <div v-if="entry.previousValueJson">
                      <p class="mb-2 text-xs font-semibold uppercase tracking-wide text-gray-500">Previous</p>
                      <pre class="overflow-x-auto rounded border border-gray-200 bg-white p-4 text-xs dark:border-gray-700 dark:bg-gray-900">{{ formatJsonBlock(entry.previousValueJson) }}</pre>
                    </div>
                    <div v-if="entry.newValueJson">
                      <p class="mb-2 text-xs font-semibold uppercase tracking-wide text-gray-500">New</p>
                      <pre class="overflow-x-auto rounded border border-gray-200 bg-white p-4 text-xs dark:border-gray-700 dark:bg-gray-900">{{ formatJsonBlock(entry.newValueJson) }}</pre>
                    </div>
                  </div>
                  <p v-if="entry.reason" class="mt-4 text-sm text-gray-600 dark:text-gray-400">
                    Reason: {{ entry.reason }}
                  </p>
                </td>
              </tr>
            </template>
          </tbody>
        </table>
      </div>

      <div class="mt-4 flex items-center justify-between text-sm text-gray-600 dark:text-gray-400">
        <span>{{ totalCount }} entries — page {{ page }} of {{ totalPages }}</span>
        <div class="flex gap-2">
          <Button size="sm" variant="secondary" :disabled="page <= 1" @click="prevPage">Previous</Button>
          <Button size="sm" variant="secondary" :disabled="page >= totalPages" @click="nextPage">Next</Button>
        </div>
      </div>
    </template>
  </div>
</template>
