<script lang="ts">
	import type { PageData } from './$types';
	import { goto, invalidateAll } from '$app/navigation';
	import { SvelteMap, SvelteSet } from 'svelte/reactivity';
	import { client } from '$lib/graphql/client';
	import { ContentContainer } from '$lib/components/layout';
	import { PageHeader, SectionHeader } from '$lib/components/admin';
	import { IconTrash, IconPlus } from '$lib/components/icons';
	import { FormDrawer } from '$lib/components/drawers';
	import { DeleteModal } from '$lib/components/modals';
	import { ServiceForm, CalendarEventForm } from '$lib/components/forms';
	import {
		SessionContent,
		StartSessionButton,
		type ExtendedServiceTask,
		type ServiceArea,
		type ServiceAreaWithCompletions,
		type ServiceAreaWithTasks
	} from '$lib/components/session';
	import {
		DELETE_SERVICE,
		ASSIGN_SERVICE_TEAM_MEMBER,
		REMOVE_SERVICE_TEAM_MEMBER
	} from '$lib/graphql/mutations/service';
	import { LINK_CALENDAR_EVENT_TO_SERVICE } from '$lib/graphql/mutations/calendar';
	import {
		OPEN_SERVICE_SESSION,
		CLOSE_SERVICE_SESSION,
		REVERT_SERVICE_SESSION,
		ADD_SERVICE_TASK_COMPLETION,
		REMOVE_SERVICE_TASK_COMPLETION,
		CREATE_SERVICE_SESSION_NOTE,
		UPDATE_SERVICE_SESSION_NOTE,
		DELETE_SERVICE_SESSION_NOTE,
		UPLOAD_SERVICE_SESSION_IMAGE,
		UPDATE_SERVICE_SESSION_IMAGE,
		DELETE_SERVICE_SESSION_IMAGE,
		UPLOAD_SERVICE_SESSION_VIDEO,
		UPDATE_SERVICE_SESSION_VIDEO,
		DELETE_SERVICE_SESSION_VIDEO
	} from '$lib/graphql/mutations/session';
	import type { WorkStatus } from '$lib/graphql/queries/services';
	import type { ServiceSession } from '$lib/graphql/queries/session';
	import { config } from '$lib/config';

	let { data }: { data: PageData } = $props();

	let service = $derived(data.service);

	// Get dispatch profile for dispatch functionality
	let dispatchProfile = $derived(
		(data.teamProfiles ?? []).find((p) => p.id === config.dispatch.profileId) ?? null
	);

	// Get the dispatch assignment (dispatch account team member entry)
	let dispatchAssignment = $derived(
		service.teamMembers.find((m) => m.teamProfileId === config.dispatch.profileId) ?? null
	);

	// Filter out dispatch account from team members display
	let teamMembers = $derived(
		service.teamMembers.filter((m) => m.teamProfileId !== config.dispatch.profileId)
	);

	let isDispatched = $derived(!!dispatchAssignment);

	let isAssigned = $derived(teamMembers.length > 0);

	function getStatusBadgeClass(status: WorkStatus): string {
		switch (status) {
			case 'SCHEDULED':
				return 'bg-accent2-100 text-accent2-800 dark:bg-accent2-900/30 dark:text-accent2-400';
			case 'IN_PROGRESS':
				return 'bg-accent-100 text-accent-800 dark:bg-accent-900/30 dark:text-accent-400';
			case 'COMPLETED':
				return 'bg-primary-100 text-primary-800 dark:bg-primary-900/30 dark:text-primary-400';
			case 'CANCELLED':
				return 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400';
			default:
				return 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300';
		}
	}

	function formatStatusLabel(status: WorkStatus): string {
		switch (status) {
			case 'IN_PROGRESS':
				return 'In Progress';
			default:
				return status.charAt(0) + status.slice(1).toLowerCase();
		}
	}

	function formatDate(dateStr: string): string {
		const date = new Date(dateStr + 'T00:00:00');
		return date.toLocaleDateString('en-US', {
			weekday: 'long',
			year: 'numeric',
			month: 'long',
			day: 'numeric'
		});
	}

	function formatAddress(address: {
		streetAddress: string;
		city: string;
		state: string;
		zipCode: string;
	}): string {
		return `${address.streetAddress}, ${address.city}, ${address.state} ${address.zipCode}`;
	}

	function formatCurrency(amount: string): string {
		return new Intl.NumberFormat('en-US', {
			style: 'currency',
			currency: 'USD',
			minimumFractionDigits: 2,
			maximumFractionDigits: 2
		}).format(parseFloat(amount));
	}

	// Get active labor rate from account address
	let activeLabor = $derived(service.accountAddress?.labor?.find((l) => l.isActive) ?? null);

	// Get month from service date for back navigation
	let backMonth = $derived(() => {
		const [year, month] = service.date.split('-');
		return `${year}-${month}`;
	});

	// Drawer state
	let drawerOpen = $state(false);
	let drawerMode = $state<'service' | null>(null);

	// Delete modal state
	let deleteModalOpen = $state(false);
	let deleteTarget = $state<{
		type: 'service' | 'team_member';
		id: string;
		name: string;
	} | null>(null);
	let deleteLoading = $state(false);

	// Calendar event drawer state
	let calendarDrawerOpen = $state(false);

	// Team profiles for assignment (would need a query to fetch available team members)
	let availableTeamProfiles = $derived(data.teamProfiles ?? []);

	// Team member assignment menu
	let assignMenuOpen = $state(false);
	let assignLoading = $state(false);
	let selectedTeamMembers = new SvelteSet<string>();

	// ==================== SESSION STATE ====================

	// Session data from server (can be active or closed)
	let session = $derived(data.session as ServiceSession | null);
	let scope = $derived(service.accountAddress?.activeScope ?? null);

	// Session loading states
	let sessionLoading = $state(false);
	let isClosingSession = $state(false);
	let isRevertingSession = $state(false);
	let submittingTaskId = $state<string | null>(null);
	let removingTaskId = $state<string | null>(null);

	// Convert scope areas to session format
	const sessionAreas = $derived.by<ServiceArea[]>(() => {
		if (!scope) return [];
		return scope.areas.map((area) => ({
			id: area.id,
			name: area.name,
			description: null,
			order: area.order,
			tasks: area.tasks
		}));
	});

	// Flatten tasks with area context
	const allTasks = $derived.by<ExtendedServiceTask[]>(() => {
		if (!scope) return [];
		return scope.areas.flatMap((area) =>
			area.tasks.map((task) => ({
				...task,
				uuid: task.id,
				areaId: area.id,
				areaName: area.name
			}))
		);
	});

	// Task selection state
	let selectedTaskIds = new SvelteSet<string>();
	const completedTaskIds = $derived.by(() => {
		const ids = new SvelteSet<string>();
		if (session) {
			for (const completion of session.completedTasks) {
				ids.add(completion.taskId);
			}
		}
		return ids;
	});

	// Group completed tasks by area
	const completedTasksByArea = $derived.by<ServiceAreaWithCompletions[]>(() => {
		if (!session || !scope) return [];
		const grouped = new SvelteMap<string, ServiceAreaWithCompletions>();

		for (const completion of session.completedTasks) {
			const task = allTasks.find((t) => t.id === completion.taskId);
			if (!task) continue;

			const area = scope.areas.find((a) => a.id === task.areaId);
			if (!area) continue;

			if (!grouped.has(area.id)) {
				grouped.set(area.id, {
					area: {
						id: area.id,
						name: area.name,
						description: null,
						order: area.order,
						tasks: area.tasks
					},
					completions: []
				});
			}
			grouped.get(area.id)!.completions.push(completion);
		}

		return Array.from(grouped.values()).sort((a, b) => a.area.order - b.area.order);
	});

	// Group selected tasks (ready to submit) by area
	const readyToSubmitByArea = $derived.by<ServiceAreaWithTasks[]>(() => {
		const grouped = new SvelteMap<string, ServiceAreaWithTasks>();

		for (const taskId of selectedTaskIds) {
			const task = allTasks.find((t) => t.id === taskId);
			if (!task) continue;

			const area = scope?.areas.find((a) => a.id === task.areaId);
			if (!area) continue;

			if (!grouped.has(area.id)) {
				grouped.set(area.id, {
					area: {
						id: area.id,
						name: area.name,
						description: null,
						order: area.order,
						tasks: area.tasks
					},
					tasks: []
				});
			}
			grouped.get(area.id)!.tasks.push(task);
		}

		return Array.from(grouped.values()).sort((a, b) => a.area.order - b.area.order);
	});

	// Count of available tasks (not selected, not completed)
	const availableTasksCount = $derived(
		allTasks.filter((t) => !selectedTaskIds.has(t.id) && !completedTaskIds.has(t.id)).length
	);

	// Can start session when service is SCHEDULED and has team members assigned
	const canStartSession = $derived(service.status === 'SCHEDULED' && isAssigned && !session);

	// Session helpers
	function getTeamMemberName(id: string | null | undefined): string {
		if (!id) return 'Unknown';
		const profile = data.teamProfiles?.find((p) => p.id === id);
		return profile?.fullName ?? 'Unknown';
	}

	// ==================== SESSION HANDLERS ====================

	async function handleStartSession() {
		sessionLoading = true;
		try {
			await client.mutate({
				mutation: OPEN_SERVICE_SESSION,
				variables: { input: { serviceId: service.id } }
			});
			await invalidateAll();
		} catch (err) {
			console.error('Failed to start session:', err);
		} finally {
			sessionLoading = false;
		}
	}

	async function handleCloseSession() {
		if (!session) return;
		isClosingSession = true;
		try {
			const taskIds = Array.from(completedTaskIds);
			await client.mutate({
				mutation: CLOSE_SERVICE_SESSION,
				variables: { input: { serviceId: service.id, taskIds } }
			});
			await invalidateAll();
		} catch (err) {
			console.error('Failed to close session:', err);
		} finally {
			isClosingSession = false;
		}
	}

	async function handleRevertSession() {
		isRevertingSession = true;
		try {
			await client.mutate({
				mutation: REVERT_SERVICE_SESSION,
				variables: { serviceId: service.id }
			});
			await invalidateAll();
		} catch (err) {
			console.error('Failed to revert session:', err);
		} finally {
			isRevertingSession = false;
		}
	}

	function handleToggleTask(taskId: string) {
		if (selectedTaskIds.has(taskId)) {
			selectedTaskIds.delete(taskId);
		} else {
			selectedTaskIds.add(taskId);
		}
	}

	async function handleSubmitTask(taskId: string) {
		submittingTaskId = taskId;
		try {
			await client.mutate({
				mutation: ADD_SERVICE_TASK_COMPLETION,
				variables: { serviceId: service.id, taskId }
			});
			selectedTaskIds.delete(taskId);
			await invalidateAll();
		} catch (err) {
			console.error('Failed to submit task:', err);
		} finally {
			submittingTaskId = null;
		}
	}

	function handleRemoveTask(taskId: string) {
		selectedTaskIds.delete(taskId);
	}

	async function handleRemoveCompletedTask(taskId: string) {
		removingTaskId = taskId;
		try {
			await client.mutate({
				mutation: REMOVE_SERVICE_TASK_COMPLETION,
				variables: { serviceId: service.id, taskId }
			});
			await invalidateAll();
		} catch (err) {
			console.error('Failed to remove task completion:', err);
		} finally {
			removingTaskId = null;
		}
	}

	async function handleSubmitAllTasks() {
		for (const taskId of selectedTaskIds) {
			await handleSubmitTask(taskId);
		}
	}

	function handleClearSelection() {
		selectedTaskIds.clear();
	}

	// Note handlers
	async function handleAddNote(content: string, internal: boolean) {
		if (!session) return;
		await client.mutate({
			mutation: CREATE_SERVICE_SESSION_NOTE,
			variables: { input: { sessionId: session.id, content, internal } }
		});
		await invalidateAll();
	}

	async function handleUpdateNote(noteId: string, content: string, internal: boolean) {
		await client.mutate({
			mutation: UPDATE_SERVICE_SESSION_NOTE,
			variables: { id: noteId, input: { content, internal } }
		});
		await invalidateAll();
	}

	async function handleDeleteNote(noteId: string) {
		await client.mutate({
			mutation: DELETE_SERVICE_SESSION_NOTE,
			variables: { id: noteId }
		});
		await invalidateAll();
	}

	// Media handlers
	async function handleUploadPhoto(file: File, title: string, notes: string, internal: boolean) {
		if (!session) return;
		await client.mutate({
			mutation: UPLOAD_SERVICE_SESSION_IMAGE,
			variables: {
				sessionId: session.id,
				file,
				title: title || null,
				notes: notes || null,
				internal
			}
		});
		await invalidateAll();
	}

	async function handleUploadVideo(file: File, title: string, notes: string, internal: boolean) {
		if (!session) return;
		await client.mutate({
			mutation: UPLOAD_SERVICE_SESSION_VIDEO,
			variables: {
				sessionId: session.id,
				file,
				title: title || null,
				notes: notes || null,
				internal
			}
		});
		await invalidateAll();
	}

	async function handleUpdatePhoto(
		photoId: string,
		title: string,
		notes: string,
		internal: boolean
	) {
		await client.mutate({
			mutation: UPDATE_SERVICE_SESSION_IMAGE,
			variables: { id: photoId, input: { title: title || null, notes: notes || null, internal } }
		});
		await invalidateAll();
	}

	async function handleUpdateVideo(
		videoId: string,
		title: string,
		notes: string,
		internal: boolean
	) {
		await client.mutate({
			mutation: UPDATE_SERVICE_SESSION_VIDEO,
			variables: { id: videoId, input: { title: title || null, notes: notes || null, internal } }
		});
		await invalidateAll();
	}

	async function handleDeletePhoto(photoId: string) {
		await client.mutate({
			mutation: DELETE_SERVICE_SESSION_IMAGE,
			variables: { id: photoId }
		});
		await invalidateAll();
	}

	async function handleDeleteVideo(videoId: string) {
		await client.mutate({
			mutation: DELETE_SERVICE_SESSION_VIDEO,
			variables: { id: videoId }
		});
		await invalidateAll();
	}

	function toggleTeamMemberSelection(profileId: string) {
		if (selectedTeamMembers.has(profileId)) {
			selectedTeamMembers.delete(profileId);
		} else {
			selectedTeamMembers.add(profileId);
		}
	}

	function closeAssignMenu() {
		assignMenuOpen = false;
		selectedTeamMembers.clear();
	}

	function handleEditService() {
		drawerMode = 'service';
		drawerOpen = true;
	}

	function closeDrawer() {
		drawerOpen = false;
		drawerMode = null;
	}

	async function handleFormSuccess() {
		closeDrawer();
		await invalidateAll();
	}

	// Calendar event form initial values
	let calendarEventInitialValues = $derived({
		summary: `${service.account?.name ?? 'Service'} - Service`,
		description: service.notes ? `Notes: ${service.notes}` : undefined,
		location: service.accountAddress ? formatAddress(service.accountAddress) : undefined,
		date: service.date
	});

	function openCalendarDrawer() {
		calendarDrawerOpen = true;
	}

	function closeCalendarDrawer() {
		calendarDrawerOpen = false;
	}

	async function handleCalendarEventSuccess(eventId: string) {
		// Link the created event to this service
		try {
			await client.mutate({
				mutation: LINK_CALENDAR_EVENT_TO_SERVICE,
				variables: {
					serviceId: service.id,
					eventId
				}
			});
			closeCalendarDrawer();
			await invalidateAll();
		} catch (err) {
			console.error('Failed to link calendar event:', err);
			// Event was created but not linked - still close drawer and refresh
			closeCalendarDrawer();
			await invalidateAll();
		}
	}

	function handleDeleteService() {
		deleteTarget = {
			type: 'service',
			id: service.id,
			name: `service on ${formatDate(service.date)}`
		};
		deleteModalOpen = true;
	}

	function handleRemoveTeamMember(memberId: string, memberName: string) {
		deleteTarget = {
			type: 'team_member',
			id: memberId,
			name: memberName
		};
		deleteModalOpen = true;
	}

	function closeDeleteModal() {
		deleteModalOpen = false;
		deleteTarget = null;
	}

	async function confirmDelete() {
		if (!deleteTarget) return;

		deleteLoading = true;
		try {
			if (deleteTarget.type === 'service') {
				await client.mutate({
					mutation: DELETE_SERVICE,
					variables: { id: deleteTarget.id }
				});
				closeDeleteModal();
				await goto(`/admin/services?month=${backMonth()}`);
				return;
			} else if (deleteTarget.type === 'team_member') {
				await client.mutate({
					mutation: REMOVE_SERVICE_TEAM_MEMBER,
					variables: { id: deleteTarget.id }
				});
			}

			closeDeleteModal();
			await invalidateAll();
		} catch (err) {
			console.error('Delete failed:', err);
		} finally {
			deleteLoading = false;
		}
	}

	async function handleAssignSelectedTeamMembers() {
		if (selectedTeamMembers.size === 0) return;
		assignLoading = true;
		try {
			for (const teamProfileId of selectedTeamMembers) {
				await client.mutate({
					mutation: ASSIGN_SERVICE_TEAM_MEMBER,
					variables: {
						serviceId: service.id,
						teamProfileId
					}
				});
			}
			closeAssignMenu();
			await invalidateAll();
		} catch (err) {
			console.error('Assignment failed:', err);
		} finally {
			assignLoading = false;
		}
	}

	// Dispatch state
	let dispatchLoading = $state(false);

	function handleMessageTeam() {
		if (teamMembers.length === 0) return;

		const participants = teamMembers.map((m) => m.teamProfileId).join(',');
		const subject = encodeURIComponent(
			`Service: ${service.account?.name ?? 'Unknown'} - ${formatDate(service.date)}`
		);

		goto(
			`/messages/new?subject=${subject}&entityType=service&entityId=${service.id}&participants=${participants}`
		);
	}

	async function handleDispatch() {
		if (!dispatchProfile) return;
		dispatchLoading = true;
		try {
			await client.mutate({
				mutation: ASSIGN_SERVICE_TEAM_MEMBER,
				variables: {
					serviceId: service.id,
					teamProfileId: dispatchProfile.id
				}
			});
			await invalidateAll();
		} catch (err) {
			console.error('Dispatch failed:', err);
		} finally {
			dispatchLoading = false;
		}
	}

	async function handleUndispatch() {
		if (!dispatchAssignment) return;
		dispatchLoading = true;
		try {
			// First remove all team members (non-admin)
			for (const member of teamMembers) {
				await client.mutate({
					mutation: REMOVE_SERVICE_TEAM_MEMBER,
					variables: { id: member.id }
				});
			}
			// Then remove dispatch (admin)
			await client.mutate({
				mutation: REMOVE_SERVICE_TEAM_MEMBER,
				variables: { id: dispatchAssignment.id }
			});
			await invalidateAll();
		} catch (err) {
			console.error('Undispatch failed:', err);
		} finally {
			dispatchLoading = false;
		}
	}
