<template>
	<div class="calendar-container">
		<div class="calendar-header">
			<h2>Weekly Schedule - {{ companyStore.currentCompany }}</h2>
			<div class="header-controls">
				<v-btn
					@click="previousWeek"
					icon="mdi-chevron-left"
					variant="outlined"
					size="small"
				></v-btn>
				<v-btn
					@click="showDatePicker = true"
					variant="text"
					class="week-display-btn"
				>
					<span class="date-text">{{ weekDisplayText }}</span>
					<v-icon right size="small">mdi-calendar</v-icon>
				</v-btn>
				<v-btn
					@click="nextWeek"
					icon="mdi-chevron-right"
					variant="outlined"
					size="small"
				></v-btn>
				<v-btn @click="goToThisWeek" variant="outlined" size="small" class="ml-4">
					This Week
				</v-btn>
				<v-menu
					v-model="showTemplateMenu"
					:close-on-content-click="false"
					location="bottom"
				>
					<template v-slot:activator="{ props }">
						<v-btn
							v-bind="props"
							variant="outlined"
							size="small"
							class="ml-4"
						>
							<v-icon left size="small">mdi-file-document-multiple</v-icon>
							Project Template ({{ selectedProjectTemplates.length }})
							<v-icon right size="small">mdi-chevron-down</v-icon>
						</v-btn>
					</template>
					<v-card min-width="300" max-width="400">
						<v-card-title class="text-subtitle-1 py-2">
							Select Project Templates
						</v-card-title>
						<v-divider></v-divider>
						<v-card-text class="pa-2">
							<v-list density="compact">
								<v-list-item @click="toggleAllTemplates">
									<template v-slot:prepend>
										<v-checkbox-btn
											:model-value="selectedProjectTemplates.length === projectTemplates.length"
											:indeterminate="selectedProjectTemplates.length > 0 && selectedProjectTemplates.length < projectTemplates.length"
										></v-checkbox-btn>
									</template>
									<v-list-item-title>Select All</v-list-item-title>
								</v-list-item>
								<v-divider></v-divider>
								<v-list-item
									v-for="template in projectTemplates"
									:key="template.name"
									@click="toggleTemplate(template.name)"
								>
									<template v-slot:prepend>
										<v-checkbox-btn
											:model-value="selectedProjectTemplates.includes(template.name)"
										></v-checkbox-btn>
									</template>
									<v-list-item-title>{{ template.name }}</v-list-item-title>
								</v-list-item>
							</v-list>
						</v-card-text>
						<v-card-actions>
							<v-spacer></v-spacer>
							<v-btn
								color="primary"
								variant="flat"
								size="small"
								@click="applyTemplateFilter"
							>
								Apply
							</v-btn>
						</v-card-actions>
					</v-card>
				</v-menu>
				<v-menu
					v-model="showForemenMenu"
					:close-on-content-click="false"
					location="bottom"
				>
					<template v-slot:activator="{ props }">
						<v-btn
							v-bind="props"
							variant="outlined"
							size="small"
							class="ml-4"
						>
							<v-icon left size="small">mdi-account-group</v-icon>
							Crews ({{ selectedForemen.length }})
							<v-icon right size="small">mdi-chevron-down</v-icon>
						</v-btn>
					</template>
					<v-card min-width="250" max-width="300">
						<v-card-title class="text-subtitle-1 py-2">
							Select Crews
						</v-card-title>
						<v-divider></v-divider>
						<v-card-text class="pa-2">
							<v-list density="compact">
								<v-list-item @click="toggleAllForemen">
									<template v-slot:prepend>
										<v-checkbox-btn
											:model-value="selectedForemen.length === foremen.length"
											:indeterminate="selectedForemen.length > 0 && selectedForemen.length < foremen.length"
										></v-checkbox-btn>
									</template>
									<v-list-item-title>Select All</v-list-item-title>
								</v-list-item>
								<v-divider></v-divider>
								<v-list-item
									v-for="foreman in foremen"
									:key="foreman.name"
									@click="toggleForeman(foreman.customCrew ? parseInt(foreman.customCrew) : foreman.name)"
								>
									<template v-slot:prepend>
										<v-checkbox-btn
											:model-value="selectedForemen.includes(foreman.customCrew ? parseInt(foreman.customCrew) : foreman.name)"
										></v-checkbox-btn>
									</template>
									<v-list-item-title>{{ foreman.employeeName }}{{ foreman.customCrew ? ` (Crew ${foreman.customCrew})` : '' }}</v-list-item-title>
								</v-list-item>
							</v-list>
						</v-card-text>
					</v-card>
				</v-menu>
			</div>
		</div>

		<!-- Date Picker Dialog -->
		<v-dialog v-model="showDatePicker" max-width="400px">
			<v-card>
				<v-card-title>Select Week</v-card-title>
				<v-card-text>
					<v-date-picker
						v-model="selectedDate"
						@update:model-value="onDateSelected"
						full-width
					></v-date-picker>
				</v-card-text>
				<v-card-actions>
					<v-spacer></v-spacer>
					<v-btn @click="showDatePicker = false">Cancel</v-btn>
				</v-card-actions>
			</v-card>
		</v-dialog>

		<div class="calendar-main">
			<!-- Weekly Calendar Grid -->
			<div class="calendar-section">
				<div class="weekly-calendar">
					<!-- Days Header -->
					<div class="calendar-header-row" :style="{ gridTemplateColumns: `150px repeat(7, 1fr)` }">
						<div class="crew-column-header">Crew</div>
						<div
							v-for="day in weekDays"
							:key="day.date"
							class="day-header"
							:class="{ 'today': isToday(day.date) }"
						>
							<div class="day-name">{{ day.dayName }}</div>
							<div class="day-date">{{ day.displayDate }}</div>
						</div>
					</div>

					<!-- Foremen Grid -->
					<div class="calendar-grid">
						<div v-for="foreman in visibleForemen" :key="foreman.name" class="foreman-row" :style="{ gridTemplateColumns: `150px repeat(7, 1fr)` }">
							<!-- Foreman/Crew Column -->
							<div class="crew-column">
								<div class="crew-name">{{ foreman.employeeName }}</div>
								<div class="crew-number">{{ foreman.customCrew ? `Crew ${foreman.customCrew}` : 'No Crew #' }}</div>
							</div>

							<!-- Day Columns -->
							<div
								v-for="day in weekDays"
								:key="`${foreman.name}-${day.date}`"
								class="day-cell"
								:class="{
									'today': isToday(day.date),
									'holiday': isHoliday(day.date),
									'sunday': isSunday(day.date),
									'drag-over': isDragOver && dragOverCell?.foremanId === foreman.name && dragOverCell?.date === day.date,
								}"
								@dragover="handleDragOver($event, foreman.name, day.date)"
								@dragleave="handleDragLeave"
								@drop="handleDrop($event, foreman.name, day.date)"
							>
								<!-- Jobs in this day -->
								<div
									v-for="job in getJobsForCell(foreman.name, day.date)"
									:key="job.name"
									class="calendar-job"
									:style="getJobStyle(job, day.date)"
									:draggable="job.status === 'Scheduled'"
									@click.stop="showEventDetails({ event: job })"
									@dragstart="job.status === 'Scheduled' ? handleDragStart(job, $event) : null"
									@dragend="handleDragEnd"
									@mousedown="(job.status === 'Scheduled' || job.status === 'Started') ? startResize($event, job, day.date) : null"
									@drop.stop.prevent="handleScheduledDrop(job, $event, foreman.name, day.date)"
									@dragover.stop.prevent="handleScheduledDragOver(job, $event, foreman.name, day.date)"
								>
								<v-icon v-if="jobStartsBeforeWeek(job)" size="small" class="spans-arrow-left">mdi-arrow-left</v-icon>
								<div class="job-content">
									<div class="job-title">{{ job.projectTemplate }}</div>
									<div class="job-address">{{ job.serviceAddress.fullAddress }}</div>
								</div>
								<v-icon v-if="jobSpansToNextWeek(job)" size="small" class="spans-arrow-right">mdi-arrow-right</v-icon>
								<div class="resize-handle"></div>
							</div>
								
							<!-- Holiday connector line for split jobs -->
							<template v-if="isHoliday(day.date)">
								<div
									v-for="job in getJobsWithConnector(foreman.name, day.date)"
									:key="`connector-${job.name}`"
									class="holiday-connector"
									:class="getPriorityClass(job.priority)"
								></div>
							</template>
							</div>
						</div>
					</div>
				</div>
			</div>

			<!-- Unscheduled Services Column -->
			<div class="unscheduled-section">
				<div class="unscheduled-header">
					<h4>Unscheduled Jobs</h4>
					<v-chip
						:color="unscheduledServices.length > 0 ? 'warning' : 'success'"
						size="small"
					>
						{{ unscheduledServices.length }} pending
					</v-chip>
				</div>

				<div 
					class="unscheduled-list"
					:class="{ 'unscheduled-drop-zone': isDragOver && draggedService?.status === 'scheduled' }"
					@dragover="handleUnscheduledDragOver"
					@dragleave="handleUnscheduledDragLeave"
					@drop="handleUnscheduledDrop"
				>
					   <v-card
						   v-for="service in unscheduledServices"
						   :key="service.name"
						   class="unscheduled-item mb-2"
						   :class="getPriorityClass(service.project?.priority || service.priority)"
						   elevation="1"
						   hover
						   density="compact"
						   draggable="true"
						   @click.stop="showEventDetails({ event: service })"
						   @dragstart="handleDragStart(service, $event)"
						   @dragend="handleDragEnd"
					   >
						   <v-card-text class="pa-3">
							   <div class="service-title-compact mb-2">
								   {{ service.project?.projectName || service.projectTemplate || service.name }}
							   </div>
							   <div class="service-address mb-1">
								   <v-icon size="x-small" class="mr-1">mdi-map-marker</v-icon>
								   {{ service.serviceAddress?.fullAddress || service.serviceAddress?.addressTitle || service.serviceAddress?.name || service.project?.jobAddress }}
							   </div>
							   <div class="service-customer mb-2">
								   <v-icon size="x-small" class="mr-1">mdi-account</v-icon>
								   {{ service.customer?.customerName || service.customer?.name || service.project?.customer || service.customer || 'N/A' }}
							   </div>
							   <div v-if="service.project?.notes || service.notes" class="service-notes-compact mt-2">
								   <span class="text-caption">{{ service.project?.notes || service.notes }}</span>
							   </div>
							   <v-btn
								   color="primary"
								   size="x-small"
								   variant="outlined"
								   class="mt-2"
								   block
								   @click="scheduleService(service)"
							   >
								   <v-icon left size="x-small">mdi-calendar-plus</v-icon>
								   Schedule
							   </v-btn>
						   </v-card-text>
					   </v-card>
				</div>

				<div v-if="unscheduledServices.length === 0" class="no-unscheduled">
					<v-icon size="large" color="success">mdi-check-circle</v-icon>
					<p class="text-body-2">All installs scheduled!</p>
				</div>
			</div>
		</div>

		<!-- Event Details Modal -->
		<JobDetailsModal
			v-model="eventDialog"
			:job="selectedEvent"
			:foremen="foremen"
			:project="selectedEvent?.project"
			:customer="selectedEvent?.customer"
			:service-address="selectedEvent?.serviceAddress"
			@close="eventDialog = false"
		/>

		<!-- Extend to next week popup -->
		<div v-if="showExtendToNextWeekPopup && resizingJob" class="extend-popup">
			➜ Extend to next week
		</div>
	</div>
