<template lang="html">
	<!-- Filter Controls Panel -->
	<div v-if="hasFilters" :key="`filter-controls-${tableName}`" class="dt-filter-panel">
		<div class="dt-filter-header">
			<h6 class="dt-filter-title">
				<i class="pi pi-filter"></i>
				Filters
			</h6>
		</div>
		<div class="dt-filter-content">
			<div class="dt-filter-grid">
				<div v-for="col in filterableColumns" :key="col.fieldName" class="dt-filter-field">
					<label :for="col.filterInputId || `filter-${col.fieldName}`" class="dt-filter-label">
						{{ col.label }}
					</label>
					<InputText
						:id="col.filterInputId || col.searchInputId || `filter-${col.fieldName}`"
						v-model="pendingFilters[col.fieldName]"
						:placeholder="`Filter by ${col.label.toLowerCase()}...`"
						class="dt-filter-input"
						@keyup.enter="applyFilters"
					/>
				</div>
			</div>
			<div class="dt-filter-actions">
				<Button
					label="Apply"
					icon="pi pi-check"
					@click="applyFilters"
					:disabled="!hasFilterChanges"
					class="dt-btn-primary"
					size="small"
				/>
				<Button
					label="Clear"
					icon="pi pi-times"
					@click="clearFilters"
					severity="secondary"
					outlined
					size="small"
					:disabled="!hasActiveFilters"
					class="dt-btn-secondary"
				/>
			</div>
			<div v-if="hasActiveFilters" class="dt-filter-status">
				<i class="pi pi-info-circle"></i>
				<span>Active filters: {{ getActiveFiltersText() }}</span>
			</div>
		</div>
	</div>

	<!-- Page Jump Controls -->
	<div
		v-if="totalPages > 1"
		:key="`page-controls-${totalPages}-${getPageInfo().total}`"
		class="dt-pagination-panel"
	>
		<div class="dt-pagination-content">
			<div class="dt-pagination-info">
				<i class="pi pi-info-circle"></i>
				<span class="dt-pagination-text">
					Showing {{ getPageInfo().start }} - {{ getPageInfo().end }} of
					{{ getPageInfo().total }} records
				</span>
			</div>
			<div class="dt-pagination-controls">
				<label for="page-jump" class="dt-pagination-label">Jump to:</label>
				<select
					id="page-jump"
					v-model="selectedPageJump"
					@change="jumpToPage"
					class="dt-pagination-select"
				>
					<option value="">Page...</option>
					<option v-for="page in totalPages" :key="page" :value="page">
						Page {{ page }}
					</option>
				</select>
			</div>
		</div>
	</div>

	<!-- Bulk Actions Section (when rows are selected) -->
	<div v-if="hasBulkActions && hasSelectedRows" class="dt-bulk-actions-panel">
		<div class="dt-bulk-actions-content">
			<div class="dt-bulk-actions-groups">
				<!-- Left positioned bulk actions -->
				<div
					v-if="bulkActionsGrouped.left.length > 0"
					class="dt-action-group dt-action-group-left"
				>
					<Button
						v-for="action in bulkActionsGrouped.left"
						:key="action.label"
						:label="`${action.label} (${selectedRows.length})`"
						:severity="action.style || 'warning'"
						:icon="action.icon"
						:size="action.size || 'small'"
						@click="handleBulkAction(action, selectedRows)"
						:disabled="loading"
						class="dt-bulk-btn"
					/>
				</div>
				<!-- Center positioned bulk actions -->
				<div
					v-if="bulkActionsGrouped.center.length > 0"
					class="dt-action-group dt-action-group-center"
				>
					<Button
						v-for="action in bulkActionsGrouped.center"
						:key="action.label"
						:label="`${action.label} (${selectedRows.length})`"
						:severity="action.style || 'warning'"
						:icon="action.icon"
						:size="action.size || 'small'"
						@click="handleBulkAction(action, selectedRows)"
						:disabled="loading"
						class="dt-bulk-btn"
					/>
				</div>
				<!-- Right positioned bulk actions -->
				<div
					v-if="bulkActionsGrouped.right.length > 0"
					class="dt-action-group dt-action-group-right"
				>
					<Button
						v-for="action in bulkActionsGrouped.right"
						:key="action.label"
						:label="`${action.label} (${selectedRows.length})`"
						:severity="action.style || 'warning'"
						:icon="action.icon"
						:size="action.size || 'small'"
						@click="handleBulkAction(action, selectedRows)"
						:disabled="loading"
						class="dt-bulk-btn"
					/>
				</div>
			</div>
			<div class="dt-bulk-actions-status">
				<i class="pi pi-check-circle"></i>
				<span
					>{{ selectedRows.length }} row{{
						selectedRows.length !== 1 ? "s" : ""
					}}
					selected</span
				>
			</div>
		</div>
	</div>

	<!-- Global Actions Section -->
	<div v-if="hasTopActions" class="dt-global-actions-panel">
		<div class="dt-global-actions-content">
			<!-- Left positioned actions -->
			<div
				v-if="topActionsGrouped.left.length > 0"
				class="dt-action-group dt-action-group-left"
			>
				<Button
					v-for="action in topActionsGrouped.left"
					:key="action.label"
					:label="action.label"
					:severity="getActionSeverity(action)"
					:icon="action.icon"
					:size="action.size || 'small'"
					@click="handleTopAction(action)"
					:disabled="getActionDisabled(action)"
					:class="getActionClasses(action)"
				/>
			</div>
			<!-- Center positioned actions -->
			<div
				v-if="topActionsGrouped.center.length > 0"
				class="dt-action-group dt-action-group-center"
			>
				<Button
					v-for="action in topActionsGrouped.center"
					:key="action.label"
					:label="action.label"
					:severity="getActionSeverity(action)"
					:icon="action.icon"
					:size="action.size || 'small'"
					@click="handleTopAction(action)"
					:disabled="getActionDisabled(action)"
					:class="getActionClasses(action)"
				/>
			</div>
			<!-- Right positioned actions -->
			<div
				v-if="topActionsGrouped.right.length > 0"
				class="dt-action-group dt-action-group-right"
			>
				<Button
					v-for="action in topActionsGrouped.right"
					:key="action.label"
					:label="action.label"
					:severity="getActionSeverity(action)"
					:icon="action.icon"
					:size="action.size || 'small'"
					@click="handleTopAction(action)"
					:disabled="getActionDisabled(action)"
					:class="getActionClasses(action)"
				/>
			</div>
		</div>
		<div v-if="singleSelectionActions.length > 0" class="dt-global-actions-status">
			<i class="pi pi-info-circle"></i>
			<span v-if="!hasSelectedRows">Select a row to enable single-selection actions</span>
			<span v-else-if="selectedRows.length > 1"
				>Select only one row to enable single-selection actions</span
			>
			<span v-else-if="hasExactlyOneRowSelected">Single-selection actions enabled</span>
		</div>
	</div>

	<DataTable
		ref="dataTableRef"
		:value="data"
		:rowsPerPageOptions="rowsPerPageOptions"
		:paginator="paginator"
		:rows="currentRows"
		:first="currentFirst"
		:lazy="lazy"
		:totalRecords="lazy ? totalRecords : getFilteredDataLength"
		@page="handlePage"
		@sort="handleSort"
		@filter="handleFilter"
		sortMode="single"
		removableSort
		filterDisplay="none"
		v-model:filters="filterRef"
		scrollable
		:scrollHeight="scrollHeight"
		v-model:selection="selectedRows"
		selectionMode="multiple"
		metaKeySelection="true"
		dataKey="id"
		:loading="loading"
		:loadingIcon="loadingIcon"
		@row-click="$emit('row-click', $event)"
	>
		<template #empty>
			<div class="text-center py-6">
				<i class="pi pi-info-circle text-4xl text-gray-400 mb-2"></i>
				<p class="text-gray-500">{{ emptyMessage || "No data available" }}</p>
			</div>
		</template>
		<template #loading>
			<div class="text-center py-6">
				<i class="pi pi-spin pi-spinner text-4xl text-blue-500 mb-2"></i>
				<p class="text-gray-600">{{ loadingMessage || "Loading data. Please wait..." }}</p>
			</div>
		</template>
		<Column
			v-for="col in columns"
			:key="col.fieldName"
			:field="col.fieldName"
			:header="col.label"
			:sortable="col.sortable"
		>
			<template v-if="col.filterable === true" #filter="{ filterModel, filterCallback }">
				<InputText
					:id="col.filterInputId || col.searchInputId || `inline-filter-${col.fieldName}`"
					v-model="filterModel.value"
					type="text"
					@input="handleFilterInput(col.fieldName, filterModel.value, filterCallback)"
					:placeholder="`Search ${col.label}...`"
					:disabled="loading"
				/>
			</template>
			<template v-if="col.type === 'status'" #body="slotProps">
				<Tag
					:value="slotProps.data[col.fieldName]"
					:severity="getBadgeColor(slotProps.data[col.fieldName])"
				/>
			</template>
			<template v-if="col.type === 'status-button'" #body="slotProps">
				<Button
					:label="slotProps.data[col.fieldName]"
					:severity="getBadgeColor(slotProps.data[col.fieldName])"
					size="small"
					:variant="col.buttonVariant || 'filled'"
					@click="handleStatusButtonClick(col, slotProps.data)"
					:disabled="
						loading ||
						(col.disableCondition &&
							col.disableCondition(slotProps.data[col.fieldName]))
					"
					class="status-button"
				/>
			</template>
			<template v-if="col.type === 'date'" #body="slotProps">
				<span>{{ formatDate(slotProps.data[col.fieldName]) }}</span>
			</template>
			<template v-if="col.type === 'button'" #body="slotProps">
				<Button
					:label="slotProps.data[col.fieldName]"
					size="small"
					severity="info"
					@click="$emit('rowClick', slotProps)"
				/>
			</template>
			<template v-if="col.type === 'link'" #body="slotProps">
				<button class="datatable-link"
					@click="handleLinkClick(col, slotProps.data)">
					{{ slotProps.data[col.fieldName] }}
				</button>
			</template>
		</Column>

		<!-- Actions Column -->
		<Column
			v-if="rowActions.length > 0"
			header="Actions"
			:exportable="false"
			class="dt-actions-column"
		>
			<template #body="slotProps">
				<div class="dt-row-actions">
					<!-- Primary row actions -->
					<div
						v-if="rowActionsGrouped.primary.length > 0"
						class="dt-row-actions-primary"
					>
						<Button
							v-for="action in rowActionsGrouped.primary"
							:key="action.label"
							:label="action.label"
							:severity="action.style || 'secondary'"
							:icon="action.icon"
							:size="action.size || 'small'"
							@click="handleRowAction(action, slotProps.data)"
							:disabled="loading"
							:class="[
								'dt-row-btn',
								action.layout?.variant && `dt-row-btn-${action.layout.variant}`,
							]"
							outlined
						/>
					</div>
					<!-- Secondary row actions -->
					<div
						v-if="rowActionsGrouped.secondary.length > 0"
						class="dt-row-actions-secondary"
					>
						<Button
							v-for="action in rowActionsGrouped.secondary"
							:key="action.label"
							:label="action.label"
							:severity="action.style || 'secondary'"
							:icon="action.icon"
							:size="action.size || 'small'"
							@click="handleRowAction(action, slotProps.data)"
							:disabled="loading"
							:class="[
								'dt-row-btn',
								'dt-row-btn-secondary',
								action.layout?.variant && `dt-row-btn-${action.layout.variant}`,
							]"
							text
						/>
					</div>
					<!-- Dropdown menu for overflow actions -->
					<div
						v-if="rowActionsGrouped.dropdown.length > 0"
						class="dt-row-actions-dropdown"
					>
						<Button
							icon="pi pi-ellipsis-v"
							:size="'small'"
							severity="secondary"
							text
							@click="toggleRowDropdown($event, slotProps.data)"
							class="dt-row-btn dt-row-btn-dropdown"
							aria-haspopup="true"
						/>
						<!-- Dropdown menu would go here - could be implemented with PrimeVue Menu component -->
					</div>
					<!-- Select menu for a single action with multiple options -->
					<div
						v-if="rowActionsGrouped.select.length > 0"
						class="dt-row-actions-select"
					>
						<Select
								v-for="action in rowActionsGrouped.select"
								:options="action.selectOptions"
								:placeholder="action.label"
								@change="handleSelectChange(action, slotProps.data, $event)"
						/>
					</div>
					<!-- Render Generic Component -->
					<div
						v-if="rowActionsGrouped.menu.length > 0"
						class="dt-row-actions-menu"
					>
						<template
							v-for="action in rowActionsGrouped.menu"
							:key="action.label"
						>
							<Button
								type="button"
								:label="action.menuLabel || action.label"
								:icon="action.icon"
								:size="action.size || 'small'"
								:severity="action.style || 'secondary'"
								@click="toggleMenu($event, action, slotProps.data)"
								aria-haspopup="true"
								:disabled="loading"
								class="dt-row-btn"
								outlined
							/>
							<Menu
								:ref="(el) => setMenuRef(el, action.label, slotProps.data.id)"
								:model="buildMenuItems(action.menuItems || [], slotProps.data)"
								:popup="true"
							/>
						</template>
					</div>
				</div>
			</template>
		</Column>
	</DataTable>
