<template>
	<div class="injury-list">
		<div class="injury-list__header">
			<h2>Verletzungsprotokoll</h2>
			<div class="injury-list__actions">
				<div class="injury-list__filters">
					<input v-model="filterDateFrom"
						type="date"
						class="injury-list__input"
						placeholder="Von"
						@change="doFilter">
					<input v-model="filterDateTo"
						type="date"
						class="injury-list__input"
						placeholder="Bis"
						@change="doFilter">
				</div>
				<ColumnPicker :columns="allColumns"
					:model-value="visibleKeys"
					@update:model-value="setVisibleKeys" />
				<NcButton type="primary" @click="showCreate = true">
					Neue Verletzung
				</NcButton>
			</div>
		</div>

		<!-- Messages -->
		<div v-if="injuryStore.error" class="injury-list__message injury-list__message--error">
			{{ injuryStore.error }}
			<NcButton @click="injuryStore.clearError()">
				Schließen
			</NcButton>
		</div>
		<div v-if="injuryStore.success" class="injury-list__message injury-list__message--success">
			{{ injuryStore.success }}
			<NcButton @click="injuryStore.clearSuccess()">
				Schließen
			</NcButton>
		</div>

		<!-- Injury table -->
		<div v-if="injuryStore.loading" class="injury-list__loading">
			Lade Verletzungen...
		</div>
		<table v-else class="injury-list__table">
			<thead>
				<tr>
					<th v-for="col in visibleColumns" :key="col.key"
						class="injury-list__th"
						:class="{ 'injury-list__th--sortable': col.sortable }"
						@click="col.sortable && toggleSort(col.sortField || col.key)">
						{{ col.label }}
						<SortIcon v-if="col.sortable"
							:field="col.sortField || col.key"
							:current-sort="sortField"
							:sort-asc="sortAsc" />
					</th>
				</tr>
			</thead>
			<tbody>
				<tr v-for="injury in paginatedItems"
					:key="injury.id"
					class="injury-list__row">
					<td v-for="col in visibleColumns" :key="col.key"
						:class="{ 'injury-list__beschreibung': col.key === 'beschreibung' }">
						<template v-if="col.key === 'mitglied'">
							<router-link :to="{ name: 'member-detail', params: { id: injury.memberId } }">
								{{ col.render(injury) }}
							</router-link>
						</template>
						<template v-else-if="col.key === 'aktionen'">
							<NcButton @click="editInjury(injury)">
								Bearbeiten
							</NcButton>
							<NcButton @click="confirmDelete(injury)">
								Löschen
							</NcButton>
						</template>
						<template v-else>{{ col.render(injury) }}</template>
					</td>
				</tr>
				<tr v-if="injuryStore.injuries.length === 0">
					<td :colspan="visibleColumns.length" class="injury-list__empty">
						Keine Verletzungen dokumentiert
					</td>
				</tr>
			</tbody>
		</table>

		<!-- Pagination -->
		<PaginationControls
			:current-page="currentPage"
			:total-items="totalItems"
			:page-size="pageSize"
			item-label="Verletzungen"
			@page="goToPage"
			@update:page-size="onPageSizeChange" />

		<!-- Create / Edit dialog -->
		<InjuryForm v-if="showCreate"
			:injury="editingInjury"
			@close="closeForm"
			@submit="handleSubmit" />
	</div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { NcButton } from '@nextcloud/vue'
import { useInjuryStore } from '../stores/injuries.js'
import { useColumnVisibility } from '../utils/useColumnVisibility.js'
import { usePageSize } from '../utils/usePageSize.js'
import { useClientPagination } from '../utils/useClientPagination.js'
import ColumnPicker from '../components/ColumnPicker.vue'
import PaginationControls from '../components/PaginationControls.vue'
import SortIcon from '../components/SortIcon.vue'
import InjuryForm from '../components/InjuryForm.vue'
import { formatDate } from '../utils/dateFormat.js'

const injuryStore = useInjuryStore()
const { pageSize, setPageSize } = usePageSize('mv_injury_pagesize')

const showCreate = ref(false)
const editingInjury = ref(null)
const filterDateFrom = ref('')
const filterDateTo = ref('')
const sortField = ref('datum')
const sortAsc = ref(false)

function truncate(text, maxLen) {
	if (!text) return ''
	return text.length > maxLen ? text.substring(0, maxLen) + '...' : text
}