</template>

<script setup>
import { ref, onMounted, computed, watch } from "vue";
import Api from "../../../api";
import { useNotificationStore } from "../../../stores/notifications-primevue";
import { useCompanyStore } from "../../../stores/company";
import { useRoute } from "vue-router";
import JobDetailsModal from "../../modals/JobDetailsModal.vue";

const notifications = useNotificationStore();
const companyStore = useCompanyStore();
const route = useRoute();

const serviceAptToFind = route.query.apt || null;

// Reactive data
const scheduledServices = ref([]);
const unscheduledServices = ref([]);
const weekStartDate = ref(getWeekStart(new Date()));
const eventDialog = ref(false);
const selectedEvent = ref(null);
const projectTemplates = ref([]);
const holidays = ref([]);

// Drag and drop state
const draggedService = ref(null);
const isDragOver = ref(false);
const dragOverCell = ref(null);

// Extend to next week popup state
const showExtendToNextWeekPopup = ref(false);

// Resize state
const resizingJob = ref(null);
const resizeStartX = ref(0);
const resizeStartDate = ref(null);
const originalEndDate = ref(null);
const justFinishedResize = ref(false);

// Foremen data (Crews)
const foremen = ref([]);

// Foremen selection
const selectedForemen = ref([]); // Will be populated on fetch
const showForemenMenu = ref(false);

// Date picker
const showDatePicker = ref(false);
const selectedDate = ref(null);

// Project template filter
const selectedProjectTemplates = ref([]);
const showTemplateMenu = ref(false);

// Helper function to get local date string (YYYY-MM-DD)
function toLocalDateString(date) {
	const year = date.getFullYear();
	const month = String(date.getMonth() + 1).padStart(2, '0');
	const day = String(date.getDate()).padStart(2, '0');
	return `${year}-${month}-${day}`;
}

// Helper function to parse local date string into Date object
function parseLocalDate(dateStr) {
	const [year, month, day] = dateStr.split('-').map(Number);
	return new Date(year, month - 1, day);
}