</template>
<script setup>
import { defineProps, computed, onMounted, watch, ref, reactive } from "vue";
import DataTable from "primevue/datatable";
import Column from "primevue/column";
import Tag from "primevue/tag";
import Button from "primevue/button";
import Select from "primevue/select";
import Menu from "primevue/menu";
import InputText from "primevue/inputtext";
import { FilterMatchMode } from "@primevue/core";
import { useFiltersStore } from "../../stores/filters";
import { useLoadingStore } from "../../stores/loading";
import { usePaginationStore } from "../../stores/pagination";

const filtersStore = useFiltersStore();
const loadingStore = useLoadingStore();
const paginationStore = usePaginationStore();

const menuRefs = reactive({});
const activeMenuKey = ref(null);

const props = defineProps({
	columns: {
		type: Array,
		required: true,
	},
	data: {
		type: Array,
		required: true,
	},
	// Pagination control
	paginator: {
		type: Boolean,
		default: true,
	},
	rows: {
		type: Number,
		default: 10,
	},
	rowsPerPageOptions: {
		type: Array,
		default: () => [5, 10, 20, 50],
	},
	filters: {
		type: Object,
		default: () => ({
			global: { value: null, matchMode: FilterMatchMode.CONTAINS },
		}),
	},
	tableName: {
		type: String,
		required: true,
	},
	loading: {
		type: Boolean,
		default: false,
	},
	loadingMessage: {
		type: String,
		default: "",
	},
	emptyMessage: {
		type: String,
		default: "",
	},
	loadingIcon: {
		type: String,
		default: "pi pi-spinner pi-spin",
	},
	scrollHeight: {
		type: String,
		default: "70vh",
	},
	// Auto-connect to global loading store
	useGlobalLoading: {
		type: Boolean,
		default: true,
	},
	// Server-side pagination support
	lazy: {
		type: Boolean,
		default: false,
	},
	totalRecords: {
		type: Number,
		default: 0,
	},
	// Total filtered records for non-lazy tables (when server-side filtering is used)
	totalFilteredRecords: {
		type: Number,
		default: null,
	},
	// Custom pagination event handler
	onLazyLoad: {
		type: Function,
		default: null,
	},
	// Table actions for rows
	tableActions: {
		type: Array,
		default: () => [],
	},
});

