<template>
	<div class="schedule-bid-container">
		<!-- Header -->
		<div class="header">
			<h2>Bid Schedule</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="goToCurrentWeek" variant="outlined" size="small" class="ml-4"
					>This Week</v-btn
				>
				<v-btn
					@click="openNewMeetingModal"
					variant="elevated"
					size="small"
					color="primary"
					class="ml-4"
				>
					<v-icon left size="small">mdi-plus</v-icon>
					New
				</v-btn>
			</div>
		</div>

		<!-- Date Picker Dialog -->
		<v-dialog v-model="showDatePicker" max-width="400px">
			<v-card>
				<v-card-title>Select Date</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>

		<!-- Main Content Layout -->
		<div class="main-layout">
			<!-- Weekly Calendar -->
			<div class="calendar-section">
				<div class="weekly-calendar">
					<!-- Days of Week Header -->
					<div class="calendar-header-row">
						<div class="time-column-header">Time</div>
						<div
							v-for="day in weekDays"
							:key="day.date"
							class="day-header"
							:class="{ today: day.isToday }"
						>
							<div class="day-name">{{ day.dayName }}</div>
							<div class="day-date">{{ day.displayDate }}</div>
							<div class="meetings-count">
								{{ getDayMeetingsCount(day.date) }} meetings
							</div>
						</div>
					</div>

					<!-- Time Grid -->
					<div class="calendar-grid">
						<div
							v-for="timeSlot in businessHours"
							:key="timeSlot.time"
							class="time-row"
						>
							<!-- Time Column -->
							<div class="time-column">
								<span class="time-label">{{ timeSlot.display }}</span>
							</div>

							<!-- Day Columns -->
							<div
								v-for="day in weekDays"
								:key="`${day.date}-${timeSlot.time}`"
								class="day-column"
								:class="{
									'current-time': isCurrentTimeSlot(day.date, timeSlot.time),
									'past-time': isPastTimeSlot(day.date, timeSlot.time),
									'drag-over':
										isDragOver &&
										dragOverSlot?.date === day.date &&
										dragOverSlot?.time === timeSlot.time,
									weekend: day.isWeekend,
								}"
								@click="selectTimeSlot(day.date, timeSlot.time)"
								@dragover="handleDragOver($event, day.date, timeSlot.time)"
								@dragleave="handleDragLeave"
								@drop="handleDrop($event, day.date, timeSlot.time)"
							>
								<!-- Meetings in this time slot -->
								<div
									v-for="meeting in getMeetingsForTimeSlot(
										day.date,
										timeSlot.time,
									)"
									:key="meeting.id"
									class="meeting-event"
									:class="[getMeetingColorClass(meeting), { 'meeting-completed-locked': meeting.status === 'Completed' }]"
									:draggable="meeting.status !== 'Completed'"
									@dragstart="handleMeetingDragStart($event, meeting)"
									@dragend="handleDragEnd($event)"
									@click.stop="showMeetingDetails(meeting)"
								>
									<div class="event-time">
										{{ formatTimeDisplay(meeting.scheduledTime) }}
									</div>
									<div class="event-address">{{ meeting.address.fullAddress }}</div>
									<div class="event-client" v-if="meeting.client">
										{{ meeting.client }}
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>

			<!-- Right Sidebar for Unscheduled Meetings -->
			<div class="sidebar sidebar-right" :class="{ collapsed: isSidebarCollapsed }">
				<div class="sidebar-header">
					<div class="sidebar-title">
						<h4 v-if="!isSidebarCollapsed">Unscheduled Meetings</h4>
						<v-chip color="warning" size="small">{{
							unscheduledMeetings.length
						}}</v-chip>
					</div>
					<v-btn
						@click="isSidebarCollapsed = !isSidebarCollapsed"
						:icon="isSidebarCollapsed ? 'mdi-chevron-left' : 'mdi-chevron-right'"
						variant="text"
						size="small"
						density="compact"
					></v-btn>
				</div>
				<div
					v-if="!isSidebarCollapsed"
					class="unscheduled-meetings-list"
					:class="{ 'drag-over-unscheduled': isUnscheduledDragOver }"
					@dragover="handleUnscheduledDragOver"
					@dragleave="handleUnscheduledDragLeave"
					@drop="handleDropToUnscheduled"
				>
					<div v-if="unscheduledMeetings.length === 0" class="empty-state">
						<v-icon size="large" color="grey-lighten-1">mdi-calendar-check</v-icon>
						<p>No unscheduled meetings</p>
					</div>
					<v-card
						v-for="meeting in unscheduledMeetings"
						:key="meeting.name"
						class="meeting-card mb-3"
						elevation="2"
						hover
						draggable="true"
						@dragstart="handleDragStart($event, meeting)"
						@dragend="handleDragEnd($event)"
						@click="showMeetingDetails(meeting)"
					>
						<v-card-text class="pa-2">
							<div class="unscheduled-address">
								<v-icon size="x-small" class="mr-1">mdi-map-marker</v-icon>
								{{ meeting.address?.fullAddress || meeting.address }}
							</div>
							<div v-if="meeting.contact?.name" class="unscheduled-contact">
								<v-icon size="x-small" class="mr-1">mdi-account</v-icon>
								{{ meeting.contact.name }}
							</div>
							<div v-if="meeting.projectTemplate" class="unscheduled-project">
								<v-icon size="x-small" class="mr-1">mdi-file-document</v-icon>
								{{ meeting.projectTemplate }}
							</div>
							<div class="unscheduled-status">
								<v-chip size="x-small" :color="getStatusColor(meeting.status)">
									{{ meeting.status }}
								</v-chip>
							</div>
						</v-card-text>
					</v-card>
				</div>
			</div>
		</div>

		<!-- Meeting Details Modal -->
		<MeetingDetailsModal
			:visible="showMeetingModal"
			@update:visible="showMeetingModal = $event"
			:meeting="selectedMeeting"
			@close="closeMeetingModal"
			@meeting-updated="handleMeetingUpdated"
			@complete-meeting="openNoteForm"
		/>

		<!-- New Meeting Modal -->
		<BidMeetingModal
			:visible="showNewMeetingModal"
			@update:visible="showNewMeetingModal = $event"
			:initial-address="queryAddress"
			@confirm="handleNewMeetingConfirm"
			@cancel="handleNewMeetingCancel"
		/>

		<!-- Bid Meeting Note Form Modal -->
		<BidMeetingNoteForm
			v-if="selectedMeetingForNotes"
			:visible="showNoteFormModal"
			@update:visible="showNoteFormModal = $event"
			:bid-meeting-name="selectedMeetingForNotes.name"
			:project-template="selectedMeetingForNotes.projectTemplate"
			@submit="handleNoteFormSubmit"
			@cancel="handleNoteFormCancel"
		/>
	</div>