// Helper function to get the start of the week (Monday)
function getWeekStart(date) {
	const d = new Date(date);
	// Get the day of week (0 = Sunday, 1 = Monday, ..., 6 = Saturday)
	const dayOfWeek = d.getDay();
	
	// Calculate days to subtract to get to Monday
	// Monday (1): subtract 0 days
	// Tuesday (2): subtract 1 day
	// ...
	// Sunday (0): subtract 6 days
	const daysToSubtract = (dayOfWeek - 1 + 7) % 7;
	
	// Create new date and subtract the days
	const monday = new Date(d);
	monday.setDate(d.getDate() - daysToSubtract);
	
	// Return as YYYY-MM-DD string using local date
	return toLocalDateString(monday);
}

// Helper function to format date
function formatDate(dateStr) {
	const date = parseLocalDate(dateStr);
	return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
}

// Helper function to get day name
function getDayName(dateStr) {
	const date = parseLocalDate(dateStr);
	return date.toLocaleDateString("en-US", { weekday: "short" });
}

// Helper function to check if date is today
function isToday(dateStr) {
	const today = new Date();
	const year = today.getFullYear();
	const month = String(today.getMonth() + 1).padStart(2, '0');
	const day = String(today.getDate()).padStart(2, '0');
	const todayStr = `${year}-${month}-${day}`;
	return dateStr === todayStr;
}

// Helper function to add days to a date
function addDays(dateStr, days) {
	const date = parseLocalDate(dateStr);
	date.setDate(date.getDate() + days);
	return toLocalDateString(date);
}

// Helper function to calculate days between two dates
function daysBetween(startDate, endDate) {
	const start = parseLocalDate(startDate);
	const end = parseLocalDate(endDate);
	const diffTime = end - start;
	const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
	return diffDays;
}

// Helper function to check if date is a holiday
function isHoliday(dateStr) {
	return holidays.value.some(holiday => holiday.holidayDate === dateStr);
}

// Helper function to get holiday description for a date
function getHolidayDescription(dateStr) {
	const holiday = holidays.value.find(h => h.holidayDate === dateStr);
	return holiday ? holiday.description : null;
}

// Helper function to check if date is Sunday
function isSunday(dateStr) {
	const date = parseLocalDate(dateStr);
	return date.getDay() === 0;
}

// Helper function to get next Monday from a date
function getNextMonday(dateStr) {
	const date = parseLocalDate(dateStr);
	const day = date.getDay();
	const daysToMonday = day === 1 ? 7 : (8 - day) % 7;
	date.setDate(date.getDate() + daysToMonday);
	return toLocalDateString(date);
}

// Helper function to check if any day in range is a holiday
function hasHolidayInRange(startDate, endDate) {
	const start = parseLocalDate(startDate);
	const end = parseLocalDate(endDate);
	for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
		const dateStr = toLocalDateString(d);
		if (isHoliday(dateStr)) return true;
	}
	return false;
}

// Helper function to check if job spans to next week
function jobSpansToNextWeek(job) {
	const endDate = job.expectedEndDate || job.expectedStartDate;
	const end = parseLocalDate(endDate);
	const weekEnd = parseLocalDate(addDays(weekStartDate.value, 6));
	return end > weekEnd;
}

// Helper function to check if job starts before current week
function jobStartsBeforeWeek(job) {
	const startDate = job.expectedStartDate;
	const start = parseLocalDate(startDate);
	const weekStart = parseLocalDate(weekStartDate.value);
	return start < weekStart;
}


// Helper function to get crew name from foreman ID
function getCrewName(foremanId) {
	if (!foremanId) return 'Not assigned';
	const foreman = foremen.value.find(f => f.name === foremanId);
	if (!foreman) return foremanId;
	return foreman.customCrew ? `${foreman.employeeName} (Crew ${foreman.customCrew})` : foreman.employeeName;
}

// Helper function to get all holidays in a date range
function getHolidaysInRange(startDate, endDate) {
	const start = parseLocalDate(startDate);
	const end = parseLocalDate(endDate);
	const holidaysInRange = [];
	for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
		const dateStr = toLocalDateString(d);
		if (isHoliday(dateStr)) {
			holidaysInRange.push(dateStr);
		}
	}
	return holidaysInRange;
}

// Helper function to calculate job segments (parts between holidays/Sundays)
function getJobSegments(job) {
	const startDate = job.expectedStartDate;
	const endDate = job.expectedEndDate || job.expectedStartDate;
	const weekEndDate = addDays(weekStartDate.value, 6); // Saturday
	
	const segments = [];
	let segmentStart = startDate;
	let currentDate = startDate;
	
	const start = parseLocalDate(startDate);
	const end = parseLocalDate(endDate);
	const weekEnd = parseLocalDate(weekEndDate);
	
	// Don't render segments beyond the current week's Saturday
	const effectiveEnd = end <= weekEnd ? end : weekEnd;
	
	for (let d = new Date(start); d <= effectiveEnd; d.setDate(d.getDate() + 1)) {
		const dateStr = toLocalDateString(d);
		
		// If we hit a holiday or Sunday, close the current segment
		if (isHoliday(dateStr) || isSunday(dateStr)) {
			// Close previous segment if it exists
			if (segmentStart !== null) {
				const prevDate = toLocalDateString(new Date(d.getTime() - 86400000)); // Previous day
				if (parseLocalDate(prevDate) >= parseLocalDate(startDate)) {
					segments.push({ start: segmentStart, end: prevDate });
				}
				segmentStart = null;
			}
		} else {
			// Start a new segment if we don't have one
			if (segmentStart === null) {
				segmentStart = dateStr;
			}
		}
	}
	
	// Close the final segment if there's an open one
	if (segmentStart !== null) {
		const finalEnd = toLocalDateString(effectiveEnd);
		segments.push({ start: segmentStart, end: finalEnd });
	}
	
	return segments;
}

// Computed properties
const weekDisplayText = computed(() => {
	const startDate = parseLocalDate(weekStartDate.value);
	const endDate = parseLocalDate(weekStartDate.value);
	endDate.setDate(endDate.getDate() + 6);
	
	return `${startDate.toLocaleDateString("en-US", { month: "short", day: "numeric" })} - ${endDate.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })}`;
});

const weekDays = computed(() => {
	const days = [];
	for (let i = 0; i < 7; i++) {
		const date = addDays(weekStartDate.value, i);
		days.push({
			date,
			dayName: getDayName(date),
			displayDate: formatDate(date),
		});
	}
	return days;
});

const visibleForemen = computed(() => {
	return foremen.value.filter(foreman => {
		const crewNum = foreman.customCrew ? parseInt(foreman.customCrew) : foreman.name;
		return selectedForemen.value.includes(crewNum);
	});
});



// Methods

const getPriorityClass = (priority) => {
	switch (priority) {
		case "urgent":
			return "priority-urgent";
		case "high":
			return "priority-high";
		case "medium":
			return "priority-medium";
		case "low":
			return "priority-low";
		default:
			return "";
	}
};

const getPriorityColor = (priority) => {
	switch (priority) {
		case "urgent":
			return "red";
		case "high":
			return "orange";
		case "medium":
			return "yellow";
		case "low":
			return "green";
		default:
			return "grey";
	}
};