const setMenuRef = (el, label, id) => {
	if (el) {
		const refName = `${label}-${id}`;
		menuRefs[refName] = el;
	}
}

const emit = defineEmits([
	"rowClick",
	"row-click",
	"lazy-load",
	"page-change",
	"sort-change",
	"filter-change",
	"data-refresh",
]);

// Computed loading state that considers both prop and global store
const loading = computed(() => {
	if (props.useGlobalLoading) {
		return (
			props.loading ||
			loadingStore.getComponentLoading("dataTable") ||
			loadingStore.getComponentLoading(props.tableName) ||
			loadingStore.isAnyLoading
		);
	}
	return props.loading;
});

// Get current rows per page from pagination store or default
const currentRows = computed(() => {
	if (!props.paginator) {
		return props.data?.length || 0;
	}
	if (props.lazy) {
		return paginationStore.getTablePagination(props.tableName).rows;
	}
	return props.rows || 10; // Default for non-lazy tables
});

// Get current first index for pagination synchronization
const currentFirst = computed(() => {
	if (props.lazy && props.paginator) {
		return paginationStore.getTablePagination(props.tableName).first;
	}
	return currentPageState.value.first;
});

// Initialize filters and pagination in store when component mounts
onMounted(() => {
	filtersStore.initializeTableFilters(props.tableName, props.columns);
	filtersStore.initializeTableSorting(props.tableName);
	if (props.lazy && props.paginator) {
		paginationStore.initializeTablePagination(props.tableName, {
			rows: 10,
			totalRecords: props.totalRecords,
		});
	}
});