</template>

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

const route = useRoute();
const router = useRouter();
const loadingStore = useLoadingStore();
const notificationStore = useNotificationStore();
const companyStore = useCompanyStore();

// Query parameters
const isNewMode = computed(() => route.query.new === "true");
const queryAddress = computed(() => route.query.address || "");
const queryMeetingName = computed(() => route.query.name || "");

// Date management
const currentWeekStart = ref(new Date());
const showDatePicker = ref(false);
const selectedDate = ref(null);

// Calendar state
const meetings = ref([]);
const unscheduledMeetings = ref([]);
const selectedMeeting = ref(null);
const showMeetingModal = ref(false);
const showNewMeetingModal = ref(false);
const showNoteFormModal = ref(false);
const selectedMeetingForNotes = ref(null);

// Drag and drop state
const isDragOver = ref(false);
const dragOverSlot = ref(null);
const draggedMeeting = ref(null);
const originalMeetingForReschedule = ref(null); // Store original meeting data for reschedules
const isUnscheduledDragOver = ref(false);

// Sidebar state
const isSidebarCollapsed = ref(false);

// Business hours (8 AM to 6 PM)
const businessHours = computed(() => {
	const hours = [];
	for (let hour = 8; hour <= 18; hour++) {
		const time = `${hour.toString().padStart(2, "0")}:00`;
		const displayHour = hour > 12 ? hour - 12 : hour === 0 ? 12 : hour;
		const ampm = hour >= 12 ? "PM" : "AM";
		const display = `${displayHour}:00 ${ampm}`;

		hours.push({ time, display });

		// Add 30-minute slot (except for the last hour)
		if (hour < 18) {
			const halfTime = `${hour.toString().padStart(2, "0")}:30`;
			const halfDisplay = `${displayHour}:30 ${ampm}`;
			hours.push({ time: halfTime, display: halfDisplay });
		}
	}
	return hours;
});

// Week display
const weekDays = computed(() => {
	const days = [];
	const startOfWeek = new Date(currentWeekStart.value);
	startOfWeek.setDate(startOfWeek.getDate() - startOfWeek.getDay()); // Get Sunday

	for (let i = 0; i < 7; i++) {
		const day = new Date(startOfWeek);
		day.setDate(startOfWeek.getDate() + i);

		const today = new Date();
		const isToday = day.toDateString() === today.toDateString();
		const isWeekend = day.getDay() === 0 || day.getDay() === 6;

		days.push({
			date: day.toISOString().split("T")[0],
			dayName: day.toLocaleDateString("en-US", { weekday: "short" }),
			displayDate: day.toLocaleDateString("en-US", { month: "short", day: "numeric" }),
			isToday,
			isWeekend,
		});
	}
	return days;
});

const weekDisplayText = computed(() => {
	const startOfWeek = new Date(currentWeekStart.value);
	startOfWeek.setDate(startOfWeek.getDate() - startOfWeek.getDay());

	const endOfWeek = new Date(startOfWeek);
	endOfWeek.setDate(startOfWeek.getDate() + 6);

	const startMonth = startOfWeek.toLocaleDateString("en-US", { month: "short" });
	const endMonth = endOfWeek.toLocaleDateString("en-US", { month: "short" });
	const startDay = startOfWeek.getDate();
	const endDay = endOfWeek.getDate();
	const year = startOfWeek.getFullYear();

	if (startMonth === endMonth) {
		return `${startMonth} ${startDay}-${endDay}, ${year}`;
	} else {
		return `${startMonth} ${startDay} - ${endMonth} ${endDay}, ${year}`;
	}
});

