<script lang="ts">
	import { fade, scale } from 'svelte/transition';
	import { AdminProjectsStore, UpdateReportStore } from '$houdini';
	import { SvelteSet } from 'svelte/reactivity';
	import type { GetReport$result } from '$houdini';

	type Report = NonNullable<GetReport$result['report']>;

	interface AccountInfo {
		accountName: string;
		addressName?: string | null;
	}

	interface CustomerInfo {
		customerName: string;
	}

	interface Props {
		open: boolean;
		report: Report;
		teamMemberId: string;
		accountLookup: Map<string, AccountInfo>;
		customerLookup: Map<string, CustomerInfo>;
		onSuccess: () => void;
	}

	let {
		open = $bindable(false),
		report,
		teamMemberId,
		accountLookup,
		customerLookup,
		onSuccess
	}: Props = $props();

	let loading = $state(false);
	let saving = $state(false);
	let error = $state('');
	let availableProjects = $state<
		{
			id: string;
			name: string;
			date: string;
			accountAddressId: string | null;
			customerId: string | null;
		}[]
	>([]);
	let selectedProjectIds = new SvelteSet<string>();

	const projectsStore = new AdminProjectsStore();
	const updateStore = new UpdateReportStore();

	// Get already included project IDs
	let includedProjectIds = $derived(new Set(report.projects.map((p) => p.id)));

	// Load available projects when modal opens
	$effect(() => {
		if (open) {
			loadAvailableProjects();
			selectedProjectIds.clear();
		}
	});

	async function loadAvailableProjects() {
		loading = true;
		error = '';

		// Extract year-month from report date (YYYY-MM)
		const [year, month] = report.date.split('-');
		const startOfMonth = `${year}-${month}-01`;
		const endOfMonth = new Date(parseInt(year), parseInt(month), 0).toISOString().split('T')[0];

		try {
			const result = await projectsStore.fetch({
				variables: {
					filters: {
						status: { exact: 'COMPLETED' },
						date: { gte: startOfMonth, lte: endOfMonth }
					}
				}
			});

			// Filter to only projects assigned to this team member and not already included
			availableProjects = (result.data?.projects ?? []).filter((project) => {
				const isAssigned = project.teamMembers?.some((m) => m.pk === teamMemberId);
				const notIncluded = !includedProjectIds.has(project.id);
				return isAssigned && notIncluded;
			});
		} catch (err) {
			console.error('Failed to load projects:', err);
			error = 'Failed to load projects';
		} finally {
			loading = false;
		}
	}

	function formatItemDate(dateStr: string): string {
		return new Date(dateStr + 'T00:00:00').toLocaleDateString('en-US', {
			month: 'short',
			day: 'numeric'
		});
	}

	function getProjectDisplayName(project: {
		date: string;
		name: string;
		accountAddressId: string | null;
		customerId: string | null;
	}): string {
		const dateStr = formatItemDate(project.date);

		let entityName = 'Unknown';
		if (project.accountAddressId) {
			const accountInfo = accountLookup.get(project.accountAddressId);
			if (accountInfo) {
				entityName = accountInfo.accountName;
			}
		} else if (project.customerId) {
			const customerInfo = customerLookup.get(project.customerId);
			if (customerInfo) {
				entityName = customerInfo.customerName;
			}
		}

		return `${dateStr}, ${entityName} - ${project.name}`;
	}

	function toggleProject(projectId: string) {
		if (selectedProjectIds.has(projectId)) {
			selectedProjectIds.delete(projectId);
		} else {
			selectedProjectIds.add(projectId);
		}
	}

	function selectAll() {
		for (const project of availableProjects) {
			selectedProjectIds.add(project.id);
		}
	}

	function selectNone() {
		selectedProjectIds.clear();
	}

	async function handleSave() {
		if (selectedProjectIds.size === 0) return;

		saving = true;
		error = '';

		try {
			// Combine existing project IDs with newly selected ones
			const existingIds = report.projects.map((p) => p.id);
			const newIds = [...selectedProjectIds];
			const allIds = [...existingIds, ...newIds];

			await updateStore.mutate({
				input: {
					id: report.id,
					projectIds: allIds
				}
			});

			open = false;
			onSuccess();
		} catch (err) {
			console.error('Failed to add projects:', err);
			error = 'Failed to add projects';
		} finally {
			saving = false;
		}
	}

	function handleClose() {
		open = false;
	}

	function handleBackdropClick(e: MouseEvent) {
		if (e.target === e.currentTarget) {
			handleClose();
		}
	}