// Get filters from store, with fallback to props.filters
const filterRef = computed({
	get() {
		const storeFilters = filtersStore.getTableFilters(props.tableName);
		// Merge store filters with any additional filters from props
		return { ...props.filters, ...storeFilters };
	},
	set(newFilters) {
		// Update store when filters change
		Object.keys(newFilters).forEach((key) => {
			if (key !== "global" && newFilters[key]) {
				const filter = newFilters[key];
				filtersStore.updateTableFilter(
					props.tableName,
					key,
					filter.value,
					filter.matchMode,
				);
			}
		});
	},
});

// Watch for changes in total records to update page controls reactivity
watch(
	() => props.totalRecords,
	(newTotal) => {
		if (props.lazy && props.paginator && newTotal !== undefined) {
			// Force reactivity update for page controls
			selectedPageJump.value = "";
		}
	},
);

// Watch for data changes to update page controls for non-lazy tables
watch(
	() => props.data,
	(newData) => {
		if (!props.lazy && newData) {
			// Force reactivity update for page controls
			selectedPageJump.value = "";
		}
	},
);

// Watch for filter changes to sync match mode changes
watch(
	filterRef,
	(newFilters) => {
		Object.keys(newFilters).forEach((key) => {
			if (key !== "global" && newFilters[key]) {
				const filter = newFilters[key];
				const storeFilter = filtersStore.getTableFilters(props.tableName)[key];

				// Only update if the match mode has actually changed
				if (storeFilter && storeFilter.matchMode !== filter.matchMode) {
					filtersStore.updateTableFilter(
						props.tableName,
						key,
						filter.value,
						filter.matchMode,
					);
				}
			}
		});
	},
	{ deep: true },
);

const selectedRows = ref();
const pendingFilters = ref({});
const selectedPageJump = ref("");
const dataTableRef = ref();
const currentPageState = ref({ page: 0, first: 0 }); // Track current page for non-lazy tables

// Computed properties for filtering
const filterableColumns = computed(() => {
	return props.columns.filter((col) => col.filterable);
});

const hasFilters = computed(() => {
	return filterableColumns.value.length > 0;
});

const hasActiveFilters = computed(() => {
	return filtersStore.getActiveFiltersCount(props.tableName) > 0;
});

const hasFilterChanges = computed(() => {
	const currentFilters = filtersStore.getTableFilters(props.tableName);
	return Object.keys(pendingFilters.value).some((key) => {
		const pending = pendingFilters.value[key] || "";
		const current = currentFilters[key]?.value || "";
		return pending.trim() !== current.trim();
	});
});

const totalPages = computed(() => {
	if (!props.paginator) {
		return 1;
	}
	if (props.lazy) {
		return paginationStore.getTotalPages(props.tableName);
	}
	// For non-lazy tables, calculate based on current filtered data
	const filteredDataLength = getFilteredDataLength.value;
	return Math.ceil(filteredDataLength / currentRows.value) || 1;
});

// Computed properties for table actions
const hasActions = computed(() => {
	return props.tableActions && props.tableActions.length > 0;
});

const globalActions = computed(() => {
	return props.tableActions.filter(
		(action) =>
			!action.requiresSelection && !action.requiresMultipleSelection && !action.rowAction,
	);
});

const singleSelectionActions = computed(() => {
	return props.tableActions.filter(
		(action) =>
			action.requiresSelection && !action.requiresMultipleSelection && !action.rowAction,
	);
});

const rowActions = computed(() => {
	return props.tableActions.filter((action) => action.rowAction === true);
});

const bulkActions = computed(() => {
	return props.tableActions.filter((action) => action.requiresMultipleSelection === true);
});

// Layout-based action grouping
const topActionsGrouped = computed(() => {
	const actions = [...globalActions.value, ...singleSelectionActions.value];
	const groups = {
		left: actions.filter(
			(action) => action.layout?.position === "left" || !action.layout?.position,
		),
		center: actions.filter((action) => action.layout?.position === "center"),
		right: actions.filter((action) => action.layout?.position === "right"),
	};
	return groups;
});

const bulkActionsGrouped = computed(() => {
	const groups = {
		left: bulkActions.value.filter(
			(action) => action.layout?.position === "left" || !action.layout?.position,
		),
		center: bulkActions.value.filter((action) => action.layout?.position === "center"),
		right: bulkActions.value.filter((action) => action.layout?.position === "right"),
	};
	return groups;
});

const rowActionsGrouped = computed(() => {
	const groups = {
		primary: rowActions.value.filter(
			(action) => action.layout?.priority === "primary" || !action.layout?.priority,
		),
		secondary: rowActions.value.filter((action) => action.layout?.priority === "secondary"),
		dropdown: rowActions.value.filter((action) => action.layout?.priority === "dropdown"),
		select: rowActions.value.filter((action) => action.layout?.priority === "select"),
		menu: rowActions.value.filter((action) => action.layout?.priority === "menu"),
	};
	return groups;
});

const hasBulkActions = computed(() => {
	return bulkActions.value.length > 0;
});

const hasSingleSelectionActions = computed(() => {
	return singleSelectionActions.value.length > 0;
});

const hasTopActions = computed(() => {
	return globalActions.value.length > 0 || singleSelectionActions.value.length > 0;
});

const hasSelectedRows = computed(() => {
	return selectedRows.value && selectedRows.value.length > 0;
});

const hasExactlyOneRowSelected = computed(() => {
	return selectedRows.value && selectedRows.value.length === 1;
});

// Initialize pending filters from store
onMounted(() => {
	const currentFilters = filtersStore.getTableFilters(props.tableName);
	filterableColumns.value.forEach((col) => {
		// Use defaultValue from column definition if provided, otherwise use stored filter value
		const storedValue = currentFilters[col.fieldName]?.value || "";
		pendingFilters.value[col.fieldName] = col.defaultValue || storedValue;
	});
});

