<template>
	<div class="audit-log">
		<div class="audit-log__header">
			<h2>Audit-Log</h2>
			<ColumnPicker :columns="allColumns"
				:model-value="visibleKeys"
				@update:model-value="setVisibleKeys" />
		</div>

		<!-- Filters -->
		<div class="audit-log__filters">
			<div class="audit-log__filter">
				<label>Entität</label>
				<select :value="store.filters.entitaet || ''"
					class="audit-log__select"
					@change="onFilterChange('entitaet', $event.target.value || null)">
					<option value="">Alle</option>
					<option value="member">Mitglied</option>
					<option value="family">Familie</option>
					<option value="stufe">Stufe</option>
					<option value="fee_rule">Beitragsregel</option>
					<option value="fee_record">Beitragsposition</option>
					<option value="permission">Berechtigung</option>
				</select>
			</div>

			<div class="audit-log__filter">
				<label>Benutzer</label>
				<NcTextField :model-value="store.filters.ncUserId || ''"
					placeholder="Benutzer-ID"
					@update:model-value="onFilterChange('ncUserId', $event || null)" />
			</div>

			<div class="audit-log__filter">
				<label>Entität-ID</label>
				<NcTextField :model-value="store.filters.entitaetId || ''"
					placeholder="ID"
					@update:model-value="onFilterChange('entitaetId', $event || null)" />
			</div>

			<div class="audit-log__filter">
				<label>Von</label>
				<input type="date"
					:value="store.filters.from || ''"
					class="audit-log__date-input"
					@input="onFilterChange('from', $event.target.value || null)">
			</div>

			<div class="audit-log__filter">
				<label>Bis</label>
				<input type="date"
					:value="store.filters.to || ''"
					class="audit-log__date-input"
					@input="onFilterChange('to', $event.target.value || null)">
			</div>

			<NcButton @click="store.clearFilters()">
				Filter zurücksetzen
			</NcButton>
		</div>

		<!-- Error -->
		<NcEmptyContent v-if="store.error && !store.loading"
			name="Fehler"
			:description="store.error">
			<template #action>
				<NcButton @click="reload">Erneut versuchen</NcButton>
			</template>
		</NcEmptyContent>

		<!-- Loading -->
		<NcLoadingIcon v-else-if="store.loading && store.entries.length === 0"
			:size="64"
			class="audit-log__loading" />

		<!-- Empty state -->
		<NcEmptyContent v-else-if="!store.loading && store.entries.length === 0"
			name="Keine Einträge"
			description="Für die aktuelle Filterauswahl wurden keine Audit-Log-Einträge gefunden." />

		<!-- Table -->
		<table v-else class="audit-log__table">
			<thead>
				<tr>
					<th v-for="col in visibleColumns" :key="col.key"
						class="audit-log__th">
						{{ col.label }}
					</th>
				</tr>
			</thead>
			<tbody>
				<tr v-for="entry in store.entries"
					:key="entry.id"
					class="audit-log__row">
					<td v-for="col in visibleColumns" :key="col.key"
						class="audit-log__td"
						:class="{
							'audit-log__td--time': col.key === 'zeitpunkt',
							'audit-log__td--value': col.key === 'alterWert' || col.key === 'neuerWert',
						}">
						<template v-if="col.key === 'aktion'">
							<span :class="'audit-log__action audit-log__action--' + entry.aktion">
								{{ col.render(entry) }}
							</span>
						</template>
						<template v-else-if="col.key === 'entitaet'">
							<span class="audit-log__entity-link"
								@click="navigateToEntity(entry.entitaet, entry.entitaetId)">
								{{ col.render(entry) }}
							</span>
						</template>
						<template v-else-if="col.key === 'alterWert' || col.key === 'neuerWert'">
							<span :class="{ 'audit-log__encrypted': isEncrypted(col.render(entry)) }">
								{{ col.render(entry) }}
							</span>
						</template>
						<template v-else>{{ col.render(entry) }}</template>
					</td>
				</tr>
			</tbody>
		</table>

		<!-- Pagination -->
		<PaginationControls
			:current-page="store.currentPage"
			:total-items="store.total"
			:page-size="pageSize"
			item-label="Einträge"
			@page="store.goToPage($event)"
			@update:page-size="onPageSizeChange" />
	</div>
</template>

