<script lang="ts">
	import AssignColumnHeader from './AssignColumnHeader.svelte';
	import AssignServiceGroup from './AssignServiceGroup.svelte';
	import IconSpinner from '$lib/components/icons/IconSpinner.svelte';
	import type { SvelteSet } from 'svelte/reactivity';

	type EnrichedService = {
		id: string;
		date: string;
		status: string;
		notes: string | null;
		teamMembers: { pk: string }[];
		accountAddressId: string;
		accountName: string;
		addressName: string | null;
		address: string | null;
	};

	type ColumnType = 'unassigned' | 'readyToAssign' | 'assigned';

	interface Props {
		column: ColumnType;
		services: EnrichedService[];
		groupedServices: Map<string, EnrichedService[]>;
		expandedGroups: SvelteSet<string>;
		updatingServices: Set<string>;
		openTeamMemberDropdown: string | null;
		editingDateServiceId?: string | null;
		// Selection props
		selectedServices: SvelteSet<string>;
		isBulkOperating?: boolean;
		// For Ready to Assign bulk operations
		nonAdminTeamMembers?: { id: string; fullName: string }[];
		bulkSelectedTeamMember?: string | null;
		showBulkTeamMemberDropdown?: boolean;
		// Callbacks
		onToggleGroup: (groupKey: string) => void;
		getTeamMemberNames: (teamMembers: { pk: string }[]) => string[];
		getNonDispatchTeamMemberNames: (teamMembers: { pk: string }[]) => string[];
		getAvailableTeamMembers: (service: EnrichedService) => { pk: string; name: string }[];
		getStagedTeamMemberDetails: (serviceId: string) => { pk: string; name: string }[];
		hasStagedMembers: (serviceId: string) => boolean;
		onAddDispatch: (service: EnrichedService) => void;
		onRemoveDispatch: (service: EnrichedService) => void;
		onSubmitStaged: (service: EnrichedService) => void;
		onRemoveNonDispatch: (service: EnrichedService) => void;
		onStageTeamMember: (serviceId: string, memberPk: string) => void;
		onUnstageTeamMember: (serviceId: string, memberPk: string) => void;
		onToggleDropdown: (serviceId: string | null) => void;
		// Selection callbacks
		onToggleSelection: (serviceId: string) => void;
		onSelectAll: () => void;
		onClearSelection: () => void;
		onBulkAction: () => void;
		// For Ready to Assign
		onBulkTeamMemberSelect?: (memberPk: string) => void;
		onToggleBulkTeamMemberDropdown?: () => void;
		// Unassigned column specific
		onUpdateDate?: (service: EnrichedService, newDate: string) => void;
		onDeleteService?: (service: EnrichedService) => void;
		onStartEditDate?: (serviceId: string) => void;
		onCancelEditDate?: () => void;
	}

	let {
		column,
		services,
		groupedServices,
		expandedGroups,
		updatingServices,
		openTeamMemberDropdown,
		editingDateServiceId = null,
		selectedServices,
		isBulkOperating = false,
		nonAdminTeamMembers = [],
		bulkSelectedTeamMember = null,
		showBulkTeamMemberDropdown = false,
		onToggleGroup,
		getTeamMemberNames,
		getNonDispatchTeamMemberNames,
		getAvailableTeamMembers,
		getStagedTeamMemberDetails,
		hasStagedMembers,
		onAddDispatch,
		onRemoveDispatch,
		onSubmitStaged,
		onRemoveNonDispatch,
		onStageTeamMember,
		onUnstageTeamMember,
		onToggleDropdown,
		onToggleSelection,
		onSelectAll,
		onClearSelection,
		onBulkAction,
		onBulkTeamMemberSelect,
		onToggleBulkTeamMemberDropdown,
		onUpdateDate,
		onDeleteService,
		onStartEditDate,
		onCancelEditDate
	}: Props = $props();

	let hasSelection = $derived(selectedServices.size > 0);
	let allSelected = $derived(services.length > 0 && selectedServices.size === services.length);

	function getEmptyIcon(): string {
		switch (column) {
			case 'unassigned':
			case 'assigned':
				return 'M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z';
			case 'readyToAssign':
				return 'M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z';
		}
	}

	function getEmptyMessage(): string {
		switch (column) {
			case 'unassigned':
				return 'No unassigned services';
			case 'readyToAssign':
				return 'No services ready to assign';
			case 'assigned':
				return 'No assigned services';
		}
	}

	function getBulkActionLabel(): string {
		switch (column) {
			case 'unassigned':
				return 'Add Dispatch';
			case 'readyToAssign':
				return 'Assign';
			case 'assigned':
				return 'Remove Team';
		}
	}

	function getBulkActionDisabled(): boolean {
		if (isBulkOperating) return true;
		if (selectedServices.size === 0) return true;
		return column === 'readyToAssign' && !bulkSelectedTeamMember;
	}

	function getSelectedTeamMemberName(): string {
		if (!bulkSelectedTeamMember) return 'Select team member...';
		const member = nonAdminTeamMembers.find((m) => {
			// Extract pk from global id
			const parts = atob(m.id).split(':');
			return parts[1] === bulkSelectedTeamMember;
		});
		return member?.fullName ?? 'Unknown';
	}
</script>