// Computed property to get filtered data length for non-lazy tables
const getFilteredDataLength = computed(() => {
	if (props.lazy) {
		return props.totalRecords;
	}

	// For non-lazy tables, use totalFilteredRecords if provided (server-side filtering),
	// otherwise fall back to data length (client-side filtering)
	return props.totalFilteredRecords !== null ? props.totalFilteredRecords : props.data.length;
});

// Filter management methods
const applyFilters = () => {
	// Update store with pending filter values
	Object.keys(pendingFilters.value).forEach((fieldName) => {
		const value = pendingFilters.value[fieldName]?.trim();
		filtersStore.updateTableFilter(
			props.tableName,
			fieldName,
			value || null,
			FilterMatchMode.CONTAINS,
		);
	});

	// Reset to first page when filters change (for both lazy and non-lazy)
	currentPageState.value = { page: 0, first: 0 };
	selectedPageJump.value = ""; // Reset page jump dropdown

	// For both lazy and non-lazy tables, trigger reload with new filters
	if (props.lazy) {
		paginationStore.resetToFirstPage(props.tableName);
		triggerLazyLoad();
	} else {
		// For non-lazy tables, also trigger a reload to get fresh data from server
		triggerDataRefresh();
	}
};

const clearFilters = () => {
	// Clear pending filters
	filterableColumns.value.forEach((col) => {
		pendingFilters.value[col.fieldName] = "";
	});

	// Clear store filters (but keep sorting)
	filtersStore.clearTableFilters(props.tableName);

	// Reset to first page when filters are cleared (for both lazy and non-lazy)
	currentPageState.value = { page: 0, first: 0 };
	selectedPageJump.value = ""; // Reset page jump dropdown

	// For both lazy and non-lazy tables, trigger reload with cleared filters
	if (props.lazy) {
		paginationStore.clearTableCache(props.tableName);
		paginationStore.resetToFirstPage(props.tableName);
		triggerLazyLoad();
	} else {
		// For non-lazy tables, also trigger a reload to get fresh data from server
		triggerDataRefresh();
	}
};

const getActiveFiltersText = () => {
	const currentFilters = filtersStore.getTableFilters(props.tableName);
	const activeFilters = [];
	Object.keys(currentFilters).forEach((key) => {
		if (currentFilters[key]?.value) {
			const column = filterableColumns.value.find((col) => col.fieldName === key);
			if (column) {
				activeFilters.push(`${column.label}: "${currentFilters[key].value}"`);
			}
		}
	});
	return activeFilters.join(", ");
};

// Page navigation methods
const jumpToPage = () => {
	if (selectedPageJump.value) {
		const pageNumber = parseInt(selectedPageJump.value) - 1; // Convert to 0-based

		if (props.lazy) {
			// Update pagination store - the currentFirst computed property will automatically sync
			paginationStore.setPage(props.tableName, pageNumber);
			triggerLazyLoad();
		} else {
			// For non-lazy tables, update our internal state
			currentPageState.value = {
				page: pageNumber,
				first: pageNumber * currentRows.value,
			};
		}
	}
	selectedPageJump.value = ""; // Reset selection
};

const getPageInfo = () => {
	if (props.lazy) {
		return paginationStore.getPageInfo(props.tableName);
	}

	// For non-lazy tables, calculate based on current page state and filtered data
	const filteredTotal = getFilteredDataLength.value;
	const rows = currentRows.value;
	const currentFirst = currentPageState.value.first;
	const start = filteredTotal > 0 ? currentFirst + 1 : 0;
	const end = Math.min(filteredTotal, currentFirst + rows);

	return {
		start,
		end,
		total: filteredTotal,
	};
};

// Handle pagination events
const handlePage = (event) => {
	console.log("Page event:", event);

	// Update current page state for both lazy and non-lazy tables
	currentPageState.value = {
		page: event.page,
		first: event.first,
	};

	if (props.lazy) {
		paginationStore.updateTablePagination(props.tableName, {
			page: event.page,
			first: event.first,
			rows: event.rows,
		});
		triggerLazyLoad();
	}
	emit("page-change", event);
};

// Handle sorting events
const handleSort = (event) => {
	console.log("Sort event received:", {
		sortField: event.sortField,
		sortOrder: event.sortOrder,
		type: typeof event.sortOrder,
		event: event,
	});

	try {
		// Handle removable sort - when sortOrder is null/undefined, clear sorting
		if (event.sortOrder === null || event.sortOrder === undefined) {
			console.log("Clearing sort due to removable sort");
			filtersStore.updateTableSorting(props.tableName, null, null);
		} else {
			// Update the stored sorting state immediately
			filtersStore.updateTableSorting(props.tableName, event.sortField, event.sortOrder);
		}

		// Reset to first page when sorting changes
		currentPageState.value = { page: 0, first: 0 };
		selectedPageJump.value = ""; // Reset page jump dropdown

		if (props.lazy) {
			paginationStore.clearTableCache(props.tableName);
			paginationStore.resetToFirstPage(props.tableName);

			// Trigger lazy load with sort information (or no sort if cleared)
			triggerLazyLoad({
				sortField: event.sortField || null,
				sortOrder: event.sortOrder || null,
				page: 0,
				first: 0,
			});
		} else {
			// For non-lazy tables, trigger data refresh
			triggerDataRefresh();
		}

		emit("sort-change", event);
	} catch (error) {
		console.error("Error in handleSort:", error);
		console.error("Event that caused error:", event);
		console.error("Stack trace:", error.stack);
	}
};

// Handle filter events
const handleFilter = (event) => {
	console.log("Filter event:", event);

	// Reset to first page when filters change (for both lazy and non-lazy)
	currentPageState.value = { page: 0, first: 0 };
	selectedPageJump.value = ""; // Reset page jump dropdown

	if (props.lazy) {
		paginationStore.resetToFirstPage(props.tableName);
		triggerLazyLoad();
	}
	emit("filter-change", event);
};