</script>

<svelte:head>
	<title>Service - {service.account?.name ?? 'Unknown'} - Admin - Nexus</title>
</svelte:head>

<div class="py-8">
	<ContentContainer>
		<PageHeader
			title={service.account?.name ?? 'Unknown Account'}
			subtitle={service.account?.customer?.name ?? undefined}
			backHref="/admin/services?month={backMonth()}"
			colorScheme="secondary"
		>
			<div class="flex flex-wrap items-center gap-2">
				<span
					class="inline-flex rounded-full px-2 py-0.5 text-xs font-semibold {getStatusBadgeClass(
						service.status
					)}"
				>
					{formatStatusLabel(service.status)}
				</span>
				{#if isDispatched}
					<span
						class="inline-flex rounded-full bg-purple-100 px-2 py-0.5 text-xs font-semibold text-purple-800 dark:bg-purple-900/30 dark:text-purple-400"
					>
						Dispatched
					</span>
				{/if}
				{#if isAssigned}
					<span
						class="inline-flex rounded-full bg-blue-100 px-2 py-0.5 text-xs font-semibold text-blue-800 dark:bg-blue-900/30 dark:text-blue-400"
					>
						Assigned
					</span>
				{/if}
				<span class="text-sm text-theme-secondary">{formatDate(service.date)}</span>
			</div>
		</PageHeader>

		<div class="space-y-6">
			<!-- Service Details Section -->
			<section
				class="overflow-hidden rounded-xl border border-secondary-500/20 bg-theme-card shadow-theme-md"
			>
				<div class="section-header-secondary px-6 py-4">
					<SectionHeader
						title="Service Details"
						buttonText="Edit"
						buttonIcon="edit"
						onButtonClick={handleEditService}
					/>
				</div>
				<div class="grid grid-cols-1 gap-4 p-6 sm:grid-cols-2">
					<div>
						<dt class="text-sm font-medium text-theme-secondary">Date</dt>
						<dd class="mt-1 text-theme">{formatDate(service.date)}</dd>
					</div>
					<div>
						<dt class="text-sm font-medium text-theme-secondary">Status</dt>
						<dd class="mt-1">
							<span
								class="inline-flex rounded-full px-2 py-0.5 text-xs font-semibold {getStatusBadgeClass(
									service.status
								)}"
							>
								{formatStatusLabel(service.status)}
							</span>
						</dd>
					</div>
					<div>
						<dt class="text-sm font-medium text-theme-secondary">Labor</dt>
						<dd class="mt-1">
							{#if activeLabor}
								<span class="text-theme">{formatCurrency(activeLabor.amount)}</span>
							{:else}
								<span class="text-theme-muted">Not set</span>
							{/if}
						</dd>
					</div>
					<div>
						<dt class="text-sm font-medium text-theme-secondary">Calendar Event</dt>
						<dd class="mt-1">
							{#if service.calendarEventId}
								<a
									href="/admin/calendar/{service.calendarEventId}"
									class="text-sm font-medium text-accent7-600 hover:text-accent7-700 dark:text-accent7-400 dark:hover:text-accent7-300"
								>
									View Event →
								</a>
							{:else}
								<button
									type="button"
									onclick={openCalendarDrawer}
									class="inline-flex items-center gap-1.5 text-sm font-medium text-accent7-600 hover:text-accent7-700 dark:text-accent7-400 dark:hover:text-accent7-300"
								>
									<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
										<path
											stroke-linecap="round"
											stroke-linejoin="round"
											stroke-width="2"
											d="M12 4v16m8-8H4"
										/>
									</svg>
									Schedule Event
								</button>
							{/if}
						</dd>
					</div>
				</div>
			</section>

			<!-- Account & Location Section -->
			<section
				class="overflow-hidden rounded-xl border border-secondary-500/20 bg-theme-card shadow-theme-md"
			>
				<div class="section-header-secondary px-6 py-4">
					<h2 class="text-lg font-semibold text-theme">Account & Location</h2>
				</div>
				<div class="grid grid-cols-1 gap-4 p-6 sm:grid-cols-2">
					<div>
						<dt class="text-sm font-medium text-theme-secondary">Account</dt>
						<dd class="mt-1">
							{#if service.account}
								<a
									href="/admin/accounts/{service.account.id}"
									class="text-primary-500 hover:text-primary-600"
								>
									{service.account.name}
								</a>
							{:else}
								<span class="text-theme-muted">Unknown</span>
							{/if}
						</dd>
					</div>
					{#if service.account?.customer}
						<div>
							<dt class="text-sm font-medium text-theme-secondary">Customer</dt>
							<dd class="mt-1">
								<a
									href="/admin/customers/{service.account.customer.id}"
									class="text-accent3-500 hover:text-accent3-600"
								>
									{service.account.customer.name}
								</a>
							</dd>
						</div>
					{/if}
					{#if service.accountAddress}
						<div class="sm:col-span-2">
							<dt class="text-sm font-medium text-theme-secondary">Location</dt>
							<dd class="mt-1">
								<a
									href="/admin/accounts/{service.account?.id}/locations/{service.accountAddress.id}"
									class="text-primary-500 hover:text-primary-600"
								>
									{#if service.accountAddress.name}
										{service.accountAddress.name} -
									{/if}
									{formatAddress(service.accountAddress)}
								</a>
							</dd>
						</div>
					{/if}
				</div>
			</section>

			<!-- Service Notes Section -->
			{#if service.notes}
				<section
					class="overflow-hidden rounded-xl border border-secondary-500/20 bg-theme-card shadow-theme-md"
				>
					<div class="section-header-secondary px-6 py-4">
						<h2 class="text-lg font-semibold text-theme">Service Notes</h2>
					</div>
					<div class="p-6">
						<p class="whitespace-pre-wrap text-theme">{service.notes}</p>
					</div>
				</section>
			{/if}

			<!-- Team Members Section -->
			<section
				class="overflow-hidden rounded-xl border border-secondary-500/20 bg-theme-card shadow-theme-md"
			>
				<div class="section-header-secondary px-6 py-4">
					<div class="flex items-center justify-between">
						<h2 class="text-lg font-semibold text-theme">Team Members</h2>
						<div class="flex items-center gap-3">
							{#if teamMembers.length > 0}
								<button
									type="button"
									onclick={handleMessageTeam}
									class="flex items-center gap-1 text-sm font-medium text-accent-600 hover:text-accent-700 dark:text-accent-400 dark:hover:text-accent-300"
								>
									<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
										<path
											stroke-linecap="round"
											stroke-linejoin="round"
											stroke-width="2"
											d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
										/>
									</svg>
									Message Team
								</button>
							{/if}
							{#if !isDispatched}
								<!-- Not dispatched: show Dispatch button -->
								<button
									type="button"
									onclick={handleDispatch}
									disabled={dispatchLoading || !dispatchProfile}
									class="flex items-center gap-1 text-sm font-medium text-purple-600 hover:text-purple-700 disabled:opacity-50 dark:text-purple-400 dark:hover:text-purple-300"
								>
									{#if dispatchLoading}
										<svg class="h-4 w-4 animate-spin" 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>
									{:else}
										<IconPlus class="h-4 w-4" />
									{/if}
									Dispatch
								</button>
							{:else}
								<!-- Dispatched: show Assign button and Undispatch option -->
								<div class="relative">
									<button
										type="button"
										onclick={() => (assignMenuOpen = !assignMenuOpen)}
										class="flex items-center gap-1 text-sm font-medium text-secondary-600 hover:text-secondary-700 dark:text-secondary-400 dark:hover:text-secondary-300"
									>
										<IconPlus class="h-4 w-4" />
										Assign
									</button>
									{#if assignMenuOpen}
										<div class="fixed inset-0 z-50 flex items-center justify-center p-4">
											<button
												type="button"
												class="absolute inset-0 bg-black/50"
												onclick={closeAssignMenu}
												aria-label="Close menu"
											></button>
											<div
												class="relative w-full max-w-xs rounded-xl border border-theme bg-theme-card py-2 shadow-xl"
											>
												<p
													class="px-4 py-2 text-xs font-medium tracking-wide text-theme-muted uppercase"
												>
													Assign Team Members
												</p>
												{#each availableTeamProfiles.filter((p) => p.id !== config.dispatch.profileId) as profile (profile.id)}
													{@const alreadyAssigned = service.teamMembers.some(
														(m) => m.teamProfileId === profile.id
													)}
													{@const isSelected = selectedTeamMembers.has(profile.id)}
													<button
														type="button"
														onclick={() => toggleTeamMemberSelection(profile.id)}
														disabled={alreadyAssigned || assignLoading}
														class="flex w-full items-center gap-3 px-4 py-3 text-theme hover:bg-theme-secondary disabled:cursor-not-allowed disabled:opacity-50"
													>
														<span
															class="flex h-5 w-5 items-center justify-center rounded border {isSelected
																? 'border-secondary-500 bg-secondary-500'
																: 'border-theme-secondary'}"
														>
															{#if isSelected}
																<svg
																	class="h-3 w-3 text-white"
																	fill="none"
																	stroke="currentColor"
																	viewBox="0 0 24 24"
																>
																	<path
																		stroke-linecap="round"
																		stroke-linejoin="round"
																		stroke-width="3"
																		d="M5 13l4 4L19 7"
																	/>
																</svg>
															{/if}
														</span>
														<span class="text-left">
															<span class="block text-sm font-medium">{profile.fullName}</span>
															<span class="block text-xs text-theme-muted">
																{profile.role === 'TEAM_LEADER' ? 'Team Leader' : 'Team Member'}
																{#if alreadyAssigned}
																	<span class="text-secondary-500"> (assigned)</span>
																{/if}
															</span>
														</span>
													</button>
												{/each}
												{#if availableTeamProfiles.filter((p) => p.id !== config.dispatch.profileId).length === 0}
													<p class="px-4 py-3 text-sm text-theme-muted">
														No team members available
													</p>
												{/if}
												{#if selectedTeamMembers.size > 0}
													<div class="my-1 border-t border-theme"></div>
													<button
														type="button"
														onclick={handleAssignSelectedTeamMembers}
														disabled={assignLoading}
														class="flex w-full items-center justify-center gap-2 px-4 py-3 text-sm font-medium text-secondary-600 hover:bg-secondary-50 disabled:opacity-50 dark:text-secondary-400 dark:hover:bg-secondary-950/50"
													>
														{#if assignLoading}
															<svg class="h-4 w-4 animate-spin" 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>
														{/if}
														Assign {selectedTeamMembers.size} Member{selectedTeamMembers.size > 1
															? 's'
															: ''}
													</button>
												{/if}
												<div class="my-1 border-t border-theme"></div>
												{#if teamMembers.length > 0}
													<p class="px-4 py-2 text-xs text-error-500 dark:text-error-400">
														This will also remove {teamMembers.length} assigned team member{teamMembers.length >
														1
															? 's'
															: ''}
													</p>
												{/if}
												<button
													type="button"
													onclick={() => {
														closeAssignMenu();
														handleUndispatch();
													}}
													disabled={dispatchLoading}
													class="flex w-full items-center gap-3 px-4 py-3 text-error-600 hover:bg-error-50 disabled:opacity-50 dark:text-error-400 dark:hover:bg-error-950/50"
												>
													<svg
														class="h-5 w-5"
														fill="none"
														stroke="currentColor"
														viewBox="0 0 24 24"
													>
														<path
															stroke-linecap="round"
															stroke-linejoin="round"
															stroke-width="2"
															d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"
														/>
													</svg>
													Remove From Dispatch
												</button>
											</div>
										</div>
									{/if}
								</div>
							{/if}
						</div>
					</div>
				</div>
				{#if teamMembers.length > 0}
					<div class="p-6">
						<ul class="divide-theme divide-y">
							{#each teamMembers as member (member.id)}
								<li class="group py-3">
									<div class="flex items-center justify-between">
										<div class="flex items-center gap-3">
											<div
												class="flex h-8 w-8 items-center justify-center rounded-full bg-secondary-100 text-secondary-600 dark:bg-secondary-900/30 dark:text-secondary-400"
											>
												<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
													<path
														stroke-linecap="round"
														stroke-linejoin="round"
														stroke-width="2"
														d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
													/>
												</svg>
											</div>
											<div>
												<p class="text-sm font-medium text-theme">
													{member.teamProfile?.fullName ?? 'Unknown'}
												</p>
												{#if member.teamProfile?.role}
													<p class="text-xs text-theme-muted">
														{member.teamProfile.role === 'TEAM_LEADER'
															? 'Team Leader'
															: 'Team Member'}
													</p>
												{/if}
											</div>
										</div>
										<button
											type="button"
											onclick={() =>
												handleRemoveTeamMember(
													member.id,
													member.teamProfile?.fullName ?? 'Unknown'
												)}
											class="btn-icon-sm btn-delete-hover text-theme-muted opacity-0 group-hover:opacity-100"
											aria-label="Remove team member"
										>
											<IconTrash />
										</button>
									</div>
								</li>
							{/each}
						</ul>
					</div>
				{:else if isDispatched}
					<p class="p-6 text-sm text-theme-muted">Dispatched. Ready to assign team members.</p>
				{:else}
					<p class="p-6 text-sm text-theme-muted">Dispatch first to assign team members.</p>
				{/if}
			</section>

			<!-- Work Session Section -->
			<section
				class="overflow-hidden rounded-xl border border-secondary-500/20 bg-theme-card shadow-theme-md"
			>
				<div class="section-header-secondary px-6 py-4">
					<h2 class="text-lg font-semibold text-theme">Work Session</h2>
				</div>
				<div class="p-6">
					{#if session}
						<!-- Active or completed session -->
						<SessionContent
							sessionType="service"
							isActive={session.isActive}
							session={{
								isActive: session.isActive,
								start: session.start,
								end: session.end,
								durationSeconds: session.durationSeconds,
								images: session.images,
								videos: session.videos,
								notes: session.notes,
								completedTasks: session.completedTasks,
								createdBy: session.createdBy,
								closedBy: session.closedBy
							}}
							entityName={service.account?.name ?? 'Service'}
							scopeName={scope?.name}
							scopeDescription={scope?.description}
							addressInfo={service.accountAddress
								? `${service.accountAddress.streetAddress}, ${service.accountAddress.city}`
								: null}
							teamMembers={data.teamProfiles?.map((p) => ({ id: p.id, fullName: p.fullName })) ??
								[]}
							areas={sessionAreas}
							tasks={allTasks}
							{selectedTaskIds}
							{completedTaskIds}
							{completedTasksByArea}
							{readyToSubmitByArea}
							{availableTasksCount}
							isSubmitting={isClosingSession}
							isReverting={isRevertingSession}
							{submittingTaskId}
							{removingTaskId}
							onClose={handleCloseSession}
							onRevert={handleRevertSession}
							onToggleTask={handleToggleTask}
							onSubmitTask={handleSubmitTask}
							onRemoveTask={handleRemoveTask}
							onRemoveCompletedTask={handleRemoveCompletedTask}
							onSubmitAllTasks={handleSubmitAllTasks}
							onClearSelection={handleClearSelection}
							onAddNote={handleAddNote}
							onUpdateNote={handleUpdateNote}
							onDeleteNote={handleDeleteNote}
							onUploadPhoto={handleUploadPhoto}
							onUploadVideo={handleUploadVideo}
							onUpdatePhoto={handleUpdatePhoto}
							onUpdateVideo={handleUpdateVideo}
							onDeletePhoto={handleDeletePhoto}
							onDeleteVideo={handleDeleteVideo}
							{getTeamMemberName}
						/>
					{:else if canStartSession}
						<!-- Can start a new session -->
						<div class="flex flex-col items-center gap-4 py-8">
							<p class="text-sm text-theme-muted">
								Start a work session to track time, complete tasks, and capture notes/photos.
							</p>
							<StartSessionButton
								sessionType="service"
								isLoading={sessionLoading}
								onStart={handleStartSession}
							/>
						</div>
					{:else if service.status === 'IN_PROGRESS'}
						<p class="text-sm text-theme-muted">
							This service has an active session but it was not loaded. Try refreshing the page.
						</p>
					{:else if service.status === 'COMPLETED'}
						<p class="text-sm text-theme-muted">
							This service has been completed. View the session history for details.
						</p>
					{:else if !isAssigned}
						<p class="text-sm text-theme-muted">Assign team members to enable work sessions.</p>
					{:else if !scope}
						<p class="text-sm text-theme-muted">
							No active scope found for this location. Configure a scope to enable work sessions.
						</p>
					{:else}
						<p class="text-sm text-theme-muted">
							Work session is not available for this service status.
						</p>
					{/if}
				</div>
			</section>

			<!-- Danger Zone -->
			<details
				class="group overflow-hidden rounded-xl border border-error-500/30 bg-error-50/50 shadow-theme dark:bg-error-950/20"
			>
				<summary
					class="flex cursor-pointer items-center justify-between bg-linear-to-r from-error-500/10 to-transparent px-5 py-3 select-none"
				>
					<span class="text-lg font-semibold text-error-700 dark:text-error-400">Danger Zone</span>
					<svg
						class="h-5 w-5 text-error-500 transition-transform group-open:rotate-180"
						fill="none"
						stroke="currentColor"
						viewBox="0 0 24 24"
					>
						<path
							stroke-linecap="round"
							stroke-linejoin="round"
							stroke-width="2"
							d="M19 9l-7 7-7-7"
						/>
					</svg>
				</summary>
				<div class="space-y-4 border-t border-error-500/20 px-5 py-5">
					<p class="text-sm text-error-600 dark:text-error-300">
						Deleting this service will remove it from the schedule. This action cannot be undone.
					</p>
					<button type="button" class="btn-danger" onclick={handleDeleteService}>
						Delete Service
					</button>
				</div>
			</details>
		</div>

		<!-- Form Drawer -->
		<FormDrawer
			open={drawerOpen}
			title={drawerMode === 'service' ? 'Edit Service' : ''}
			onClose={closeDrawer}
		>
			{#if drawerMode === 'service'}
				<ServiceForm {service} onSuccess={handleFormSuccess} onCancel={closeDrawer} />
			{/if}
		</FormDrawer>

		<!-- Calendar Event Drawer -->
		<FormDrawer
			open={calendarDrawerOpen}
			title="Schedule Calendar Event"
			onClose={closeCalendarDrawer}
		>
			<CalendarEventForm
				teamProfiles={data.teamProfiles ?? []}
				initialValues={calendarEventInitialValues}
				onSuccess={handleCalendarEventSuccess}
				onCancel={closeCalendarDrawer}
			/>
		</FormDrawer>

		<!-- Delete Modal -->
		<DeleteModal
			open={deleteModalOpen}
			title={deleteTarget
				? `Delete ${deleteTarget.type === 'team_member' ? 'Team Member' : 'Service'}`
				: ''}
			message={deleteTarget
				? deleteTarget.type === 'team_member'
					? `Are you sure you want to remove "${deleteTarget.name}" from this service?`
					: `Are you sure you want to delete this ${deleteTarget.name}? This action cannot be undone.`
				: ''}
			loading={deleteLoading}
			onConfirm={confirmDelete}
			onCancel={closeDeleteModal}
		/>
	</ContentContainer>
</div>