const formatDuration = (minutes) => {
	const hours = Math.floor(minutes / 60);
	const mins = minutes % 60;
	if (hours === 0) return `${mins}m`;
	if (mins === 0) return `${hours}h`;
	return `${hours}h ${mins}m`;
};

// Get jobs for a specific foreman and date
const getJobsForCell = (foremanId, date) => {
	// Don't render jobs on Sunday or holidays
	if (isSunday(date) || isHoliday(date)) return [];
	
	return scheduledServices.value.filter((job) => {
		if (job.foreman !== foremanId) return false;
		
		const jobStart = job.expectedStartDate;
		const jobEnd = job.expectedEndDate || job.expectedStartDate;
		
		// Check if this date falls within the job's date range
		// AND that it's a valid segment start date
		const segments = getJobSegments(job);
		return segments.some(seg => seg.start === date);
	});
};

// Get jobs that need a connector line on this holiday
const getJobsWithConnector = (foremanId, date) => {
	if (!isHoliday(date)) return [];
	
	return scheduledServices.value.filter((job) => {
		if (job.foreman !== foremanId) return false;
		
		const jobStart = job.expectedStartDate;
		const jobEnd = job.expectedEndDate || job.expectedStartDate;
		
		// Check if this holiday date falls within the job's range
		return date > jobStart && date < jobEnd;
	});
};

// Get job style for width spanning multiple days
const getJobStyle = (job, currentDate) => {
	const jobStart = job.expectedStartDate;
	const jobEnd = job.expectedEndDate || job.expectedStartDate;
	const segments = getJobSegments(job);
	
	// Find which segment (if any) should be rendered at currentDate
	const segmentIndex = segments.findIndex(seg => seg.start === currentDate);
	
	if (segmentIndex === -1) {
		return { display: 'none' };
	}
	
	const segment = segments[segmentIndex];
	
	// Calculate visual duration for this segment
	let visualDays = daysBetween(segment.start, segment.end) + 1;
	
	// For multi-day jobs, calculate width to span cells
	const widthCalc = visualDays === 1 
		? 'calc(100% - 8px)' // Single day: full width minus padding
		: `calc(${visualDays * 100}% + ${(visualDays - 1)}px)`; // Multi-day: span cells accounting for borders
	
	// Get color from project template
	let backgroundColor = '#2196f3'; // Default color
	if (job.projectTemplate) {
		const template = projectTemplates.value.find(t => t.name === job.projectTemplate);
		if (template && template.calendarColor) {
			backgroundColor = template.calendarColor;
		}
	}
	const darkerColor = darkenColor(backgroundColor, 20);
	
	return {
		width: widthCalc,
		zIndex: 10,
		background: `linear-gradient(135deg, ${backgroundColor}, ${darkerColor})`
	};
};

// Helper function to darken a color
function darkenColor(color, percent) {
	if (!color || color === 'transparent') return '#1976d2';
	
	// Convert hex to RGB
	let r, g, b;
	if (color.startsWith('#')) {
		const hex = color.replace('#', '');
		r = parseInt(hex.substring(0, 2), 16);
		g = parseInt(hex.substring(2, 4), 16);
		b = parseInt(hex.substring(4, 6), 16);
	} else {
		return color; // Return original if not hex
	}
	
	// Darken
	r = Math.max(0, Math.floor(r * (1 - percent / 100)));
	g = Math.max(0, Math.floor(g * (1 - percent / 100)));
	b = Math.max(0, Math.floor(b * (1 - percent / 100)));
	
	return `rgb(${r}, ${g}, ${b})`;
}

// Calendar navigation methods
const previousWeek = () => {
	const date = parseLocalDate(weekStartDate.value);
	date.setDate(date.getDate() - 7);
	weekStartDate.value = toLocalDateString(date);
};

const nextWeek = () => {
	const date = parseLocalDate(weekStartDate.value);
	date.setDate(date.getDate() + 7);
	weekStartDate.value = toLocalDateString(date);
};

const goToThisWeek = () => {
	weekStartDate.value = getWeekStart(new Date());
};

// Foremen selection methods
const toggleAllForemen = () => {
	if (selectedForemen.value.length === foremen.value.length) {
		// Deselect all
		selectedForemen.value = [];
	} else {
		// Select all
		selectedForemen.value = foremen.value.map(f => {
			if (f.customCrew && f.customCrew.trim() !== '') {
				return parseInt(f.customCrew);
			}
			return f.name;
		});
	}
};

const toggleForeman = (crewNumber) => {
	const index = selectedForemen.value.indexOf(crewNumber);
	if (index > -1) {
		selectedForemen.value.splice(index, 1);
	} else {
		selectedForemen.value.push(crewNumber);
	}
};

// Project template selection methods
const toggleAllTemplates = () => {
	if (selectedProjectTemplates.value.length === projectTemplates.value.length) {
		// Deselect all
		selectedProjectTemplates.value = [];
	} else {
		// Select all
		selectedProjectTemplates.value = projectTemplates.value.map(t => t.name);
	}
};

const toggleTemplate = (templateName) => {
	const index = selectedProjectTemplates.value.indexOf(templateName);
	if (index > -1) {
		selectedProjectTemplates.value.splice(index, 1);
	} else {
		selectedProjectTemplates.value.push(templateName);
	}
};

const applyTemplateFilter = async () => {
	showTemplateMenu.value = false;
	// await fetchProjects(currentDate.value);
	await fetchServiceAppointments();
};

// Date picker methods
const onDateSelected = (date) => {
	if (date) {
		const dateObj = Array.isArray(date) ? date[0] : date;
		weekStartDate.value = getWeekStart(dateObj);
		showDatePicker.value = false;
	}
};

const showEventDetails = (event) => {
	// Don't open modal if we just finished resizing
	if (justFinishedResize.value) {
		justFinishedResize.value = false;
		return;
	}
	selectedEvent.value = event.event;
	eventDialog.value = true;
};

const scheduleService = (service) => {
	// Placeholder for future drag-and-drop functionality
	console.log("Scheduling service:", service);
	alert(
		`Drag and drop the job onto a day/crew cell to schedule it.`,
	);
};

// Drag and Drop methods
const handleDragStart = (service, event) => {
	draggedService.value = service;
	event.dataTransfer.effectAllowed = "move";
	event.dataTransfer.setData("text/plain", service.name);
	
	// Get the dimensions of the dragged element
	const dragElement = event.target;
	const rect = dragElement.getBoundingClientRect();
	
	// Set the drag image offset to center the element horizontally and position cursor at top
	const offsetX = rect.width / 2;
	const offsetY = 10;
	
	try {
		event.dataTransfer.setDragImage(dragElement, offsetX, offsetY);
	} catch (e) {
		console.log("Could not set custom drag image");
	}
	
	// Add visual feedback
	event.target.style.opacity = '0.5';
	console.log("Drag started for service:", service.projectTemplate);
};

const handleDragEnd = (event) => {
	// Reset visual feedback
	event.target.style.opacity = '1';
	draggedService.value = null;
	isDragOver.value = false;
	dragOverCell.value = null;
};