// Modal options - keeping these for backward compatibility if needed
const meetingModalOptions = computed(() => ({
	maxWidth: "600px",
	showCancelButton: false,
	confirmButtonText: "Close",
	confirmButtonColor: "primary",
}));

// Methods
const initializeWeek = () => {
	const today = new Date();
	currentWeekStart.value = new Date(today.getFullYear(), today.getMonth(), today.getDate());
};

const previousWeek = () => {
	const newDate = new Date(currentWeekStart.value);
	newDate.setDate(newDate.getDate() - 7);
	currentWeekStart.value = newDate;
	loadWeekMeetings();
};

const nextWeek = () => {
	const newDate = new Date(currentWeekStart.value);
	newDate.setDate(newDate.getDate() + 7);
	currentWeekStart.value = newDate;
	loadWeekMeetings();
};

const goToCurrentWeek = () => {
	initializeWeek();
	loadWeekMeetings();
};

const onDateSelected = (date) => {
	if (date) {
		const dateObj = Array.isArray(date) ? date[0] : date;
		currentWeekStart.value = new Date(
			dateObj.getFullYear(),
			dateObj.getMonth(),
			dateObj.getDate(),
		);
		showDatePicker.value = false;
		loadWeekMeetings();
	}
};

const getMeetingsForTimeSlot = (date, time) => {
	if (!Array.isArray(meetings.value)) {
		return [];
	}
	return meetings.value.filter((meeting) => {
		if (meeting.date !== date) return false;

		// Check if the meeting starts at this time slot
		const meetingTime = meeting.scheduledTime;
		return meetingTime === time;
	});
};

const getDayMeetingsCount = (date) => {
	if (!Array.isArray(meetings.value)) {
		return 0;
	}
	return meetings.value.filter((meeting) => meeting.date === date).length;
};

const isCurrentTimeSlot = (date, time) => {
	const now = new Date();
	const today = now.toISOString().split("T")[0];
	const currentHour = now.getHours();
	const currentMinute = now.getMinutes();
	const currentTime = `${currentHour.toString().padStart(2, "0")}:${currentMinute >= 30 ? "30" : "00"}`;

	return date === today && time === currentTime;
};

const isPastTimeSlot = (date, time) => {
	const now = new Date();
	const slotDateTime = new Date(`${date}T${time}:00`);
	return slotDateTime < now;
};

const getMeetingColorClass = (meeting) => {
	if (meeting.status === "Completed") {
		return "meeting-completed";
	}

	// Check if meeting is in the past based on end time
	if (meeting.endTime) {
		const endDateTime = new Date(meeting.endTime);
		const now = new Date();

		if (endDateTime < now && meeting.status !== "Completed") {
			return "meeting-overdue";
		}
	}

	// Default: scheduled and in the future
	return "meeting-scheduled";
};

const formatTimeDisplay = (time) => {
	const [hours, minutes] = time.split(":").map(Number);
	const displayHour = hours > 12 ? hours - 12 : hours === 0 ? 12 : hours;
	const ampm = hours >= 12 ? "PM" : "AM";
	return `${displayHour}:${minutes.toString().padStart(2, "0")} ${ampm}`;
};

const formatDate = (dateStr) => {
	const date = new Date(dateStr);
	return date.toLocaleDateString("en-US", {
		weekday: "long",
		year: "numeric",
		month: "long",
		day: "numeric",
	});
};

const formatDateForUrl = (date) => {
	return date.toISOString().split("T")[0];
};

const getAddressText = (address) => {
	if (!address) return "";
	if (typeof address === "string") return address;
	return address.full_address || address.fullAddress || address.name || "";
};

const selectTimeSlot = (date, time) => {
	console.log("Selected time slot:", date, time);
};

const showMeetingDetails = (meeting) => {
	selectedMeeting.value = meeting;
	showMeetingModal.value = true;
};

const closeMeetingModal = () => {
	showMeetingModal.value = false;
	selectedMeeting.value = null;
};

const handleMeetingUpdated = async () => {
	// Reload both scheduled and unscheduled meetings
	await loadWeekMeetings();
	await loadUnscheduledMeetings();
};

const openNoteForm = (meeting) => {
	// Verify meeting has required data
	if (!meeting || !meeting.name) {
		notificationStore.addNotification({
			type: "error",
			title: "Error",
			message: "Meeting information is incomplete",
			duration: 5000,
		});
		return;
	}

	if (!meeting.projectTemplate) {
		notificationStore.addNotification({
			type: "error",
			title: "Missing Project Template",
			message: "This meeting does not have a project template assigned. Cannot open note form.",
			duration: 5000,
		});
		return;
	}

	selectedMeetingForNotes.value = meeting;
	showNoteFormModal.value = true;
};

const handleNoteFormSubmit = async () => {
	// After successful submission, mark the meeting as completed
	try {
		loadingStore.setLoading(true);
		await Api.updateBidMeeting(selectedMeetingForNotes.value.name, {
			status: "Completed",
		});

		notificationStore.addNotification({
			type: "success",
			title: "Success",
			message: "Meeting marked as completed",
			duration: 5000,
		});

		// Reload meetings
		await handleMeetingUpdated();
	} catch (error) {
		console.error("Error updating meeting status:", error);
	} finally {
		loadingStore.setLoading(false);
		showNoteFormModal.value = false;
		selectedMeetingForNotes.value = null;
	}
};