<div class="flex w-1/3 flex-col overflow-hidden rounded-xl bg-theme-card shadow-md">
	<AssignColumnHeader {column} count={services.length} />

	<!-- Bulk Action Bar -->
	{#if services.length > 0}
		<div class="border-b border-theme bg-theme-card px-3 py-2">
			<div class="flex items-center justify-between gap-2">
				<!-- Select All / Clear -->
				<div class="flex items-center gap-2">
					<button
						onclick={() => (allSelected ? onClearSelection() : onSelectAll())}
						class="flex items-center gap-1.5 rounded interactive px-2 py-1 text-xs font-medium {hasSelection
							? 'text-primary-600 dark:text-primary-400'
							: 'text-theme-muted'}"
					>
						<svg
							class="h-4 w-4"
							style="fill: none"
							viewBox="0 0 24 24"
							stroke="currentColor"
							stroke-width="2"
						>
							{#if allSelected}
								<path
									stroke-linecap="round"
									stroke-linejoin="round"
									d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
								/>
							{:else if hasSelection}
								<path
									stroke-linecap="round"
									stroke-linejoin="round"
									d="M15 12H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"
								/>
							{:else}
								<circle cx="12" cy="12" r="9" />
							{/if}
						</svg>
						{#if hasSelection}
							<span>{selectedServices.size} selected</span>
						{:else}
							<span>Select all</span>
						{/if}
					</button>
					{#if hasSelection}
						<button onclick={onClearSelection} class="text-xs text-theme-muted hover:text-theme">
							Clear
						</button>
					{/if}
				</div>

				<!-- Bulk Action -->
				{#if hasSelection}
					<div class="flex items-center gap-2">
						{#if column === 'readyToAssign'}
							<!-- Team member dropdown for bulk assignment -->
							<div class="relative">
								<button
									onclick={(e) => {
										e.stopPropagation();
										onToggleBulkTeamMemberDropdown?.();
									}}
									class="flex items-center gap-1 rounded border border-theme interactive bg-theme px-2 py-1 text-xs font-medium text-theme"
								>
									<span class="max-w-[100px] truncate">{getSelectedTeamMemberName()}</span>
									<svg class="h-3 w-3" style="fill: none" viewBox="0 0 24 24" stroke="currentColor">
										<path
											stroke-linecap="round"
											stroke-linejoin="round"
											stroke-width="2"
											d="M19 9l-7 7-7-7"
										/>
									</svg>
								</button>
								{#if showBulkTeamMemberDropdown}
									<!-- svelte-ignore a11y_click_events_have_key_events -->
									<div
										role="menu"
										tabindex="-1"
										onclick={(e) => e.stopPropagation()}
										class="absolute top-full right-0 z-30 mt-1 max-h-48 w-48 overflow-y-auto rounded-lg border border-theme bg-theme-card py-1 shadow-lg"
									>
										{#each nonAdminTeamMembers as member (member.id)}
											{@const memberPk = atob(member.id).split(':')[1]}
											<button
												onclick={() => onBulkTeamMemberSelect?.(memberPk)}
												class="block w-full px-3 py-2 text-left text-sm text-theme hover:bg-black/5 dark:hover:bg-white/10 {bulkSelectedTeamMember ===
												memberPk
													? 'bg-primary-50 dark:bg-primary-900/20'
													: ''}"
											>
												{member.fullName}
											</button>
										{/each}
									</div>
								{/if}
							</div>
						{/if}
						<button
							onclick={onBulkAction}
							disabled={getBulkActionDisabled()}
							class="flex items-center gap-1 rounded bg-primary-600 px-2 py-1 text-xs font-medium text-white transition-colors hover:bg-primary-700 disabled:cursor-not-allowed disabled:opacity-50"
						>
							{#if isBulkOperating}
								<IconSpinner class="h-3 w-3" />
							{:else}
								<svg class="h-3 w-3" style="fill: none" viewBox="0 0 24 24" stroke="currentColor">
									<path
										stroke-linecap="round"
										stroke-linejoin="round"
										stroke-width="2"
										d="M9 5l7 7-7 7"
									/>
								</svg>
							{/if}
							{getBulkActionLabel()}
						</button>
					</div>
				{/if}
			</div>
		</div>
	{/if}

	<div class="flex-1 space-y-2 overflow-y-auto bg-theme p-4">
		{#each [...groupedServices.entries()] as [groupKey, groupServices] (groupKey)}
			<AssignServiceGroup
				{groupKey}
				services={groupServices}
				{column}
				isExpanded={expandedGroups.has(groupKey)}
				{updatingServices}
				{openTeamMemberDropdown}
				{editingDateServiceId}
				{selectedServices}
				onToggle={() => onToggleGroup(groupKey)}
				{getTeamMemberNames}
				{getNonDispatchTeamMemberNames}
				{getAvailableTeamMembers}
				{getStagedTeamMemberDetails}
				{hasStagedMembers}
				{onAddDispatch}
				{onRemoveDispatch}
				{onSubmitStaged}
				{onRemoveNonDispatch}
				{onStageTeamMember}
				{onUnstageTeamMember}
				{onToggleDropdown}
				{onToggleSelection}
				{onUpdateDate}
				{onDeleteService}
				{onStartEditDate}
				{onCancelEditDate}
			/>
		{/each}
		{#if services.length === 0}
			<div class="py-12 text-center text-theme-muted">
				<svg
					class="mx-auto mb-3 h-12 w-12"
					style="fill: none"
					viewBox="0 0 24 24"
					stroke="currentColor"
				>
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="1.5"
						d={getEmptyIcon()}
					/>
				</svg>
				{getEmptyMessage()}
			</div>
		{/if}
	</div>
</div>
