<script lang="ts">
	import { authStore } from '$lib/stores/auth.svelte';
	import { toast } from 'svelte-sonner';
	import * as Card from '$lib/components/ui/card';
	import { Input } from '$lib/components/ui/input';
	import { Button } from '$lib/components/ui/button';
	import { Skeleton } from '$lib/components/ui/skeleton';
	import { formatUserName } from '$lib/utils/nameDisplay';

	interface Props {
		openUserModal: (userId: string) => void;
	}

	const { openUserModal }: Props = $props();

	type UserListItem = {
		id: string;
		fullName: string;
		email?: string;
		phone?: string;
		previousFirstName?: string | null;
		previousLastName?: string | null;
	};

	type UserListResponse = {
		users: UserListItem[];
		total: number;
		page: number;
		perPage: number;
		totalPages: number;
		next_cursor?: string | null;
	};

	let userQuery = $state('');
	let users = $state<UserListItem[]>([]);
	let totalUsers = $state(0);
	// Cursor-based pagination: cursors[i] = cursor to use when loading page i+1
	// cursors[0] is always '' (empty cursor = first page)
	let cursors = $state<string[]>(['']);
	let currentPage = $state(1);
	let totalPages = $state(1);
	let nextCursor = $state<string | null>(null);
	let loadingSearch = $state(false);
	let initialLoad = $state(true);

	async function fetchUsers(pageIdx: number = 0, search: string = '') {
		loadingSearch = true;

		try {
			const params = new URLSearchParams({
				per_page: '4'
			});
			const cursor = cursors[pageIdx];
			if (cursor) {
				params.set('cursor', cursor);
			}

			if (search.trim()) {
				params.append('q', search.trim());
			}

			const response = await fetch(`/api/admin/users?${params}`, {
				method: 'GET',
				headers: {
					'Content-Type': 'application/json',
					Authorization: `Bearer ${authStore.currentToken}`
				}
			});

			if (response.ok) {
				const data: UserListResponse = await response.json();

				if (!data.users || data.users.length === 0) {
					users = [];
					totalUsers = 0;
					totalPages = 1;
					currentPage = 1;
					cursors = [''];
					nextCursor = null;
					loadingSearch = false;
					initialLoad = false;
					return;
				}

				users = data.users || [];
				totalUsers = data.total;
				totalPages = data.totalPages;
				currentPage = pageIdx + 1;
				nextCursor = data.next_cursor ?? null;

				// Pre-store cursor for the next page so we can go forward
				if (nextCursor && cursors.length <= pageIdx + 1) {
					cursors = [...cursors, nextCursor];
				}
			} else {
				const text = await response.text();
				toast.error('Failed to load users: ' + text);
			}
		} catch (err) {
			console.error('Error fetching users:', err);
			toast.error('Network error loading users');
		} finally {
			loadingSearch = false;
			initialLoad = false;
		}
	}

	function searchUsers() {
		cursors = [''];
		nextCursor = null;
		currentPage = 1;
		fetchUsers(0, userQuery);
	}

	function nextPage() {
		if (!nextCursor || currentPage >= totalPages) return;
		// currentPage is 1-indexed; next page index = currentPage
		fetchUsers(currentPage, userQuery);
	}

	function previousPage() {
		if (currentPage <= 1) return;
		// currentPage is 1-indexed; previous page index = currentPage - 2
		fetchUsers(currentPage - 2, userQuery);
	}

	// Load initial users on mount (guarded to run once)
	$effect(() => {
		if (initialLoad) {
			fetchUsers(0);
		}
	});
</script>

<Card.Root class="h-full">
	<Card.Header>
		<div class="flex items-start justify-between">
			<div>
				<Card.Title class="flex items-center gap-2">
					<svg
						xmlns="http://www.w3.org/2000/svg"
						class="h-5 w-5"
						viewBox="0 0 24 24"
						fill="none"
						stroke="currentColor"
						stroke-width="2"
					>
						<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
						<circle cx="9" cy="7" r="4" />
						<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
						<path d="M16 3.13a4 4 0 0 1 0 7.75" />
					</svg>
					Users
				</Card.Title>
				<Card.Description>Search and manage user details.</Card.Description>
			</div>

			<div class="rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium">
				<span class="text-xs font-semibold">{totalUsers}</span>
			</div>
		</div>
	</Card.Header>
	<Card.Content class="space-y-4">
		<div>
			<div class="flex gap-2">
				<Input
					placeholder="Name, email or phone"
					bind:value={userQuery}
					onkeyup={(e) => {
						if ((e as KeyboardEvent).key === 'Enter') searchUsers();
					}}
				/>
				<Button onclick={searchUsers} disabled={loadingSearch}>
					{loadingSearch ? 'Searching...' : 'Search'}
				</Button>
			</div>

			<div class="mt-3 max-h-60 space-y-2 overflow-y-auto">
				{#if initialLoad}
					{#each Array(3) as _, i (i)}
						<div class="rounded bg-gray-50 p-2">
							<Skeleton class="mb-1 h-4 w-32" />
							<Skeleton class="h-3 w-48" />
						</div>
					{/each}
				{:else if users.length === 0}
					<div class="py-8 text-center text-sm text-gray-500">
						{userQuery ? 'No users found matching your search.' : 'No users found.'}
					</div>
				{:else}
					<div class="relative {loadingSearch ? 'opacity-60' : ''}">
						{#each users as user (user.id)}
							<div class="flex items-center justify-between rounded bg-gray-50 p-2">
								<div>
									<div class="font-medium">
										{formatUserName(user.fullName, user.previousFirstName, user.previousLastName)}
									</div>
									<div class="text-xs text-gray-500">
										{user.email || '—'} • {user.phone || '—'}
									</div>
								</div>
								<Button variant="outline" onclick={() => openUserModal(user.id)}>View</Button>
							</div>
						{/each}
					</div>
				{/if}
			</div>

			{#if !initialLoad && totalPages > 1}
				<div class="mt-3 flex items-center justify-between border-t pt-3 text-sm">
					<Button
						variant="outline"
						size="sm"
						onclick={previousPage}
						disabled={currentPage === 1 || loadingSearch}
					>
						Previous
					</Button>
					<span class="text-xs text-gray-600">
						Page {currentPage} of {totalPages}
					</span>
					<Button
						variant="outline"
						size="sm"
						onclick={nextPage}
						disabled={currentPage === totalPages || loadingSearch}
					>
						Next
					</Button>
				</div>
			{/if}
		</div>
	</Card.Content>
</Card.Root>