// Trigger lazy load event
const triggerLazyLoad = (event = {}) => {
	if (props.lazy) {
		const paginationParams = paginationStore.getPaginationParams(props.tableName);
		const filters = filtersStore.getTableFilters(props.tableName);

		// Get current sorting state from store
		const primarySortField = filtersStore.getPrimarySortField(props.tableName);
		const primarySortOrder = filtersStore.getPrimarySortOrder(props.tableName);

		const lazyEvent = {
			first: event.first !== undefined ? event.first : paginationParams.offset,
			rows: event.rows !== undefined ? event.rows : paginationParams.limit,
			page: event.page !== undefined ? event.page : paginationParams.page,
			sortField:
				event.sortField !== undefined
					? event.sortField
					: primarySortField || paginationParams.sortField,
			sortOrder:
				event.sortOrder !== undefined
					? event.sortOrder
					: primarySortOrder || paginationParams.sortOrder,
			filters: { ...filters, ...(event.filters || {}) },
		};

		console.log("Triggering lazy load with:", lazyEvent);
		emit("lazy-load", lazyEvent);
	}
};

// Trigger data refresh for non-lazy tables when filters change
const triggerDataRefresh = () => {
	const filters = filtersStore.getTableFilters(props.tableName);
	const primarySortField = filtersStore.getPrimarySortField(props.tableName);
	const primarySortOrder = filtersStore.getPrimarySortOrder(props.tableName);
	const refreshEvent = {
		filters: filters,
		sortField: primarySortField,
		sortOrder: primarySortOrder,
		page: currentPageState.value.page,
		first: currentPageState.value.first,
		rows: currentRows.value,
	};

	console.log("Triggering data refresh with:", refreshEvent);
	emit("data-refresh", refreshEvent);
};

const handleFilterInput = (fieldName, value, filterCallback) => {
	// Update the filter store
	filtersStore.updateTableFilter(props.tableName, fieldName, value, FilterMatchMode.CONTAINS);

	// Call the PrimeVue callback to update the filter
	if (filterCallback) {
		filterCallback();
	}

	// Reset to first page when filters change (for both lazy and non-lazy)
	currentPageState.value = { page: 0, first: 0 };

	// For lazy tables, reset pagination and trigger lazy load
	if (props.lazy) {
		paginationStore.resetToFirstPage(props.tableName);
		triggerLazyLoad();
	} else {
		// For non-lazy tables, also trigger a data refresh when individual filters change
		triggerDataRefresh();
	}
};

// Action handler methods
const handleActionClick = (action, rowData = null) => {
	try {
		if (typeof action.action === "function") {
			if (rowData) {
				// Row-specific action - pass row data
				action.action(rowData);
			} else {
				// Global action - no row data needed
				action.action();
			}
		}
	} catch (error) {
		console.error("Error executing action:", error);
	}
};

const toggleMenu = (event, action, rowData) => {
	const menuKey = `${action.label}-${rowData.id}`;
	const menu = menuRefs[menuKey];
	if (menu) {
		menu.toggle(event);
		activeMenuKey.value = menuKey;
	} else {
		console.log("Menu undefined for key:", menuKey);
	}
};

const buildMenuItems = (menuItems, rowData) => {
	return menuItems.map(item => ({
		...item,
		command: () => {
			if (typeof item.command === 'function') {
				item.command(rowData);
			}
		}
	}));
};

const handleSelectChange = (action, rowData, event) => {
	console.log("Action:", action);
	console.log("rowData:", rowData);
	console.log("event:", event);
	try {
		if (typeof action.action === "function") {
			if (rowData) {
				// Row-specific action - pass row data
				action.action(rowData, event.value);
			} else {
				// Global action - no row data needed
				action.action();
			}
		}
		if (action.resetComponentOnChange) {
			console.log("DEBUG: Resetting Select Component");
			event.originalEvent.target.value = null;
		}
	} catch (error) {
		console.error("Error executing action:", error);
	}
}

const handleGlobalAction = (action) => {
	handleActionClick(action);
};

const handleRowAction = (action, rowData) => {
	handleActionClick(action, rowData);
};

const handleSingleSelectionAction = (action) => {
	if (hasExactlyOneRowSelected.value) {
		const selectedRow = selectedRows.value[0];
		handleActionClick(action, selectedRow);
	}
};

// Unified handler for top-level actions (global and single selection)
const handleTopAction = (action) => {
	if (action.requiresSelection) {
		handleSingleSelectionAction(action);
	} else {
		handleGlobalAction(action);
	}
};

// Helper methods for action styling and behavior
const getActionSeverity = (action) => {
	if (action.requiresSelection) {
		return action.style || "info";
	}
	return action.style || "primary";
};

const getActionDisabled = (action) => {
	if (loading.value) return true;
	if (action.requiresSelection) {
		return !hasExactlyOneRowSelected.value;
	}
	return false;
};

const getActionClasses = (action) => {
	const classes = ["dt-action-btn"];
	if (action.requiresSelection) {
		classes.push("dt-action-btn-selection");
		if (!hasExactlyOneRowSelected.value) {
			classes.push("dt-action-btn-disabled");
		}
	} else {
		classes.push("dt-action-btn-global");
	}
	if (action.layout?.variant) {
		classes.push(`dt-action-btn-${action.layout.variant}`);
	}
	return classes;
};

const toggleRowDropdown = (event, rowData) => {
	// Placeholder for dropdown menu functionality
	// Could be implemented with PrimeVue OverlayPanel or Menu component
	console.log("Toggle dropdown for row:", rowData);
};