const handleDragOver = (event, foremanId, date) => {
	// Prevent dropping on Sunday
	if (isSunday(date)) {
		event.dataTransfer.dropEffect = "none";
		return;
	}
	
	event.preventDefault();
	event.stopPropagation();
	
	if (!draggedService.value) return;
	
	event.dataTransfer.dropEffect = "move";
	
	// Only update state if it's actually different to prevent flickering
	const currentCellKey = `${foremanId}-${date}`;
	const previousCellKey = dragOverCell.value ? `${dragOverCell.value.foremanId}-${dragOverCell.value.date}` : null;
	
	if (currentCellKey !== previousCellKey) {
		isDragOver.value = true;
		dragOverCell.value = { foremanId, date };
	}
};

const handleDragLeave = (event) => {
	// Use a small delay to prevent flickering when moving between child elements
	setTimeout(() => {
		if (!draggedService.value) return;
		
		const calendarGrid = document.querySelector('.calendar-grid');
		if (!calendarGrid) return;
		
		const rect = calendarGrid.getBoundingClientRect();
		const x = event.clientX;
		const y = event.clientY;
		
		// Only clear if mouse is outside the entire calendar grid
		if (
			x < rect.left ||
			x > rect.right ||
			y < rect.top ||
			y > rect.bottom
		) {
			isDragOver.value = false;
			dragOverCell.value = null;
		}
	}, 10);
};

const handleDrop = async (event, foremanId, date) => {
	event.preventDefault();
	event.stopPropagation();
	
	if (!draggedService.value) return;
	
	// Prevent dropping on Sunday
	if (isSunday(date)) {
		notifications.addError("Cannot schedule jobs on Sunday. Please select a weekday.");
		isDragOver.value = false;
		dragOverCell.value = null;
		draggedService.value = null;
		return;
	}
	
	// Prevent dropping on holidays
	if (isHoliday(date)) {
		const holidayDesc = getHolidayDescription(date);
		notifications.addError(`Cannot schedule jobs on ${holidayDesc || 'a holiday'}. Please select a different date.`);
		isDragOver.value = false;
		dragOverCell.value = null;
		draggedService.value = null;
		return;
	}
	
	// Get foreman details
	const foreman = foremen.value.find(f => f.name === foremanId);
	if (!foreman) return;
	
	// Default to single day
	let endDate = date;
	
	// Check for holidays in the range
	if (hasHolidayInRange(date, endDate)) {
		notifications.addError("Cannot schedule job on a holiday. Please select different dates.");
		// Reset drag state
		isDragOver.value = false;
		dragOverCell.value = null;
		draggedService.value = null;
		return;
	}
	
	// Check if this is scheduling an unscheduled job or moving a scheduled job
	const unscheduledIndex = unscheduledServices.value.findIndex(s => s.name === draggedService.value.name);
	const scheduledIndex = scheduledServices.value.findIndex(s => s.name === draggedService.value.name);
	
	if (unscheduledIndex !== -1) {
		// Scheduling an unscheduled job
		const action = 'Scheduled';
		console.log(`${action} ${draggedService.value.projectTemplate} for ${foreman.employeeName} on ${date} to ${endDate}`);
		
		// Call API to persist changes
		try {
			await Api.updateServiceAppointmentScheduledDates(
				draggedService.value.name,
				date,
				endDate,
				foreman.name
			);
			// Remove from unscheduled and add to scheduled
			const scheduledService = {
				...unscheduledServices.value[unscheduledIndex],
				expectedStartDate: date,
				expectedEndDate: endDate,
				foreman: foreman.name,
				status: 'Scheduled'
			};
			unscheduledServices.value.splice(unscheduledIndex, 1);
			scheduledServices.value.push(scheduledService);
			notifications.addSuccess("Job scheduled successfully!");
		} catch (error) {
			console.error("Error scheduling job:", error);
			notifications.addError("Failed to schedule job");
		}
	} else if (scheduledIndex !== -1 && draggedService.value.status === 'Scheduled') {
		// Moving a scheduled job to a new date/foreman
		console.log(`Moving ${draggedService.value.projectTemplate} to ${foreman.employeeName} on ${date}`);
		
		// Call API to persist changes
		try {
			await Api.updateServiceAppointmentScheduledDates(
				draggedService.value.name,
				date,
				date, // Reset to single day when moved
				foreman.name
			);
			// Update the scheduled job
			scheduledServices.value[scheduledIndex] = {
				...scheduledServices.value[scheduledIndex],
				expectedStartDate: date,
				expectedEndDate: date, // Reset to single day
				foreman: foreman.name
			};
			notifications.addSuccess("Job moved successfully!");
		} catch (error) {
			console.error("Error moving job:", error);
			notifications.addError("Failed to move job");
		}
	}
	
	// Reset drag state
	isDragOver.value = false;
	dragOverCell.value = null;
	draggedService.value = null;
};

// Handle dropping scheduled items back to unscheduled
const handleUnscheduledDragOver = (event) => {
	// Only allow dropping if the dragged job is scheduled
	if (draggedService.value && draggedService.value.status === 'Scheduled') {
		event.preventDefault();
		event.dataTransfer.dropEffect = "move";
	}
};

const handleUnscheduledDragLeave = (event) => {
	// Visual feedback will be handled by CSS
};

const handleUnscheduledDrop = async (event) => {
	event.preventDefault();
    
	if (!draggedService.value) return;
	// Only allow unscheduling if status is 'Scheduled'
	if (draggedService.value.status !== 'Scheduled') {
		notifications.addError('Only jobs with status "Scheduled" can be unscheduled.');
		isDragOver.value = false;
		dragOverCell.value = null;
		draggedService.value = null;
		return;
	}
	// Update the service to unscheduled status
	const serviceIndex = scheduledServices.value.findIndex(s => s.name === draggedService.value.name);
	if (serviceIndex !== -1) {
		// Remove from scheduled and add to unscheduled
		const unscheduledService = {
			...scheduledServices.value[serviceIndex],
			expectedStartDate: null,
			expectedEndDate: null,
			foreman: null
		};
		scheduledServices.value.splice(serviceIndex, 1);
		unscheduledServices.value.push(unscheduledService);
        
		console.log(`Unscheduled ${draggedService.value.projectTemplate}`);

		// Call API to persist changes
		try {
			await Api.updateServiceAppointmentScheduledDates(
				draggedService.value.name,
				null,
				null,
				null
			)
			notifications.addSuccess("Job unscheduled successfully!");
		} catch (error) {
			console.error("Error unscheduling job:", error);
			notifications.addError("Failed to unschedule job");
		}
	}
    
	// Reset drag state
	isDragOver.value = false;
	dragOverCell.value = null;
	draggedService.value = null;
};

// Allow moving scheduled jobs between days/crews if status is 'Scheduled'
const handleScheduledDragOver = (job, event, foremanId, date) => {
	if (!draggedService.value) return;
	// Only allow if dragging a scheduled job and target is a valid cell
	if (draggedService.value.status === 'Scheduled' && job.status === 'Scheduled') {
		event.dataTransfer.dropEffect = 'move';
	}
};