const handleNoteFormCancel = () => {
	showNoteFormModal.value = false;
	selectedMeetingForNotes.value = null;
};

const openNewMeetingModal = () => {
	showNewMeetingModal.value = true;
};

const handleNewMeetingConfirm = async (meetingData) => {
	console.log("Creating new meeting:", meetingData);

	try {
		loadingStore.setLoading(true);

		// Create the meeting via API
		const result = await Api.createBidMeeting(meetingData);

		showNewMeetingModal.value = false;

		// Optimistically add the new meeting to the unscheduled list
		unscheduledMeetings.value.unshift({
			name: result.name,
			address: meetingData.address,
			projectTemplate: meetingData.projectTemplate,
			contact: meetingData.contact,
			status: "Unscheduled",
		});

		// Reload unscheduled meetings to ensure consistency
		await loadUnscheduledMeetings();

		notificationStore.addNotification({
			type: "success",
			title: "Success",
			message: "Meeting created successfully. Drag it to the calendar to schedule a time.",
			duration: 5000,
		});

		console.log("Meeting created:", result);
	} catch (error) {
		console.error("Error creating meeting:", error);
		notificationStore.addNotification({
			type: "error",
			title: "Error",
			message: "Failed to create meeting. Please try again.",
			duration: 5000,
		});
	} finally {
		loadingStore.setLoading(false);
	}
};

const handleNewMeetingCancel = () => {
	showNewMeetingModal.value = false;
	// Clear query params after canceling
	router.push({
		path: "/schedule-bid",
		query: {
			date: formatDateForUrl(currentWeekStart.value),
		},
	});
};

// Drag and drop handlers
const handleDragStart = (event, meeting = null) => {
	// If a meeting object is passed, use it; otherwise use query address for new meetings
	if (meeting) {
		draggedMeeting.value = {
			id: meeting.name,
			address: meeting.address,
			notes: meeting.notes || "",
			assigned_employee: meeting.assigned_employee || "",
			status: meeting.status,
			projectTemplate: meeting.projectTemplate,
		};
	} else if (!draggedMeeting.value) {
		// If no meeting data is set, use query address
		draggedMeeting.value = {
			address: queryAddress.value,
			client: "",
			duration: 60,
			notes: "",
		};
	}
	event.dataTransfer.effectAllowed = "move";
	console.log("Drag started for meeting:", draggedMeeting.value);
};

const handleMeetingDragStart = (event, meeting) => {
	// Prevent dragging completed meetings
	if (meeting.status === 'Completed') {
		event.preventDefault();
		return;
	}
	
	// Handle dragging a scheduled meeting
	draggedMeeting.value = {
		id: meeting.name,
		address: meeting.address,
		notes: meeting.notes || "",
		assigned_employee: meeting.assigned_employee || "",
		status: meeting.status,
		isRescheduling: true, // Flag to indicate this is a reschedule
		projectTemplate: meeting.projectTemplate,
	};

	// Store the original meeting data in case drag is cancelled
	originalMeetingForReschedule.value = { ...meeting };

	event.dataTransfer.effectAllowed = "move";
	console.log("Rescheduling meeting:", draggedMeeting.value);
};

const resetDragState = () => {
	isDragOver.value = false;
	dragOverSlot.value = null;
	isUnscheduledDragOver.value = false;
	draggedMeeting.value = null;
	originalMeetingForReschedule.value = null;
};

const handleDragEnd = (event) => {
	// If drag was cancelled (not dropped successfully), restore the original meeting
	if (originalMeetingForReschedule.value && draggedMeeting.value?.isRescheduling) {
		// Meeting wasn't successfully dropped, so it's still in the array
		console.log("Drag cancelled, meeting remains in original position");
	}
	resetDragState();
};

const handleDragOver = (event, date, time) => {
	event.preventDefault();
	event.stopPropagation();

	if (!draggedMeeting.value) return;

	// Check if this is a past time slot
	if (isPastTimeSlot(date, time)) {
		event.dataTransfer.dropEffect = "none";
		return;
	}

	event.dataTransfer.dropEffect = "move";
	isDragOver.value = true;
	dragOverSlot.value = { date, time };
};

const handleDragLeave = (event) => {
	// Use a small delay to prevent flickering
	setTimeout(() => {
		if (!draggedMeeting.value) return;

		const calendarGrid = document.querySelector(".calendar-grid");
		if (!calendarGrid) return;

		const rect = calendarGrid.getBoundingClientRect();
		const x = event.clientX;
		const y = event.clientY;

		if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) {
			isDragOver.value = false;
			dragOverSlot.value = null;
		}
	}, 10);
};