const handleBulkAction = (action, selectedRows) => {
	try {
		if (typeof action.action === "function") {
			// Bulk action - pass array of selected row data
			action.action(selectedRows);
		}
	} catch (error) {
		console.error("Error executing bulk action:", error);
	}
};

// Handle status button clicks
const handleStatusButtonClick = (column, rowData) => {
	try {
		if (column.onStatusClick && typeof column.onStatusClick === "function") {
			column.onStatusClick(rowData[column.fieldName], rowData);
		}
	} catch (error) {
		console.error("Error executing status button click:", error);
	}
};

// Handle link clicks
const handleLinkClick = (column, rowData) => {
	try {
		if (column.onLinkClick && typeof column.onLinkClick === "function") {
			column.onLinkClick(rowData[column.fieldName], rowData);
		}
	} catch (error) {
		console.error("Error executing link click:", error);
	}
};

const getBadgeColor = (status) => {
	switch (status?.toLowerCase()) {
		case "paid":
		case "completed":
		case "open":
		case "active":
			return "success";
		case "draft":
		case "in progress":
		case "pending":
			return "warn";
		case "not started":
		case "closed":
		case "cancelled":
			return "danger";
		default:
			return "info";
	}
};

const formatDate = (dateValue) => {
	if (!dateValue) return "";

	try {
		// Handle different date formats
		let date;
		if (typeof dateValue === "string") {
			date = new Date(dateValue);
		} else if (dateValue instanceof Date) {
			date = dateValue;
		} else {
			return "";
		}

		// Check if date is valid
		if (isNaN(date.getTime())) {
			return dateValue; // Return original value if can't parse
		}

		// Format as MM/DD/YYYY
		return date.toLocaleDateString("en-US");
	} catch (error) {
		console.error("Error formatting date:", error);
		return dateValue;
	}
};
console.log("DEBUG: - DataTable props.columns", props.columns);
console.log("DEBUG: - DataTable props.data", props.data);

// Expose control methods for parent components
defineExpose({
	// Loading controls
	startLoading: (message) => loadingStore.setComponentLoading(props.tableName, true, message),
	stopLoading: () => loadingStore.setComponentLoading(props.tableName, false),
	isLoading: () => loading.value,

	// Pagination controls (for lazy tables)
	goToPage: (page) => {
		if (props.lazy) {
			paginationStore.setPage(props.tableName, page);
			triggerLazyLoad();
		}
	},
	nextPage: () => {
		if (props.lazy) {
			paginationStore.nextPage(props.tableName);
			triggerLazyLoad();
		}
	},
	previousPage: () => {
		if (props.lazy) {
			paginationStore.previousPage(props.tableName);
			triggerLazyLoad();
		}
	},
	refresh: () => {
		if (props.lazy) {
			triggerLazyLoad();
		} else {
			triggerDataRefresh();
		}
	},

	// Get current state
	getCurrentPage: () => paginationStore.getTablePagination(props.tableName).page,
	getTotalPages: () => paginationStore.getTotalPages(props.tableName),
	getFilters: () => filtersStore.getTableFilters(props.tableName),
	getPaginationInfo: () => paginationStore.getPageInfo(props.tableName),
});
</script>
<style lang="css">
/* Modern DataTable Styling */

/* Filter Panel Styles */

.dt-filter-panel {
	background: var(--surface-card);
	border: 1px solid var(--surface-border);
	border-radius: 6px;
	margin-bottom: 0.5rem;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}


.dt-filter-header {
	padding: 0.5rem 0.75rem 0.25rem;
	border-bottom: 1px solid var(--surface-border);
}

.dt-filter-title {
	margin: 0;
	font-size: 0.75rem;
	font-weight: 600;
	color: var(--theme-text);
	display: flex;
	align-items: center;
	gap: 0.375rem;
}

.dt-filter-title i {
	color: var(--theme-primary);
}

.dt-filter-content {
	padding: 0.75rem;
}

.dt-filter-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
	gap: 0.5rem;
	margin-bottom: 0.5rem;
}

.dt-filter-field {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
}

.dt-filter-label {
	font-size: 0.75rem;
	font-weight: 500;
	color: var(--theme-text);
}


.dt-filter-input {
	border: 1px solid var(--surface-border);
	border-radius: 4px;
	padding: 0.375rem 0.5rem;
	font-size: 0.75rem;
	transition: border-color 0.2s ease;
	background: var(--surface-card);
}


.dt-filter-input:focus {
	border-color: var(--theme-primary);
	outline: none;
}

.dt-filter-actions {
	display: flex;
	gap: 0.5rem;
	align-items: center;
	flex-wrap: wrap;
}

.dt-btn-primary,
.dt-btn-secondary {
	border-radius: 4px;
	font-weight: 500;
	font-size: 0.75rem;
	padding: 0.375rem 0.75rem;
}


.dt-filter-status {
	margin-top: 0.5rem;
	padding: 0.375rem 0.5rem;
	background: var(--surface-hover);
	border-radius: 4px;
	font-size: 0.7rem;
	color: var(--theme-text-muted);
	display: flex;
	align-items: center;
	gap: 0.375rem;
}