const handleScheduledDrop = async (job, event, foremanId, date) => {
	if (!draggedService.value) return;
	// Only allow if dragging a scheduled job and target is a valid cell
	if (draggedService.value.status !== 'Scheduled') return;
	// Prevent dropping on same cell
	if (draggedService.value.name === job.name && draggedService.value.foreman === foremanId && draggedService.value.expectedStartDate === date) return;

	// Prevent dropping on Sunday or holidays
	if (isSunday(date) || isHoliday(date)) return;

	// Update job's foreman and date
	const serviceIndex = scheduledServices.value.findIndex(s => s.name === draggedService.value.name);
	if (serviceIndex !== -1) {
		try {
			await Api.updateServiceAppointmentScheduledDates(
				draggedService.value.name,
				date,
				draggedService.value.expectedEndDate,
				foremanId
			);
			scheduledServices.value[serviceIndex] = {
				...scheduledServices.value[serviceIndex],
				expectedStartDate: date,
				foreman: foremanId
			};
			notifications.addSuccess('Job moved successfully!');
		} catch (error) {
			notifications.addError('Failed to move job');
		}
	}
	isDragOver.value = false;
	dragOverCell.value = null;
	draggedService.value = null;
};

// Resize functionality
const startResize = (event, job, date) => {
	// Only allow resize from the right edge
	// Only allow if status is 'Scheduled' or 'Started'
	if (!(job.status === 'Scheduled' || job.status === 'Started')) return;

	const target = event.target;
	const rect = target.getBoundingClientRect();
	const clickX = event.clientX;
    
	// Check if click is on the resize handle or near right edge
	const isNearRightEdge = clickX > rect.right - 10;
	const isResizeHandle = target.classList.contains('resize-handle');
    
	if (!isNearRightEdge && !isResizeHandle) return;
    
	event.stopPropagation();
	event.preventDefault();
    
	// Set flag immediately to prevent modal from opening
	justFinishedResize.value = true;
    
	resizingJob.value = job;
	resizeStartX.value = event.clientX;
	resizeStartDate.value = date;
	originalEndDate.value = job.expectedEndDate || job.expectedStartDate;
    
	// Add global mouse move and mouse up listeners
	document.addEventListener('mousemove', handleResize);
	document.addEventListener('mouseup', stopResize);
    
	// Add visual feedback
	document.body.style.cursor = 'ew-resize';
};

const handleResize = (event) => {
	if (!resizingJob.value) return;
	
	const deltaX = event.clientX - resizeStartX.value;
	
	// Get actual cell width from DOM for accurate calculation
	const dayCell = document.querySelector('.day-cell');
	if (!dayCell) return;
	
	const cellWidth = dayCell.getBoundingClientRect().width;
	
	// Calculate how many days to extend with better snapping (0.4 threshold instead of 0.5)
	const daysToAdd = Math.floor(deltaX / cellWidth + 0.4);
	
	// Calculate new end date based on current end date + adjustment
	const currentEndDate = originalEndDate.value;
	const currentEndDateObj = parseLocalDate(currentEndDate);
	
	// Calculate proposed end date by adding days to the CURRENT end date
	let proposedEndDate = addDays(currentEndDate, daysToAdd);
	
	// Don't allow shrinking before the start date
	const startDate = resizingJob.value.expectedStartDate;
	if (parseLocalDate(proposedEndDate) < parseLocalDate(startDate)) {
		proposedEndDate = startDate;
	}
	
	let newEndDate = proposedEndDate;
	let extendsOverSunday = false;
	let hasHolidayBlock = false;
	const weekEndDate = addDays(weekStartDate.value, 6); // Saturday
	const proposedDate = parseLocalDate(proposedEndDate);
	const saturdayDate = parseLocalDate(weekEndDate);
	
	// Check for holidays in the EXTENSION range only (from current end to proposed end)
	const holidaysInRange = getHolidaysInRange(currentEndDate, proposedEndDate);
	if (holidaysInRange.length > 0) {
		hasHolidayBlock = true;
		// Allow the extension - visual split will be handled by getJobSegments
		newEndDate = proposedEndDate;
	}
	
	// Check if the proposed end date extends past Saturday or lands on Sunday
	if (proposedDate > saturdayDate || isSunday(proposedEndDate)) {
		extendsOverSunday = true;
		// Set logical end date to next Monday, but visually cap at Saturday
		newEndDate = getNextMonday(weekEndDate);
	} else if (!hasHolidayBlock && daysToAdd > 0) {
		// Check if any date in the EXTENSION range is Sunday (only if no holiday block)
		// Only check from current end to proposed end
		const startCheck = parseLocalDate(currentEndDate);
		const endCheck = parseLocalDate(proposedEndDate);
		for (let d = new Date(startCheck.getTime() + 86400000); d <= endCheck; d.setDate(d.getDate() + 1)) {
			const checkDate = toLocalDateString(d);
			if (isSunday(checkDate)) {
				extendsOverSunday = true;
				// Extend to next Monday
				newEndDate = getNextMonday(checkDate);
				break;
			}
		}
	}
	
	// Show popup if extending over Sunday
	showExtendToNextWeekPopup.value = extendsOverSunday;
	
	const serviceIndex = scheduledServices.value.findIndex(s => s.name === resizingJob.value.name);
	if (serviceIndex !== -1) {
		scheduledServices.value[serviceIndex] = {
			...scheduledServices.value[serviceIndex],
			expectedEndDate: newEndDate
		};
	}
};

const stopResize = async () => {
	if (!resizingJob.value) return;
	
	// Hide popup
	showExtendToNextWeekPopup.value = false;
	
	const job = resizingJob.value;
	
	// Find the updated job in services array (because resizingJob.value is a stale reference)
	const serviceIndex = scheduledServices.value.findIndex(s => s.name === job.name);
	if (serviceIndex === -1) return;
	
	const updatedJob = scheduledServices.value[serviceIndex];
	const newEndDate = updatedJob.expectedEndDate || updatedJob.expectedStartDate;
	console.log(`Proposed new end date for job ${job.projectTemplate}: ${newEndDate}`);
	
	// Only update if end date changed
	if (newEndDate !== originalEndDate.value) {
		const weekEnd = addDays(weekStartDate.value, 6); // Saturday
		const extendsToNextWeek = parseLocalDate(newEndDate) > parseLocalDate(weekEnd);
		
		if (extendsToNextWeek) {
			notifications.addInfo(`Job extended to next Monday (${formatDate(newEndDate)})`);
		}
		
		console.log(`Extended job ${job.projectTemplate} from ${originalEndDate.value} to ${newEndDate}`);
		
		// Call API to persist changes
		try {
			await Api.updateServiceAppointmentScheduledDates(
				job.name,
				job.expectedStartDate,
				newEndDate,
				job.foreman
			);
			notifications.addSuccess("Job end date updated successfully!");
		} catch (error) {
			console.error("Error updating job end date:", error);
			notifications.addError("Failed to update job end date");
			// Revert on error
			const serviceIndex = scheduledServices.value.findIndex(s => s.name === job.name);
			if (serviceIndex !== -1) {
				scheduledServices.value[serviceIndex] = {
					...scheduledServices.value[serviceIndex],
					expectedEndDate: originalEndDate.value
				};
			}
		}
	}
	
	// Clean up
	document.removeEventListener('mousemove', handleResize);
	document.removeEventListener('mouseup', stopResize);
	document.body.style.cursor = 'default';
	
	// Keep flag set to prevent modal from opening on click after resize
	// Reset after a longer delay to catch any pending click events
	setTimeout(() => {
		justFinishedResize.value = false;
	}, 150);
	
	resizingJob.value = null;
	resizeStartX.value = 0;
	resizeStartDate.value = null;
	originalEndDate.value = null;
};