const handleDrop = async (event, date, time) => {
	event.preventDefault();
	event.stopPropagation();

	if (!draggedMeeting.value) return;

	// Store the dragged meeting data locally before any async operations
	// This prevents issues if dragEnd fires before drop completes
	const droppedMeeting = { ...draggedMeeting.value };
	const originalMeeting = originalMeetingForReschedule.value
		? { ...originalMeetingForReschedule.value }
		: null;

	// Prevent dropping in past time slots
	if (isPastTimeSlot(date, time)) {
		notificationStore.addNotification({
			type: "error",
			title: "Invalid Time",
			message: "Cannot schedule meetings in the past",
			duration: 3000,
		});
		// If rescheduling failed, restore the meeting to its original position
		if (droppedMeeting.isRescheduling) {
			await loadWeekMeetings();
		}
		resetDragState();
		return;
	}

	// Create datetime string from date and time
	const startDateTime = `${date} ${time}:00`;

	// Calculate end time (1 hour later)
	const startDate = new Date(`${date}T${time}:00`);
	const endDate = new Date(startDate.getTime() + 60 * 60 * 1000);
	const endTime = `${endDate.getHours().toString().padStart(2, "0")}:${endDate.getMinutes().toString().padStart(2, "0")}:00`;
	const endDateTime = `${date} ${endTime}`;

	// Create new meeting with the dragged data
	const newMeeting = {
		id: droppedMeeting.id || Date.now(), // Use existing ID if available
		name: droppedMeeting.id, // Store the doctype name if it exists
		date,
		scheduledTime: time,
		address: droppedMeeting.address,
		notes: droppedMeeting.notes || "",
		assigned_employee: droppedMeeting.assigned_employee || "",
		status: "Scheduled",
		projectTemplate: droppedMeeting.projectTemplate,
	};

	// If this is an existing meeting, update it in the backend
	if (droppedMeeting.id) {
		try {
			loadingStore.setLoading(true);

			const updateData = {
				start_time: startDateTime,
				end_time: endDateTime,
				status: "Scheduled",
			};

			await Api.updateBidMeeting(droppedMeeting.id, updateData);

			// If this was a reschedule, remove the old meeting from its original position
			if (droppedMeeting.isRescheduling && originalMeeting) {
				const oldIndex = meetings.value.findIndex((m) => m.name === droppedMeeting.id);
				if (oldIndex !== -1) {
					meetings.value.splice(oldIndex, 1);
				}
			}

			// Add to meetings array at new position
			meetings.value.push(newMeeting);

			// Remove from unscheduled list (if it was unscheduled)
			if (!droppedMeeting.isRescheduling) {
				const index = unscheduledMeetings.value.findIndex(
					(m) => m.name === droppedMeeting.id,
				);
				if (index !== -1) {
					unscheduledMeetings.value.splice(index, 1);
				}
			}

			// Show success notification
			const actionText = droppedMeeting.isRescheduling ? "rescheduled" : "scheduled";
			notificationStore.addNotification({
				type: "success",
				title: `Meeting ${actionText.charAt(0).toUpperCase() + actionText.slice(1)}`,
				message: `On-site meeting ${actionText} for ${formatDate(date)} at ${formatTimeDisplay(time)}`,
				duration: 5000,
			});

			console.log("Meeting scheduled:", newMeeting);
		} catch (error) {
			console.error("Error scheduling meeting:", error);
			notificationStore.addNotification({
				type: "error",
				title: "Error",
				message: "Failed to schedule meeting. Please try again.",
				duration: 5000,
			});
			// On error, reload to restore correct state
			if (droppedMeeting.isRescheduling) {
				await loadWeekMeetings();
			}
		} finally {
			loadingStore.setLoading(false);
		}
	} else {
		// For new meetings without an ID, just add to the array
		meetings.value.push(newMeeting);
		notificationStore.addNotification({
			type: "success",
			title: "Meeting Scheduled",
			message: `On-site meeting scheduled for ${formatDate(date)} at ${formatTimeDisplay(time)}`,
			duration: 5000,
		});
	}

	// Reset drag state
	resetDragState();
};

const handleUnscheduledDragOver = (event) => {
	if (!draggedMeeting.value) return;
	event.preventDefault();
	event.dataTransfer.dropEffect = "move";
	isUnscheduledDragOver.value = true;
};

const handleUnscheduledDragLeave = () => {
	isUnscheduledDragOver.value = false;
};

const handleDropToUnscheduled = async (event) => {
	event.preventDefault();

	if (!draggedMeeting.value) return;

	const droppedMeeting = { ...draggedMeeting.value };

	// Only act when moving a scheduled meeting back to unscheduled
	if (!droppedMeeting.isRescheduling || !droppedMeeting.id) {
		resetDragState();
		return;
	}

	try {
		loadingStore.setLoading(true);

		await Api.updateBidMeeting(droppedMeeting.id, {
			status: "Unscheduled",
			start_time: null,
			end_time: null,
		});

		// Remove from the scheduled list
		meetings.value = meetings.value.filter(
			(meeting) => meeting.name !== droppedMeeting.id && meeting.id !== droppedMeeting.id,
		);

		// Add to unscheduled list if not already present
		const exists = unscheduledMeetings.value.some((m) => m.name === droppedMeeting.id);
		if (!exists) {
			unscheduledMeetings.value.unshift({
				name: droppedMeeting.id,
				address: getAddressText(droppedMeeting.address),
				notes: droppedMeeting.notes || "",
				status: "Unscheduled",
				assigned_employee: droppedMeeting.assigned_employee || "",
				projectTemplate: droppedMeeting.projectTemplate,
			});
		}

		notificationStore.addNotification({
			type: "success",
			title: "Meeting Unscheduled",
			message: "Meeting moved back to the unscheduled list",
			duration: 4000,
		});
	} catch (error) {
		console.error("Error unscheduling meeting:", error);
		notificationStore.addNotification({
			type: "error",
			title: "Error",
			message: "Failed to move meeting to unscheduled",
			duration: 5000,
		});
	} finally {
		loadingStore.setLoading(false);
		resetDragState();
	}
};