<script setup>
import { onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { NcButton, NcTextField, NcEmptyContent, NcLoadingIcon } from '@nextcloud/vue'
import { useAuditLogStore } from '../stores/auditlog.js'
import { useColumnVisibility } from '../utils/useColumnVisibility.js'
import { usePageSize } from '../utils/usePageSize.js'
import ColumnPicker from '../components/ColumnPicker.vue'
import PaginationControls from '../components/PaginationControls.vue'
import { formatDateTime } from '../utils/dateFormat.js'

const store = useAuditLogStore()
const { pageSize, setPageSize } = usePageSize('mv_audit_pagesize')
store.limit = pageSize.value

function onPageSizeChange(size) {
	setPageSize(size)
	store.setLimit(size)
}
const router = useRouter()

let filterTimeout = null

const aktionMap = { create: 'Erstellt', update: 'Geändert', delete: 'Gelöscht', 'soft-delete': 'Soft-Delete' }
const entitaetMap = { member: 'Mitglied', family: 'Familie', stufe: 'Stufe', fee_rule: 'Beitragsregel', fee_record: 'Beitragsposition', permission: 'Berechtigung' }

const allColumns = [
	{ key: 'zeitpunkt', label: 'Zeitpunkt', alwaysVisible: true, render: e => formatDateTime(e.zeitpunkt) },
	{ key: 'ncUserId', label: 'Benutzer', render: e => e.ncUserId },
	{ key: 'aktion', label: 'Aktion', render: e => aktionMap[e.aktion] || e.aktion },
	{ key: 'entitaet', label: 'Entität', render: e => (entitaetMap[e.entitaet] || e.entitaet) + ' #' + e.entitaetId },
	{ key: 'feld', label: 'Feld', render: e => e.feld || '\u2014' },
	{ key: 'alterWert', label: 'Alter Wert', render: e => e.alterWert || '\u2014' },
	{ key: 'neuerWert', label: 'Neuer Wert', render: e => e.neuerWert || '\u2014' },
]

const { visibleKeys, visibleColumns, setVisibleKeys } = useColumnVisibility(
	'mv_audit_columns',
	allColumns,
	['zeitpunkt', 'ncUserId', 'aktion', 'entitaet', 'feld', 'alterWert', 'neuerWert'],
)

onMounted(() => {
	store.fetchEntries()
})

function onFilterChange(field, value) {
	clearTimeout(filterTimeout)
	filterTimeout = setTimeout(() => {
		store.applyFilters({ [field]: value })
	}, 400)
}

function reload() {
	store.clearError()
	store.fetchEntries()
}

function isEncrypted(value) {
	return value === '[verschluesselt]'
}

function navigateToEntity(entitaet, entitaetId) {
	if (!entitaetId) return
	switch (entitaet) {
	case 'member':
		router.push({ name: 'member-detail', params: { id: entitaetId } })
		break
	case 'family':
		router.push({ name: 'family-detail', params: { id: entitaetId } })
		break
	default:
		break
	}
}
</script>

<style scoped>
.audit-log { padding: 20px; }
.audit-log__header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
.audit-log__header h2 { margin: 0; }
.audit-log__filters { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 20px; padding: 12px 16px; background: var(--color-background-dark); border-radius: var(--border-radius-large); }
.audit-log__filter { display: flex; flex-direction: column; gap: 4px; }
.audit-log__filter label { font-size: 0.8em; color: var(--color-text-lighter); font-weight: 500; }
.audit-log__select { padding: 6px 8px; border: 1px solid var(--color-border); border-radius: var(--border-radius); background: var(--color-main-background); color: var(--color-text); }
.audit-log__date-input { padding: 6px 8px; border: 1px solid var(--color-border); border-radius: var(--border-radius); background: var(--color-main-background); color: var(--color-text); }
.audit-log__loading { display: flex; justify-content: center; margin-top: 60px; }
.audit-log__table { width: 100%; border-collapse: collapse; font-size: 0.9em; }
.audit-log__th { text-align: left; padding: 10px 12px; border-bottom: 2px solid var(--color-border-dark); font-weight: bold; white-space: nowrap; }
.audit-log__row { transition: background-color 0.15s ease; }
.audit-log__row:hover { background-color: var(--color-background-hover); }
.audit-log__td { padding: 8px 12px; border-bottom: 1px solid var(--color-border); vertical-align: top; }
.audit-log__td--time { white-space: nowrap; font-size: 0.9em; color: var(--color-text-lighter); }
.audit-log__td--value { max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.audit-log__action { display: inline-block; padding: 2px 8px; border-radius: var(--border-radius-pill); font-size: 0.85em; font-weight: 500; }
.audit-log__action--create { background-color: var(--color-success); color: white; }
.audit-log__action--update { background-color: var(--color-primary); color: white; }
.audit-log__action--delete, .audit-log__action--soft-delete { background-color: var(--color-error); color: white; }
.audit-log__entity-link { cursor: pointer; color: var(--color-primary); }
.audit-log__entity-link:hover { text-decoration: underline; }
.audit-log__encrypted { font-style: italic; color: var(--color-text-lighter); }
</style>