const handleServiceAptToFind = async () => {
	if (!serviceAptToFind) return;
	
	try {
		// Fetch the specific service appointment
		const appointment = await Api.getServiceAppointment(serviceAptToFind);
		
		if (appointment && appointment.expectedStartDate) {
			// Navigate to the week containing this appointment
			weekStartDate.value = getWeekStart(parseLocalDate(appointment.expectedStartDate));
			
			// Wait for data to load
			await fetchServiceAppointments();
			
			// Find the appointment in the loaded data
			const foundAppointment = scheduledServices.value.find(s => s.name === serviceAptToFind) ||
				unscheduledServices.value.find(s => s.name === serviceAptToFind);
			
			if (foundAppointment) {
				// Open the details modal
				selectedEvent.value = foundAppointment;
				eventDialog.value = true;
			} else {
				notifications.addWarning("Service appointment found but not visible in current filters");
			}
		} else {
			notifications.addWarning("Service appointment not scheduled yet");
		}
	} catch (error) {
		console.error("Error finding service appointment:", error);
		notifications.addError("Failed to find service appointment");
	}
};

const fetchServiceAppointments = async (currentDate) => {
	try {
		// Calculate date range for the week
		const startDate = weekStartDate.value;
		const endDate = addDays(startDate, 6);
		
		// const data = await Api.getJobsForCalendar(startDate, endDate, companyStore.currentCompany, selectedProjectTemplates.value);
		scheduledServices.value = await Api.getServiceAppointments(
			[companyStore.currentCompany],
			{ 
				"expectedStartDate": ["<=", endDate],
				"expectedEndDate": [">=", startDate],
				"status": ["not in", ["Canceled", "Open"]]
			}
			);
		unscheduledServices.value = await Api.getServiceAppointments(
			[companyStore.currentCompany],
			{
				"status": "Open",
				"ready_to_schedule": 1
			}
		);
		
		console.log("Loaded service appointments:", scheduledServices.value);
		console.log("Loaded unscheduled service appointments:", unscheduledServices.value);
	} catch (error) {
		console.error("Error loading service appointments:", error);
		notifications.addError("Failed to load service appointments");
	}
};

const fetchForemen = async () => {
	try {
		const data = await Api.getEmployees(companyStore.currentCompany, ["Foreman"]);
		foremen.value = data;
		// Update selected foremen to use customCrew numbers or foreman name as fallback
		selectedForemen.value = data.map(f => {
			if (f.customCrew && f.customCrew.trim() !== '') {
				return parseInt(f.customCrew);
			}
			return f.name; // Use employee ID as fallback
		});
		console.log("Loaded foremen:", data);
		console.log("Selected foremen IDs:", selectedForemen.value);
	} catch (error) {
		console.error("Error loading foremen:", error);
		notifications.addError("Failed to load foremen");
	}
};

const fetchProjectTemplates = async () => {
	try {
		const data = await Api.getJobTemplates(companyStore.currentCompany);
		projectTemplates.value = data;
		// Select all templates by default
		selectedProjectTemplates.value = data.map(t => t.name);
		console.log("Loaded project templates:", data);
	}
	catch (error) {
		console.error("Error loading project templates:", error);
		notifications.addError("Failed to load project templates");
	}
}

const fetchHolidays = async () => {
	try {
		const data = await Api.getWeekHolidays(weekStartDate.value);
		holidays.value = data;
		console.log("Loaded holidays:", data);
	} catch (error) {
		console.error("Error loading holidays:", error);
		notifications.addError("Failed to load holidays");
	}
}

watch(weekStartDate, async () => {
	// await fetchProjects();
	await fetchServiceAppointments();
	await fetchHolidays();
});

watch(companyStore, async () => {
	await fetchForemen();
	await fetchProjectTemplates();
	// await fetchProjects();
	await fetchServiceAppointments();
}, { deep: true });

// Lifecycle
onMounted(async () => {
	await fetchForemen();
	await fetchProjectTemplates();
	// await fetchProjects();
	await fetchServiceAppointments();
	await fetchHolidays();
	
	// Handle serviceAptToFind query parameter
	await handleServiceAptToFind();
});
</script>

<style scoped>
.calendar-container {
	padding: 20px;
	height: 100%;
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.calendar-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 20px;
	padding-bottom: 15px;
	border-bottom: 1px solid var(--surface-border);
	flex-shrink: 0;
}

.header-controls {
	display: flex;
	gap: 12px;
	align-items: center;
}

.week-display-btn {
	font-weight: 600;
	font-size: 1.1em;
	color: var(--theme-primary) !important;
	text-transform: none;
	letter-spacing: normal;
	min-width: 320px;
	max-width: 320px;
}

.week-display-btn:hover {
	background-color: rgba(25, 118, 210, 0.08);
}

.date-text {
	display: inline-block;
	text-align: center;
	width: 100%;
}

.calendar-main {
	display: flex;
	gap: 20px;
	flex: 1;
	overflow: hidden;
}

.calendar-section {
	flex: 1;
	overflow: auto;
}

.weekly-calendar {
	min-width: 1000px;
	background: white;
	border-radius: 8px;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
	overflow-x: auto;
}

.calendar-header-row {
	display: grid;
	border-bottom: 2px solid var(--surface-border);
	background-color: var(--surface-hover);
	position: sticky;
	top: 0;
	z-index: 100;
}

.crew-column-header {
	padding: 16px 8px;
	font-weight: 600;
	text-align: center;
	border-right: 1px solid var(--surface-border);
	color: var(--theme-text-muted);
	background-color: var(--surface-hover);
}

.day-header {
	padding: 12px 8px;
	text-align: center;
	border-right: 1px solid var(--surface-border);
	transition: background-color 0.2s;
}

.day-header.today {
	background-color: rgba(33, 150, 243, 0.1);
}

.day-name {
	font-weight: 600;
	font-size: 0.9em;
	margin-bottom: 4px;
	color: var(--theme-primary);
}

.day-date {
	font-size: 0.8em;
	color: var(--theme-text-muted);
	font-weight: 500;
}