const loadUnscheduledMeetings = async () => {
	loadingStore.setLoading(true);
	try {
		const result = await Api.getUnscheduledBidMeetings(companyStore.currentCompany);
		// Ensure we always have an array
		unscheduledMeetings.value = Array.isArray(result) ? result : [];
		console.log("Loaded unscheduled meetings:", unscheduledMeetings.value);
	} catch (error) {
		console.error("Error loading unscheduled meetings:", error);
		unscheduledMeetings.value = [];
		notificationStore.addNotification({
			type: "error",
			title: "Error",
			message: "Failed to load unscheduled meetings",
			duration: 5000,
		});
	} finally {
		loadingStore.setLoading(false);
	}
};

const getStatusColor = (status) => {
	const statusColors = {
		Unscheduled: "warning",
		Scheduled: "info",
		Completed: "success",
		Cancelled: "error",
	};
	return statusColors[status] || "default";
};

const loadWeekMeetings = async () => {
	loadingStore.setLoading(true);
	try {
		// Calculate week start and end dates
		const weekStart = new Date(currentWeekStart.value);
		weekStart.setDate(weekStart.getDate() - weekStart.getDay());

		const weekEnd = new Date(weekStart);
		weekEnd.setDate(weekStart.getDate() + 6);

		// Format dates as YYYY-MM-DD strings for the API
		const weekStartStr = weekStart.toISOString().split("T")[0];
		const weekEndStr = weekEnd.toISOString().split("T")[0];

		console.log(`Loading meetings for week: ${weekStartStr} to ${weekEndStr}`);

		// Initialize as empty array first
		meetings.value = [];

		// Try to get meetings from API
		try {
			const apiResult = await Api.getWeekBidMeetings(weekStartStr, weekEndStr, companyStore.currentCompany);
			if (Array.isArray(apiResult)) {
				// Transform the API data to match what the calendar expects
				meetings.value = apiResult
					.map((meeting) => {
						// Extract date and time from startTime
						const startDateTime = meeting.startTime
							? new Date(meeting.startTime)
							: null;
						const date = startDateTime
							? startDateTime.toISOString().split("T")[0]
							: null;
						const time = startDateTime
							? `${startDateTime.getHours().toString().padStart(2, "0")}:${startDateTime.getMinutes().toString().padStart(2, "0")}`
							: null;

						// Return the full meeting object with calendar-specific fields added
						return {
							...meeting, // Keep all original fields
							id: meeting.name,
							date: date,
							scheduledTime: time,
						};
					})
					.filter((meeting) => meeting.date && meeting.scheduledTime); // Only include meetings with valid date/time
				console.log("Transformed meetings:", meetings.value);
			}
		} catch (apiError) {
			console.warn("API call failed, using empty array:", apiError);
			meetings.value = [];
		}

		// Simulate API response with dummy meetings (commented out for now)
		// meetings.value = [
		// 	{
		// 		id: 1,
		// 		date: weekDays.value[1]?.date, // Monday
		// 		scheduledTime: "10:00",
		// 		address: "123 Main St, Anytown, USA",
		// 		client: "John Doe",
		// 		duration: 60,
		// 		notes: "Initial consultation",
		// 		status: "scheduled",
		// 	},
		// 	{
		// 		id: 2,
		// 		date: weekDays.value[3]?.date, // Wednesday
		// 		scheduledTime: "14:30",
		// 		address: "456 Oak Ave, Somewhere, USA",
		// 		client: "Jane Smith",
		// 		duration: 90,
		// 		notes: "Follow-up meeting",
		// 		status: "scheduled",
		// 	},
		// ].filter((meeting) => meeting.date); // Filter out undefined dates
	} catch (error) {
		console.error("Error loading meetings:", error);
		// Ensure meetings is always an array even on error
		meetings.value = [];
		notificationStore.addNotification({
			type: "error",
			title: "Error",
			message: "Failed to load meetings",
			duration: 5000,
		});
	} finally {
		loadingStore.setLoading(false);
	}
};

const navigateToSpecificMeeting = async () => {
	if (queryAddress.value) {
		// TODO: Implement logic to find the meeting by address and navigate to its week
		// For now, simulate finding an existing meeting and show its details
		console.log("Navigating to specific meeting for address:", queryAddress.value);

		// Simulate finding the meeting and opening its details
		const mockMeeting = {
			id: 999,
			date: weekDays.value[2]?.date, // Tuesday
			scheduledTime: "11:00",
			address: queryAddress.value,
			client: "Existing Client",
			duration: 60,
			notes: "This meeting was found based on the address query parameter",
			status: "scheduled",
		};

		if (mockMeeting.date) {
			// Add to calendar for display
			meetings.value.push(mockMeeting);

			// Auto-open the details modal
			setTimeout(() => {
				showMeetingDetails(mockMeeting);
			}, 500);
		}
	}
};

