<script lang="ts">
	import SelectionModal from '$lib/components/shared/SelectionModal.svelte';
	import { UpdateInvoiceStore } from '$houdini';
	import { SvelteSet } from 'svelte/reactivity';
	import type { GetInvoice$result, Accounts$result } from '$houdini';

	type Invoice = NonNullable<GetInvoice$result['invoice']>;
	type Account = Accounts$result['accounts'][number];

	interface Props {
		open: boolean;
		invoice: Invoice;
		accounts: Account[];
		onSuccess: () => void;
	}

	let { open = $bindable(false), invoice, accounts, onSuccess }: Props = $props();

	let saving = $state(false);
	let error = $state('');
	let selectedRevenueIds = new SvelteSet<string>();

	const updateStore = new UpdateInvoiceStore();

	// Get customer UUID from the invoice
	let customerUuid = $derived(invoice.customerId);

	// Get already included revenue IDs
	let includedRevenueIds = $derived(new Set(invoice.revenues.map((r) => r.id)));

	// Get accounts belonging to this customer with their revenues
	let customerAccounts = $derived(accounts.filter((a) => a.customerId === customerUuid));

	// Flatten all revenues from customer accounts that aren't already included
	let availableRevenues = $derived(
		customerAccounts.flatMap((account) =>
			(account.revenues ?? [])
				.filter((r) => !includedRevenueIds.has(r.id))
				.map((r) => ({
					...r,
					accountId: account.id,
					accountName: account.name
				}))
		)
	);

	// Reset selection when modal opens
	$effect(() => {
		if (open) {
			selectedRevenueIds.clear();
		}
	});

	function formatCurrency(value: string | number): string {
		const num = typeof value === 'string' ? parseFloat(value) : value;
		return new Intl.NumberFormat('en-US', {
			style: 'currency',
			currency: 'USD'
		}).format(num);
	}

	function formatDate(dateStr: string | null): string {
		if (!dateStr) return '';
		return new Date(dateStr + 'T00:00:00').toLocaleDateString('en-US', {
			month: 'short',
			day: 'numeric',
			year: 'numeric'
		});
	}

	function toggleRevenue(revenueId: string) {
		if (selectedRevenueIds.has(revenueId)) {
			selectedRevenueIds.delete(revenueId);
		} else {
			selectedRevenueIds.add(revenueId);
		}
	}

	function selectAll() {
		for (const revenue of availableRevenues) {
			selectedRevenueIds.add(revenue.id);
		}
	}

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

	// Calculate total of selected revenues
	let selectedTotal = $derived(
		availableRevenues
			.filter((r) => selectedRevenueIds.has(r.id))
			.reduce((sum, r) => sum + parseFloat(String(r.amount)), 0)
	);

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

		saving = true;
		error = '';

		try {
			const existingIds = invoice.revenues.map((r) => r.id);
			const newIds = [...selectedRevenueIds];
			const allIds = [...existingIds, ...newIds];

			await updateStore.mutate({
				input: {
					id: invoice.id,
					revenueIds: allIds
				}
			});

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

	function handleClose() {
		open = false;
	}
</script>

<SelectionModal
	bind:open
	title="Add Revenues"
	subtitle="Select account revenues to add to this invoice."
	itemName="Revenue"
	{saving}
	{error}
	selectedCount={selectedRevenueIds.size}
	hasItems={availableRevenues.length > 0}
	emptyMessage="No additional revenues available for this customer's accounts."
	showTotal={true}
	{selectedTotal}
	colorScheme="secondary"
	onSave={handleSave}
	onClose={handleClose}
	{selectAll}
	{selectNone}
>
	{#each availableRevenues as revenue (revenue.id)}
		<label
			class="flex cursor-pointer items-center gap-3 rounded-lg border border-theme interactive p-3"
		>
			<input
				type="checkbox"
				checked={selectedRevenueIds.has(revenue.id)}
				onchange={() => toggleRevenue(revenue.id)}
				class="checkbox-base"
			/>
			<span class="min-w-0 flex-1">
				<span class="block text-sm font-medium text-theme">{revenue.accountName}</span>
				<span class="block text-xs text-theme-muted">
					{formatDate(revenue.startDate)}
					{#if revenue.endDate}
						- {formatDate(revenue.endDate)}
					{:else}
						- Ongoing
					{/if}
				</span>
			</span>
			<span class="text-sm font-semibold text-secondary-600 dark:text-secondary-400">
				{formatCurrency(revenue.amount)}
			</span>
		</label>
	{/each}
</SelectionModal>