</script>

{#if open}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div
		class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4"
		transition:fade={{ duration: 150 }}
		onmousedown={handleBackdropClick}
		onkeydown={(e) => e.key === 'Escape' && handleClose()}
	>
		<div
			class="max-h-[90vh] w-full max-w-lg overflow-hidden rounded-xl bg-theme-card shadow-xl"
			transition:scale={{ duration: 150, start: 0.95 }}
		>
			<!-- Header -->
			<div class="border-b border-theme px-6 py-4">
				<h2 class="text-lg font-semibold text-theme">Add Projects</h2>
				<p class="mt-1 text-sm text-theme-muted">
					Select completed projects to add to this report.
				</p>
			</div>

			<!-- Content -->
			<div class="max-h-[60vh] overflow-y-auto p-6">
				{#if loading}
					<div class="flex items-center justify-center py-8">
						<svg
							class="h-8 w-8 animate-spin text-accent-500"
							style="fill: none"
							viewBox="0 0 24 24"
						>
							<circle
								class="opacity-25"
								cx="12"
								cy="12"
								r="10"
								stroke="currentColor"
								stroke-width="4"
							></circle>
							<path
								class="opacity-75"
								fill="currentColor"
								d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
							></path>
						</svg>
					</div>
				{:else if availableProjects.length === 0}
					<p class="py-8 text-center text-sm text-theme-muted italic">
						No additional projects available for this team member in this month.
					</p>
				{:else}
					<!-- Select All / None -->
					<div class="mb-4 flex items-center gap-4">
						<button
							onclick={selectAll}
							class="text-sm font-medium text-accent-600 hover:underline dark:text-accent-400"
						>
							Select All
						</button>
						<button
							onclick={selectNone}
							class="text-sm font-medium text-theme-muted hover:underline"
						>
							Select None
						</button>
						<span class="ml-auto text-sm text-theme-muted">
							{selectedProjectIds.size} selected
						</span>
					</div>

					<div class="space-y-2">
						{#each availableProjects as project (project.id)}
							<label
								class="flex cursor-pointer items-center gap-3 rounded-lg border border-theme interactive p-3"
							>
								<input
									type="checkbox"
									checked={selectedProjectIds.has(project.id)}
									onchange={() => toggleProject(project.id)}
									class="border-theme-muted h-4 w-4 rounded text-primary-500 focus:ring-primary-500"
								/>
								<span class="flex-1 text-sm text-theme">
									{getProjectDisplayName(project)}
								</span>
							</label>
						{/each}
					</div>
				{/if}

				{#if error}
					<div class="mt-4 rounded-lg bg-error-500/10 p-3">
						<p class="text-sm text-error-600 dark:text-error-400">{error}</p>
					</div>
				{/if}
			</div>

			<!-- Footer -->
			<div class="flex items-center justify-end gap-3 border-t border-theme px-6 py-4">
				<button onclick={handleClose} class="btn-ghost" disabled={saving}> Cancel </button>
				<button
					onclick={handleSave}
					class="btn-primary"
					disabled={saving || selectedProjectIds.size === 0}
				>
					{#if saving}
						Adding...
					{:else}
						Add {selectedProjectIds.size} Project{selectedProjectIds.size !== 1 ? 's' : ''}
					{/if}
				</button>
			</div>
		</div>
	</div>
{/if}