.calendar-grid {
	display: flex;
	flex-direction: column;
}

.foreman-row {
	display: grid;
	min-height: 80px;
	border-bottom: 1px solid var(--surface-border);
}

.crew-column {
	padding: 12px 8px;
	border-right: 1px solid var(--surface-border);
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	background-color: var(--surface-hover);
}

.crew-name {
	font-weight: 600;
	font-size: 0.9em;
	color: var(--theme-primary);
	margin-bottom: 4px;
	text-align: center;
}

.crew-number {
	font-size: 0.75em;
	color: var(--theme-text-muted);
	font-weight: 500;
}

.day-cell {
	border-right: 1px solid var(--surface-border);
	position: relative;
	cursor: pointer;
	transition: background-color 0.2s;
	min-height: 80px;
	max-height: 80px;
	padding: 4px;
	overflow: visible; /* Allow multi-day jobs to overflow */
	width: 100%; /* Ensure cell doesn't expand */
}

.day-cell:hover {
	background-color: var(--theme-surface-alt);
}

.day-cell.today {
	background-color: rgba(33, 150, 243, 0.05);
}

.day-cell.drag-over {
	background-color: #e8f5e8;
	border: 2px dashed #4caf50;
	box-sizing: border-box;
}

.calendar-job {
	position: absolute;
	left: 4px;
	top: 4px;
	background: linear-gradient(135deg, #2196f3, #1976d2);
	color: white;
	border-radius: 4px;
	padding: 8px 10px;
	font-size: 0.85em;
	cursor: pointer;
	overflow: hidden;
	box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
	transition: all 0.2s;
	display: flex;
	align-items: center;
	min-height: 68px;
	height: calc(100% - 8px);
	max-width: none; /* Allow spanning */
}

.calendar-job:hover {
	transform: scale(1.02);
	box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}

.calendar-job:hover .resize-handle {
	opacity: 1;
}

.calendar-job[draggable="true"] {
	cursor: grab;
}

.calendar-job[draggable="true"]:active {
	cursor: grabbing;
}

.job-content {
	flex: 1;
	overflow: hidden;
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.job-title {
	font-weight: 600;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	margin-bottom: 4px;
	font-size: 0.95em;
}

.job-address {
	font-size: 0.8em;
	opacity: 0.9;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	line-height: 1.3;
}

.resize-handle {
	position: absolute;
	right: 0;
	top: 0;
	bottom: 0;
	width: 20px;
	background: rgba(255, 255, 255, 0.2);
	cursor: ew-resize;
	opacity: 0.3;
	transition: all 0.2s;
	border-left: 3px solid rgba(255, 255, 255, 0.6);
}

.resize-handle:hover {
	background: rgba(255, 255, 255, 0.4);
	opacity: 1;
	border-left: 3px solid rgba(255, 255, 255, 0.9);
}

.spans-arrow-left {
	position: absolute;
	left: 5px;
	top: 50%;
	transform: translateY(-50%);
	color: rgba(255, 255, 255, 0.8);
}

.spans-arrow-right {
	position: absolute;
	right: 25px; /* Position before resize handle */
	top: 50%;
	transform: translateY(-50%);
	color: rgba(255, 255, 255, 0.8);
}

.unscheduled-section {
	width: 280px;
	border-left: 1px solid #e0e0e0;
	padding-left: 16px;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	flex-shrink: 0;
}

.unscheduled-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 12px;
	flex-shrink: 0;
}

.unscheduled-header h4 {
	font-size: 1.1em;
	margin: 0;
}

.unscheduled-list {
	flex: 1;
	overflow-y: auto;
	overflow-x: hidden;
	transition: all 0.3s ease;
	border-radius: 8px;
}

.unscheduled-list.unscheduled-drop-zone {
	background-color: #e8f5e8;
	border: 2px dashed #4caf50;
	box-sizing: border-box;
}

.unscheduled-item {
	border-left: 3px solid transparent;
	transition: all 0.3s ease;
}

.unscheduled-item:hover {
	transform: translateX(3px);
}

.unscheduled-item[draggable="true"] {
	cursor: grab;
}

.unscheduled-item[draggable="true"]:active {
	cursor: grabbing;
}

.priority-urgent {
	border-left-color: #f44336 !important;
}

.priority-high {
	border-left-color: #ff9800 !important;
}

.priority-medium {
	border-left-color: #ffeb3b !important;
}

.priority-low {
	border-left-color: #4caf50 !important;
}

.service-title-compact {
	font-weight: 600;
	font-size: 0.9em;
	color: #1976d2;
	line-height: 1.2;
}

.service-customer {
	font-size: 0.8em;
	color: #666;
	margin-top: 2px;
}

.service-compact-details {
	display: flex;
	align-items: center;
	gap: 8px;
}

.service-notes-compact {
	background-color: #f8f9fa;
	padding: 4px 6px;
	border-radius: 3px;
	border-left: 2px solid #2196f3;
}

.service-notes-compact .text-caption {
	font-style: italic;
	color: #666;
	line-height: 1.3;
}

.no-unscheduled {
	text-align: center;
	padding: 40px 20px;
	color: #666;
}

.day-cell.holiday {
	background: repeating-linear-gradient(
		45deg,
		rgba(255, 193, 7, 0.15),
		rgba(255, 193, 7, 0.15) 10px,
		rgba(255, 193, 7, 0.05) 10px,
		rgba(255, 193, 7, 0.05) 20px
	);
	border-left: 3px solid #ffc107;
	border-right: 3px solid #ffc107;
}

.day-cell.sunday {
	background-color: rgba(200, 200, 200, 0.1); /* light gray for Sunday */
}

.holiday-connector {
	position: absolute;
	left: 4px;
	right: 4px;
	top: 50%;
	height: 3px;
	transform: translateY(-50%);
	border-top: 3px dotted currentColor;
	opacity: 0.6;
	pointer-events: none;
	z-index: 5;
}

.holiday-connector.priority-urgent {
	color: #f44336;
}

.holiday-connector.priority-high {
	color: #ff9800;
}

.holiday-connector.priority-medium {
	color: #2196f3;
}

.holiday-connector.priority-low {
	color: #4caf50;
}

.extend-popup {
	position: fixed;
	top: 100px;
	left: 50%;
	transform: translateX(-50%);
	background: rgba(33, 150, 243, 0.95);
	color: white;
	padding: 12px 20px;
	border-radius: 8px;
	font-size: 1em;
	font-weight: 600;
	pointer-events: none;
	z-index: 10000;
	white-space: nowrap;
	box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
	border: 2px solid rgba(255, 255, 255, 0.3);
	animation: slideDown 0.2s ease-out;
}

@keyframes slideDown {
	from {
		opacity: 0;
		transform: translateX(-50%) translateY(-10px);
	}
	to {
		opacity: 1;
		transform: translateX(-50%) translateY(0);
	}
}

.service-address {
	font-size: 0.85em;
	color: #555;
	display: flex;
	align-items: center;
	line-height: 1.4;
}
</style>