/* Pagination Panel Styles */
.dt-pagination-panel {
	background: var(--surface-card);
	border: 1px solid var(--surface-border);
	border-radius: 6px;
	margin-bottom: 0.5rem;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.dt-pagination-content {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 0.5rem 0.75rem;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.dt-pagination-info {
	display: flex;
	align-items: center;
	gap: 0.375rem;
	color: var(--theme-text-muted);
	font-size: 0.75rem;
}

.dt-pagination-info i {
	color: var(--theme-primary);
	font-size: 0.75rem;
}

.dt-pagination-controls {
	display: flex;
	align-items: center;
	gap: 0.375rem;
}

.dt-pagination-label {
	font-size: 0.75rem;
	color: var(--theme-text);
	font-weight: 500;
}

.dt-pagination-select {
	border: 1px solid var(--surface-border);
	border-radius: 4px;
	padding: 0.25rem 0.5rem;
	font-size: 0.75rem;
	background: var(--surface-card);
	transition: border-color 0.2s ease;
}

.dt-pagination-select:focus {
	border-color: var(--theme-primary);
	outline: none;
}

/* Bulk Actions Panel Styles */
.dt-bulk-actions-panel {
	background: var(--theme-surface-alt);
	border: 1px solid var(--surface-border);
	border-radius: 6px;
	margin-bottom: 0.5rem;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
	animation: slideInBulk 0.2s ease-out;
}

@keyframes slideInBulk {
	from {
		opacity: 0;
		transform: translateY(-5px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.dt-bulk-actions-content {
	padding: 0.5rem 0.75rem;
}

.dt-bulk-actions-groups {
	display: flex;
	justify-content: space-between;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-bottom: 0.5rem;
}

.dt-bulk-btn {
	border-radius: 4px;
	font-weight: 500;
	font-size: 0.75rem;
	padding: 0.375rem 0.75rem;
}


.dt-bulk-actions-status {
	padding: 0.25rem 0.5rem;
	background: var(--surface-card);
	border-radius: 4px;
	font-size: 0.7rem;
	color: var(--theme-secondary);
	display: flex;
	align-items: center;
	gap: 0.375rem;
	font-weight: 500;
}

/* Global Actions Panel Styles */

.dt-global-actions-panel {
	background: var(--surface-card);
	border: 1px solid var(--surface-border);
	border-radius: 6px;
	margin-bottom: 0.5rem;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
	border-left: 3px solid var(--theme-primary);
}

.dt-global-actions-content {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 0.5rem 0.75rem;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.dt-action-group {
	display: flex;
	gap: 0.375rem;
	flex-wrap: wrap;
	align-items: center;
}

.dt-action-group-left {
	flex: 1;
	justify-content: flex-start;
}

.dt-action-group-center {
	justify-content: center;
}

.dt-action-group-right {
	justify-content: flex-end;
}

.dt-action-btn {
	border-radius: 4px;
	font-weight: 500;
	font-size: 0.75rem;
	padding: 0.375rem 0.75rem;
	transition: all 0.2s ease;
	position: relative;
}

.dt-action-btn:hover:not(:disabled) {
	transform: translateY(-1px);
	box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.dt-action-btn-global {
	/* Global action styling */
	position: relative;
}

.dt-action-btn-selection {
	/* Selection action styling */
	position: relative;
}

.dt-action-btn-disabled {
	opacity: 0.6;
	cursor: not-allowed;
}

.dt-action-btn-outlined {
	background: transparent;
	border: 1.5px solid currentColor;
}

.dt-action-btn-filled {
	border: none;
	color: white;
}


.dt-global-actions-status {
	padding: 0.375rem 0.75rem;
	background: var(--surface-hover);
	border-top: 1px solid var(--surface-border);
	font-size: 0.7rem;
	color: var(--theme-text-muted);
	display: flex;
	align-items: center;
	gap: 0.375rem;
}

/* Row Actions Styles */
.dt-actions-column {
	min-width: 160px;
}

.dt-row-actions {
	display: flex;
	gap: 0.375rem;
	align-items: center;
	justify-content: flex-start;
	flex-wrap: wrap;
}

.dt-row-actions-primary {
	display: flex;
	gap: 0.25rem;
}

.dt-row-actions-secondary {
	display: flex;
	gap: 0.25rem;
}

.dt-row-actions-dropdown {
	display: flex;
}

.dt-row-btn {
	border-radius: 6px;
	font-size: 0.8125rem;
	font-weight: 500;
	transition: all 0.2s ease;
}

.dt-row-btn:hover {
	transform: translateY(-1px);
}

.dt-row-btn-secondary {
	opacity: 0.8;
}

.dt-row-btn-secondary:hover {
	opacity: 1;
}

.dt-row-btn-dropdown {
	padding: 0.25rem;
	min-width: auto;
	width: 2rem;
	height: 2rem;
}

.dt-row-btn-icon-only {
	min-width: auto;
	width: 2.25rem;
	padding: 0.375rem;
}

.dt-row-btn-compact {
	padding: 0.25rem 0.5rem;
	font-size: 0.75rem;
}

/* Responsive Design */
@media (max-width: 768px) {
	.dt-filter-grid {
		grid-template-columns: 1fr;
	}

	.dt-pagination-content {
		flex-direction: column;
		align-items: stretch;
		text-align: center;
	}

	.dt-global-actions-content {
		flex-direction: column;
		align-items: stretch;
	}

	.dt-action-group {
		justify-content: center;
	}

	.dt-bulk-actions-groups {
		flex-direction: column;
		align-items: stretch;
	}
}

/* Animation utilities */
.dt-fade-in {
	animation: fadeIn 0.2s ease-out;
}

@keyframes fadeIn {
	from {
		opacity: 0;
		transform: translateY(5px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.dt-slide-in {
	animation: slideIn 0.2s ease-out;
}

@keyframes slideIn {
	from {
		opacity: 0;
		transform: translateX(-5px);
	}
	to {
		opacity: 1;
		transform: translateX(0);
	}
}

/* Status Button Styles */
.status-button {
	font-weight: 500;
	font-size: 0.8rem;
	border-radius: 4px;
	transition: all 0.2s ease;
	min-width: 100px;
	text-align: center;
}

.status-button:not(:disabled):hover {
	transform: translateY(-1px);
	box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.status-button:disabled {
	cursor: default;
	opacity: 0.8;
}

.status-button:disabled:hover {
	transform: none;
	box-shadow: none;
}

/* Link Styles */
.datatable-link {
	background: none;
	border: none;
	padding: 0;
	cursor: pointer;
	outline: none;
}

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

</style>