const allColumns = [
	{ key: 'datum', label: 'Datum', sortable: true, sortField: 'datum', alwaysVisible: true, render: i => formatDate(i.datum) },
	{ key: 'mitglied', label: 'Mitglied', sortable: true, sortField: '_memberName', render: i => `${i.memberVorname} ${i.memberNachname}` },
	{ key: 'lager', label: 'Lager / Aktivität', sortable: true, sortField: '_lagerName', render: i => i.lagerName || i.activityName || '-' },
	{ key: 'beschreibung', label: 'Beschreibung', render: i => truncate(i.beschreibung, 80) },
	{ key: 'beteiligte', label: 'Beteiligte', render: i => i.involvedMembers?.length || 0 },
	{ key: 'aktionen', label: 'Aktionen', render: () => '' },
]

const { visibleKeys, visibleColumns, setVisibleKeys } = useColumnVisibility(
	'mv_injury_columns',
	allColumns,
	['datum', 'mitglied', 'lager', 'beschreibung', 'beteiligte', 'aktionen'],
)

const sortedInjuries = computed(() => {
	const injuries = [...injuryStore.injuries]
	const field = sortField.value
	const asc = sortAsc.value

	return injuries.sort((a, b) => {
		let valA, valB
		if (field === '_memberName') {
			valA = `${a.memberNachname} ${a.memberVorname}`.toLowerCase()
			valB = `${b.memberNachname} ${b.memberVorname}`.toLowerCase()
		} else if (field === '_lagerName') {
			valA = (a.lagerName || a.activityName || '').toLowerCase()
			valB = (b.lagerName || b.activityName || '').toLowerCase()
		} else {
			valA = a[field] ?? ''
			valB = b[field] ?? ''
			if (typeof valA === 'string') {
				valA = valA.toLowerCase()
				valB = String(valB).toLowerCase()
			}
		}

		if (valA < valB) return asc ? -1 : 1
		if (valA > valB) return asc ? 1 : -1
		return 0
	})
})

const { currentPage, totalItems, paginatedItems, goToPage, resetPage } = useClientPagination(sortedInjuries, pageSize)

function onPageSizeChange(size) {
	setPageSize(size)
	resetPage()
}

function toggleSort(field) {
	if (sortField.value === field) {
		sortAsc.value = !sortAsc.value
	} else {
		sortField.value = field
		sortAsc.value = true
	}
}

function doFilter() {
	const params = {}
	if (filterDateFrom.value) params.dateFrom = filterDateFrom.value
	if (filterDateTo.value) params.dateTo = filterDateTo.value
	injuryStore.fetchInjuries(params)
}

function editInjury(injury) {
	editingInjury.value = injury
	showCreate.value = true
}

function closeForm() {
	showCreate.value = false
	editingInjury.value = null
}

async function handleSubmit(data) {
	try {
		if (editingInjury.value) {
			await injuryStore.updateInjury(editingInjury.value.id, data)
		} else {
			await injuryStore.createInjury(data)
		}
		closeForm()
		injuryStore.fetchInjuries()
	} catch {
		// Error handled by store
	}
}

async function confirmDelete(injury) {
	const name = `${injury.memberVorname} ${injury.memberNachname}`
	if (confirm(`Verletzungseintrag für "${name}" vom ${formatDate(injury.datum)} wirklich löschen?`)) {
		await injuryStore.deleteInjury(injury.id)
	}
}

onMounted(() => {
	injuryStore.fetchInjuries()
})
</script>

<style scoped>
.injury-list { padding: 20px; max-width: 1200px; }
.injury-list__header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 12px; }
.injury-list__header h2 { margin: 0; }
.injury-list__actions { display: flex; gap: 12px; align-items: center; }
.injury-list__filters { display: flex; gap: 8px; }
.injury-list__input { padding: 6px 8px; border: 1px solid var(--color-border); border-radius: 4px; }
.injury-list__message { padding: 12px; border-radius: 8px; margin-bottom: 16px; display: flex; justify-content: space-between; align-items: center; }
.injury-list__message--error { background: var(--color-error-hover, #fce4e4); color: var(--color-error); }
.injury-list__message--success { background: var(--color-success-hover, #e4fce4); color: var(--color-success); }
.injury-list__loading { padding: 40px; text-align: center; color: var(--color-text-lighter); }
.injury-list__table { width: 100%; border-collapse: collapse; font-size: 14px; }
.injury-list__th { background: var(--color-primary); color: white; padding: 8px 12px; text-align: left; white-space: nowrap; }
.injury-list__th--sortable { cursor: pointer; user-select: none; }
.injury-list__th--sortable:hover { background-color: var(--color-primary-element-hover); }
.injury-list__table td { padding: 8px 12px; border-bottom: 1px solid var(--color-border); }
.injury-list__row:hover { background: var(--color-background-hover); }
.injury-list__beschreibung { max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.injury-list__empty { text-align: center; padding: 40px; color: var(--color-text-lighter); }
</style>