const findAndDisplayMeetingByName = async () => {
	if (!queryMeetingName.value) return;

	console.log("Searching for meeting:", queryMeetingName.value);

	// First, search in the unscheduled meetings list
	const unscheduledMeeting = unscheduledMeetings.value.find(
		(m) => m.name === queryMeetingName.value
	);

	if (unscheduledMeeting) {
		console.log("Found in unscheduled meetings:", unscheduledMeeting);
		// Meeting is unscheduled, just show notification
		notificationStore.addNotification({
			type: "info",
			title: "Unscheduled Meeting",
			message: "This meeting has not been scheduled yet. Drag it to a time slot to schedule it.",
			duration: 6000,
		});
		return;
	}

	// Not in unscheduled list, fetch from API to get schedule details
	try {
		loadingStore.setLoading(true);
		const meetingData = await Api.getBidMeeting(queryMeetingName.value);
		
		if (!meetingData) {
			notificationStore.addNotification({
				type: "error",
				title: "Meeting Not Found",
				message: "Could not find the specified meeting.",
				duration: 5000,
			});
			return;
		}

		// Check if meeting is scheduled
		if (!meetingData.startTime) {
			notificationStore.addNotification({
				type: "info",
				title: "Unscheduled Meeting",
				message: "This meeting has not been scheduled yet.",
				duration: 5000,
			});
			return;
		}

		// Parse the start time to get date and time
		const startDateTime = new Date(meetingData.startTime);
		const meetingDate = startDateTime.toISOString().split("T")[0];
		const meetingTime = `${startDateTime.getHours().toString().padStart(2, "0")}:${startDateTime.getMinutes().toString().padStart(2, "0")}`;

		// Navigate to the week containing this meeting
		currentWeekStart.value = new Date(
			startDateTime.getFullYear(),
			startDateTime.getMonth(),
			startDateTime.getDate()
		);

		// Reload meetings for this week
		await loadWeekMeetings();

		// Find the meeting in the loaded meetings
		const scheduledMeeting = meetings.value.find(
			(m) => m.name === queryMeetingName.value
		);

		if (scheduledMeeting) {
			// Auto-open the meeting details modal
			setTimeout(() => {
				showMeetingDetails(scheduledMeeting);
			}, 300);
		} else {
			notificationStore.addNotification({
				type: "warning",
				title: "Meeting Found",
				message: `Meeting is scheduled for ${formatDate(meetingDate)} at ${formatTimeDisplay(meetingTime)}`,
				duration: 6000,
			});
		}
	} catch (error) {
		console.error("Error fetching meeting:", error);
		notificationStore.addNotification({
			type: "error",
			title: "Error",
			message: "Failed to load meeting details.",
			duration: 5000,
		});
	} finally {
		loadingStore.setLoading(false);
	}
};

// Lifecycle
onMounted(async () => {
	initializeWeek();
	await loadUnscheduledMeetings();
	await loadWeekMeetings();

	// Handle different modes based on query params
	if (isNewMode.value) {
		// New mode - always show create modal (with or without pre-filled address)
		setTimeout(() => {
			openNewMeetingModal();
		}, 500);
	} else if (queryMeetingName.value) {
		// Find and display specific meeting by name
		await findAndDisplayMeetingByName();
	} else if (queryAddress.value) {
		// View mode with address - find and show existing meeting details
		await navigateToSpecificMeeting();
	}
});

// Watch for week changes to reload data
watch(currentWeekStart, () => {
	loadWeekMeetings();
});

// Watch for company changes
watch(
	() => companyStore.currentCompany,
	async () => {
		await loadWeekMeetings();
		await loadUnscheduledMeetings();
	}
);

watch(
	() => route.query.new,
	(newVal) => {
		if (newVal === "true") {
			openNewMeetingModal();
		}
	},
);
</script>

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

.header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 20px;
	padding-bottom: 15px;
	border-bottom: 1px solid #e0e0e0;
	flex-shrink: 0;
}

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

.week-display-btn {
	font-weight: 600;
	font-size: 1.1em;
	color: #1976d2 !important;
	text-transform: none;
	letter-spacing: normal;
	min-width: 280px;
	max-width: 280px;
}

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

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

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

.sidebar {
	width: 280px;
	padding: 0 16px;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	transition: width 0.3s ease;
	flex-shrink: 0;
}

.sidebar.collapsed {
	width: 60px;
	min-width: 60px;
}

.sidebar-right {
	border-left: 1px solid #e0e0e0;
	padding-left: 16px;
}

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

.sidebar-title {
	display: flex;
	align-items: center;
	gap: 8px;
	flex: 1;
}

.sidebar-header h4 {
	font-size: 1.1em;
	margin: 0;
	flex-shrink: 0;
}

.unscheduled-meetings-list {
	flex: 1;
	overflow-y: auto;
	overflow-x: hidden;
	padding: 8px 0;
}

.unscheduled-meetings-list.drag-over-unscheduled {
	border: 2px dashed #4caf50;
	border-radius: 6px;
	background-color: #f0fff3;
}

.empty-state {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: 40px 20px;
	text-align: center;
	color: #999;
}

.empty-state p {
	margin-top: 12px;
	font-size: 0.9em;
}

.pending-meeting {
	flex: 1;
}

.meeting-card {
	border-left: 3px solid #2196f3;
	cursor: grab;
	transition: all 0.3s ease;
}

.meeting-card:hover {
	transform: translateX(3px);
	box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.meeting-card:active {
	cursor: grabbing;
}

.meeting-title {
	font-weight: 600;
	color: #1976d2;
	margin-bottom: 4px;
}

.meeting-address {
	font-size: 0.9em;
	color: #666;
	margin-bottom: 4px;
}

.meeting-duration {
	font-size: 0.8em;
	color: #999;
	display: flex;
	align-items: center;
}

.meeting-status {
	margin-top: 4px;
}

.meeting-notes {
	font-size: 0.85em;
	color: #666;
	margin-top: 4px;
	font-style: italic;
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
}

.meeting-employee {
	font-size: 0.8em;
	color: #999;
	margin-top: 4px;
	display: flex;
	align-items: center;
}

.unscheduled-address,
.unscheduled-contact,
.unscheduled-project {
	font-size: 0.8em;
	color: #666;
	margin-bottom: 4px;
	display: flex;
	align-items: center;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.unscheduled-address {
	font-weight: 600;
	color: #1976d2;
}

.unscheduled-status {
	margin-top: 6px;
	display: flex;
	justify-content: flex-start;
}

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

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

.calendar-header-row {
	display: grid;
	grid-template-columns: 80px repeat(7, 1fr);
	border-bottom: 2px solid #e0e0e0;
	background-color: #f8f9fa;
}

.time-column-header {
	padding: 16px 8px;
	font-weight: 600;
	text-align: center;
	border-right: 1px solid #e0e0e0;
	color: #666;
}

.day-header {
	padding: 12px 8px;
	text-align: center;
	border-right: 1px solid #e0e0e0;
	cursor: pointer;
	transition: background-color 0.2s;
}

.day-header:hover {
	background-color: #f0f0f0;
}

.day-header.today {
	background-color: #e3f2fd;
	color: #1976d2;
}

.day-name {
	font-weight: 600;
	font-size: 0.9em;
	margin-bottom: 4px;
}

.day-date {
	font-size: 0.8em;
	color: #666;
	margin-bottom: 4px;
}

.meetings-count {
	font-size: 0.7em;
	color: #999;
	font-weight: 500;
}

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

.time-row {
	display: grid;
	grid-template-columns: 80px repeat(7, 1fr);
	min-height: 40px;
	border-bottom: 1px solid #f0f0f0;
}

.time-row:nth-child(odd) {
	background-color: #fafafa;
}

.time-column {
	padding: 8px;
	border-right: 1px solid #e0e0e0;
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: #f8f9fa;
}

.time-label {
	font-size: 0.75em;
	color: #666;
	font-weight: 500;
}

.day-column {
	border-right: 1px solid #e0e0e0;
	position: relative;
	cursor: pointer;
	transition: background-color 0.2s;
	min-height: 40px;
}

.day-column:hover {
	background-color: #f0f8ff;
}

.day-column.current-time {
	background-color: #fff3e0;
}

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

.day-column.weekend {
	background-color: #f9f9f9;
}

.day-column.past-time {
	background-color: #fafafa;
	opacity: 0.6;
	cursor: not-allowed;
}

.day-column.past-time:hover {
	background-color: #fafafa;
}

.meeting-event {
	position: absolute;
	left: 2px;
	right: 2px;
	top: 2px;
	bottom: 2px;
	color: white;
	border-radius: 4px;
	padding: 4px 6px;
	font-size: 0.7em;
	cursor: grab;
	overflow: hidden;
	box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
	transition: all 0.2s;
	z-index: 10;
}

.meeting-event:active {
	cursor: grabbing;
}

.meeting-event.meeting-scheduled {
	background: linear-gradient(135deg, #2196f3, #1976d2);
}

.meeting-event.meeting-completed {
	background: linear-gradient(135deg, #4caf50, #388e3c);
}

.meeting-event.meeting-overdue {
	background: linear-gradient(135deg, #f44336, #d32f2f);
}

.meeting-event.meeting-completed-locked {
	cursor: default !important;
	opacity: 0.9;
}

.meeting-event.meeting-completed-locked:active {
	cursor: default !important;
}

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

.meeting-event.meeting-completed-locked:hover {
	transform: none;
}

.event-time {
	font-weight: 600;
	font-size: 0.8em;
	margin-bottom: 1px;
}

.event-address {
	font-size: 0.65em;
	opacity: 0.9;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	margin-bottom: 1px;
}

.event-client {
	font-size: 0.6em;
	opacity: 0.8;
	font-style: italic;
}

.meeting-details {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.detail-row {
	display: flex;
	align-items: center;
	gap: 8px;
}

.new-meeting-form {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.form-group {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.form-group label {
	font-weight: 500;
	color: #333;
	font-size: 0.9em;
}

/* Responsive design */
@media (max-width: 768px) {
	.main-layout {
		flex-direction: column;
	}

	.sidebar {
		width: 100%;
		border-right: none;
		border-bottom: 1px solid #e0e0e0;
		padding-right: 0;
		padding-bottom: 20px;
		max-height: 200px;
	}

	.calendar-header-row,
	.time-row {
		grid-template-columns: 60px repeat(7, 1fr);
	}
}
</style>
