<template>
	<div class="estimate-page">
		<h2>{{ isNew ? 'Create Estimate' : 'View Estimate' }}</h2>
		<div v-if="!isNew && estimate" class="page-actions">
			<div v-if="estimate && estimate.customSent === 1">
				<Button label="Estimate Response" @click="showResponseModal = true" />
			</div>
			<Button label="Duplicate" icon="pi pi-copy" @click="duplicateEstimate" />
		</div>

		<!-- Address Section -->
		<div class="address-section">
			<label for="address" class="field-label">
				Address
				<span class="required">*</span>
			</label>
			<div class="address-input-group">
				<InputText
					id="address"
					v-model="formData.address"
					placeholder="Enter address to search"
					:disabled="!isNew"
					fluid
				/>
				<Button
					label="Search"
					icon="pi pi-search"
					@click="searchAddresses"
					:disabled="!formData.address.trim() || !isNew"
					class="search-button"
				/>
			</div>
			<div v-if="selectedAddress" class="verification-info">
				<strong>Customer:</strong> {{ selectedAddress.customCustomerToBill }}
			</div>
		</div>

		<!-- Contact Section -->
		<div class="contact-section">
			<label for="contact" class="field-label">
				Contact
				<span class="required">*</span>
			</label>
			<Select
				:key="contactOptions.length"
				v-model="formData.contact"
				:options="contactOptions"
				optionLabel="label"
				optionValue="value"
				placeholder="Select a contact"
				:disabled="!formData.address || !isEditable"
				fluid
			>
				<template #option="slotProps">
					<div class="contact-option">
						<div class="contact-name">{{ slotProps.option.label }}</div>
						<div class="contact-detail" v-if="slotProps.option.email">{{ slotProps.option.email }}</div>
						<div class="contact-detail" v-if="slotProps.option.phone">{{ slotProps.option.phone }}</div>
					</div>
				</template>
			</Select>
			<div v-if="selectedContact" class="verification-info">
				<strong>Email:</strong> {{ selectedContact.emailId || "N/A" }} <br />
				<strong>Phone:</strong> {{ selectedContact.phone || "N/A" }} <br />
				<strong>Primary Contact:</strong>
				{{ selectedAddress?.primaryContact === selectedContact.name ? "Yes" : "No" }}
			</div>
		</div>



		<!-- Project Template Section -->
		<div class="project-template-section">
			<label for="projectTemplate" class="field-label">
				Project Template
				<span class="required">*</span>
				<i class="pi pi-question-circle help-icon" v-tooltip.right="'Used when generating a Project from this estimate. Defines tasks and default settings for the new Project.'"></i>
			</label>
			<Select
				v-model="formData.projectTemplate"
				:options="projectTemplates"
				optionLabel="name"
				optionValue="name"
				placeholder="Select a project template"
				:disabled="!isEditable"
				fluid
			/>
			<div v-if="isLoadingQuotationItems" class="loading-message">
				<i class="pi pi-spin pi-spinner"></i>
				<span>Loading available items...</span>
			</div>
		</div>

		<!-- Items Section -->
		<div class="items-section">
			<div class="items-header">
				<h3>Items</h3>
				<div v-if="isEditable" class="items-actions">
					<Button
						label="Add Item"
						icon="pi pi-plus"
						@click="showAddItemModal = true"
						:disabled="!hasQuotationItems || isLoadingQuotationItems"
						:loading="isLoadingQuotationItems"
					/>
					<Button
						label="Save as Package"
						icon="pi pi-save"
						@click="showSavePackageModal = true"
						:disabled="selectedItems.length === 0"
						severity="secondary"
					/>
				</div>
			</div>
			<div v-for="(item, index) in selectedItems" :key="item.itemCode" class="item-container">
				<div class="item-row">
					<div class="item-name-wrapper">
						<Button
							v-if="isPackageItem(item)"
							:icon="isItemExpanded(item.itemCode) ? 'pi pi-chevron-down' : 'pi pi-chevron-right'"
							text
							rounded
							size="small"
							@click="toggleItemExpansion(item.itemCode)"
							class="expand-button"
						/>
						<i v-if="isPackageItem(item)" class="pi pi-box package-icon"></i>
						<i v-else class="pi pi-circle-fill item-bullet"></i>
						<span class="item-name">{{ item.itemName }}</span>
					</div>
					<div class="input-wrapper">
						<span class="input-label">Quantity</span>
						<InputNumber
							v-model="item.qty"
							:min="1"
							:disabled="!isEditable"
							showButtons
							buttonLayout="horizontal"
							@input="onQtyChange(item)"
							class="qty-input"
						/>
					</div>
					<span>X</span>
					<div class="input-wrapper">
						<span class="input-label">Rate</span>
						<InputNumber
							v-model="item.rate"
							mode="currency"
							currency="USD"
							locale="en-US"
							:min="0"
							:disabled="!isEditable"
							@input="onRateChange(item)"
							class="rate-input"
						/>
					</div>
					<div class="input-wrapper">
						<span class="input-label">Discount</span>
						<div class="discount-container">
							<div class="discount-input-wrapper">
								<InputNumber
									v-if="item.discountType === 'currency'"
									v-model="item.discountAmount"
									mode="currency"
									currency="USD"
									locale="en-US"
									:min="0"
									:disabled="!isEditable"
									@input="updateDiscountFromAmount(item)"
									placeholder="$0.00"
									class="discount-input"
								/>
								<InputNumber
									v-else
									v-model="item.discountPercentage"
									suffix="%"
									:min="0"
									:max="100"
									:disabled="!isEditable"
									@input="updateDiscountFromPercentage(item)"
									placeholder="0%"
									class="discount-input"
								/>
							</div>
							<div class="discount-toggle">
								<Button
									icon="pi pi-dollar"
									class="p-button-sm p-button-outlined"
									:class="{ 'p-button-secondary': item.discountType !== 'currency' }"
									@click="toggleDiscountType(item, 'currency')"
									:disabled="!isEditable"
								/>
								<Button
									icon="pi pi-percentage"
									class="p-button-sm p-button-outlined"
									:class="{ 'p-button-secondary': item.discountType !== 'percentage' }"
									@click="toggleDiscountType(item, 'percentage')"
									:disabled="!isEditable"
								/>
							</div>
						</div>
					</div>
					<span>Total: ${{ ((item.qty || 0) * (item.rate || 0) - (item.discountAmount || 0)).toFixed(2) }}</span>
					<Button
						v-if="isEditable"
						icon="pi pi-trash"
						@click="removeItem(index)"
						severity="danger"
					/>
				</div>
				<div v-if="isPackageItem(item) && isItemExpanded(item.itemCode)" class="nested-items">
					<div v-for="bomItem in item.bom.items" :key="bomItem.itemCode">
						<BomItem :item="bomItem" :parentPath="item.itemCode" :level="0" />
					</div>
				</div>
			</div>
			<div class="total-section">
				<strong>Total Cost: ${{ totalCost.toFixed(2) }}</strong>
			</div>
			<div class="half-payment-section">
				<v-checkbox
					v-model="formData.requiresHalfPayment"
					label="Requires Half Payment"
					:disabled="!isEditable"
				/>
			</div>
			<div v-if="isEditable" class="action-buttons">
				<Button label="Clear Items" @click="clearItems" severity="secondary" />
				<Button
					label="Save Draft"
					@click="saveDraft"
					:disabled="selectedItems.length === 0 || estimate?.customSent === 1"
				/>
			</div>
			<div v-if="estimate">
				<Button label="Send Estimate" @click="initiateSendEstimate" :disabled="estimate.customSent === 1"/>
			</div>
			<div v-if="estimate && estimate.customSent === 1" class="response-status">
				<h4>Customer Response:</h4>
				<span :class="getResponseClass(getResponseText(estimateResponse))">
					{{ getResponseText(estimateResponse) }}
				</span>
			</div>
			<DocHistory
				v-if="!isNew && estimate && estimate.history"
				:events="estimate.history"
				doctype="Estimate"
			/>
		</div>

		<!-- Manual Response Modal -->
		<Modal
			:visible="showResponseModal"
			@update:visible="showResponseModal = $event"
			@close="showResponseModal = false"
			:options="{ showActions: false }"
		>
			<template #title>Set Response</template>
			<Select v-model="estimateResponseSelection" :options="responses" placeholder="Select Response"/>
			<Button label="Submit" @click="submitResponse"/>
		</Modal>

		<!-- Save Template Modal -->
		<SaveTemplateModal
			:visible="showSaveTemplateModal"
			@update:visible="showSaveTemplateModal = $event"
			@save="confirmSaveTemplate"
		/>

		<!-- Address Search Modal -->
		<Modal
			:visible="showAddressModal"
			@update:visible="showAddressModal = $event"
			@close="showAddressModal = false"
		>
			<template #title>Address Search Results</template>
			<div class="address-search-results">
				<div v-if="addressSearchResults.length === 0" class="no-results">
					<i class="pi pi-info-circle"></i>
					<p>No addresses found matching your search.</p>
				</div>
				<div v-else class="results-list">
					<div
						v-for="(address, index) in addressSearchResults"
						:key="index"
						class="address-result-item"
						@click="selectAddress(address)"
					>
						<i class="pi pi-map-marker"></i>
						<span>{{ address }}</span>
					</div>
				</div>
			</div>
		</Modal>

		<!-- Add Item Modal -->
		<AddItemModal
			:visible="showAddItemModal"
			@update:visible="showAddItemModal = $event"
			:quotation-items="quotationItems"
			@add-items="addSelectedItems"
		/>
		<!-- Save Package Modal -->
		<SavePackageModal
			:visible="showSavePackageModal"
			@update:visible="showSavePackageModal = $event"
			:items="selectedItems"
			:default-rate="totalCost"
			@save="handleSavePackage"
		/>
		<!-- Down Payment Warning Modal -->
		<Modal
			:visible="showDownPaymentWarningModal"
			@update:visible="showDownPaymentWarningModal = $event"
			@close="showDownPaymentWarningModal = false"
			:options="{ showActions: false }"
		>
			<template #title>Warning</template>
			<div class="modal-content">
				<p>Down payment is not required for this estimate. Ok to proceed?</p>
				<div class="confirmation-buttons">
					<Button
						label="No"
						@click="showDownPaymentWarningModal = false"
						severity="secondary"
					/>
					<Button label="Yes" @click="proceedFromWarning" />
				</div>
			</div>
		</Modal>

		<!-- Confirmation Modal -->
		<Modal
			:visible="showConfirmationModal"
			@update:visible="showConfirmationModal = $event"
			@close="showConfirmationModal = false"
			:options="{ showActions: false }"
		>
			<template #title>Confirm Send Estimate</template>
			<div class="modal-content">
				<div class="company-banner">Company: {{ company.currentCompany }}</div>
				<h4>Does this information look correct?</h4>
				<p><strong>Address:</strong> {{ formData.address }}</p>
				<p>
					<strong>Contact:</strong>
					{{
						selectedContact
							? `${selectedContact.firstName} ${selectedContact.lastName}`
							: ""
					}}
				</p>
				<p>
					<strong>Email:</strong>
					{{ selectedContact?.emailId || "N/A" }}
				</p>
				<p><strong>Items:</strong></p>
				<ul>
					<li v-for="item in selectedItems" :key="item.itemCode">
						{{ item.itemName }} - Qty: {{ item.qty || 0 }} - Total: ${{
							((item.qty || 0) * (item.rate || 0)).toFixed(2)
						}}
					</li>
				</ul>
				<p><strong>Total:</strong> ${{ totalCost.toFixed(2) }}</p>
				<p><strong>Requires Half Payment:</strong> {{ formData.requiresHalfPayment ? 'Yes' : 'No' }}</p>
				<p class="warning-text"><strong>⚠️ Warning:</strong> After sending this estimate, it will be locked and cannot be edited.</p>
				<div class="confirmation-buttons">
					<Button
						label="Cancel"
						@click="showConfirmationModal = false"
						severity="secondary"
					/>
					<Button label="Send Estimate" @click="confirmAndSendEstimate" :disabled="estimate.customSent !== 0" />
				</div>
			</div>
		</Modal>

		<!-- Bid Meeting Notes Side Tab -->
		<Button v-if="bidMeeting?.bidNotes" class="bid-notes-side-tab" @click="onTabClick">
			<div class="tab-content">
				<i class="pi pi-file-edit"></i>
				<span class="tab-text">Bid Notes</span>
			</div>
		</Button>

		<!-- Bid Meeting Notes Drawer -->
		<Drawer
			:visible="showDrawer"
			@update:visible="showDrawer = $event"
			position="right"
			:style="{ width: '1200px' }"
			@hide="showDrawer = false"
			class="bid-notes-drawer"
		>
			<template #header>
				<div class="drawer-header">
					<h3>Bid Meeting Notes</h3>
					<Button icon="pi pi-times" @click="showDrawer = false" text rounded />
				</div>
			</template>
			<div class="drawer-content">
				<BidMeetingNotes v-if="bidMeeting?.bidNotes" :bid-note="bidMeeting.bidNotes" />
			</div>
		</Drawer>

	</div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, watch, defineComponent, h } from "vue";
import { useRoute, useRouter } from "vue-router";
import Modal from "../common/Modal.vue";
import SaveTemplateModal from "../modals/SaveTemplateModal.vue";
import AddItemModal from "../modals/AddItemModal.vue";
import SavePackageModal from "../modals/SavePackageModal.vue";
import DataTable from "../common/DataTable.vue";
import DocHistory from "../common/DocHistory.vue";
import BidMeetingNotes from "../modals/BidMeetingNotes.vue";
import InputText from "primevue/inputtext";
import InputNumber from "primevue/inputnumber";
import Button from "primevue/button";
import Select from "primevue/select";
import Tooltip from "primevue/tooltip";
import Drawer from "primevue/drawer";
import Api from "../../api";
import DataUtils from "../../utils";
import { useLoadingStore } from "../../stores/loading";
import { useNotificationStore } from "../../stores/notifications-primevue";
import { useCompanyStore } from "../../stores/company";

const route = useRoute();
const router = useRouter();
const loadingStore = useLoadingStore();
const notificationStore = useNotificationStore();
const company = useCompanyStore();
const vTooltip = Tooltip;

const addressQuery = computed(() => route.query.address || "");
const nameQuery = computed(() => route.query.name || "");
const templateQuery = computed(() => route.query.template || "");
const fromMeetingQuery = computed(() => route.query["from-meeting"] || "");
const contactQuery = computed(() => route.query.contact || "");
const projectTemplateQuery = computed(() => route.query["project-template"] || "");
const isNew = computed(() => route.query.new === "true");

const isSubmitting = ref(false);
const isDuplicating = ref(false);
const duplicatedItems = ref([]);

const formData = reactive({
	address: "",
	addressName: "",
	contact: "",
	estimateName: null,
	requiresHalfPayment: false,
	projectTemplate: null,
	fromOnsiteMeeting: null,
});

const selectedAddress = ref(null);
const selectedContact = ref(null);
const estimateResponseClass = ref(null);
const estimateResponse = ref(null);
const estimateResponseSelection = ref(null);
const contacts = ref([]);
const contactOptions = ref([]);
const quotationItems = ref({});
const selectedItems = ref([]);
const responses = ref(["Accepted", "Rejected"]);
const projectTemplates = ref([]);

const showAddressModal = ref(false);
const showAddItemModal = ref(false);
const showConfirmationModal = ref(false);
const showDownPaymentWarningModal = ref(false);
const showResponseModal = ref(false);
const showSaveTemplateModal = ref(false);
const showSavePackageModal = ref(false);
const addressSearchResults = ref([]);
const showDrawer = ref(false);
const isLoadingQuotationItems = ref(false);
const expandedSelectedItems = ref(new Set());

const estimate = ref(null);
const bidMeeting = ref(null);

// BomItem component for recursive rendering of nested packages
const BomItem = defineComponent({
	name: 'BomItem',
	props: {
		item: Object,
		parentPath: String,
		level: {
			type: Number,
			default: 0
		}
	},
	setup(props) {
		const itemPath = computed(() => {
			return props.parentPath ? `${props.parentPath}.${props.item.itemCode}` : props.item.itemCode;
		});

		const isPackage = computed(() => {
			return props.item.bom && props.item.bom.items && props.item.bom.items.length > 0;
		});

		const isExpanded = computed(() => {
			return expandedSelectedItems.value.has(itemPath.value);
		});

		const toggleExpansion = () => {
			if (expandedSelectedItems.value.has(itemPath.value)) {
				expandedSelectedItems.value.delete(itemPath.value);
			} else {
				expandedSelectedItems.value.add(itemPath.value);
			}
			expandedSelectedItems.value = new Set(expandedSelectedItems.value);
		};

		return () => h('div', { 
			class: 'nested-item',
			style: { paddingLeft: `${props.level * 1}rem` }
		}, [
			h('div', { class: 'nested-item-content' }, [
				isPackage.value ? h(Button, {
					icon: isExpanded.value ? 'pi pi-chevron-down' : 'pi pi-chevron-right',
					onClick: toggleExpansion,
					text: true,
					rounded: true,
					size: 'small',
					class: 'nested-expand-button'
				}) : null,
				isPackage.value ? h('i', { class: 'pi pi-box package-icon' }) : h('i', { class: 'pi pi-circle-fill item-bullet' }),
				h('span', { class: 'nested-item-name' }, `${props.item.itemName} (Qty: ${props.item.qty})`)
			]),
			isPackage.value && isExpanded.value && props.item.bom?.items ? h('div', { class: 'deeply-nested-items' }, 
				props.item.bom.items.map(nestedItem => 
					h(BomItem, {
						key: nestedItem.itemCode,
						item: nestedItem,
						parentPath: itemPath.value,
						level: props.level + 1
					})
				)
			) : null
		]);
	}
});

// Computed property to determine if fields are editable
const isEditable = computed(() => {
	if (isNew.value) return true;
	if (!estimate.value) return false;
	// If docstatus is 0 (draft), allow editing of contact and items
	return estimate.value.customSent === 0;
});

const hasQuotationItems = computed(() => {
	return quotationItems.value && Object.keys(quotationItems.value).length > 0;
});

const itemColumns = [
	{ label: "Item Code", fieldName: "itemCode", type: "text" },
	{ label: "Item Name", fieldName: "itemName", type: "text" },
	{ label: "Price", fieldName: "standardRate", type: "number" },
];

// Methods
const fetchProjectTemplates = async () => {
	try {
		const result = await Api.getJobTemplates(company.currentCompany);
		projectTemplates.value = [...result, { name: "Other" }];
	} catch (error) {
		console.error("Error fetching project templates:", error);
		notificationStore.addNotification("Failed to fetch project templates", "error");
	}
};

const openSaveTemplateModal = () => {
	showSaveTemplateModal.value = true;
};

const handleSavePackage = async (packageData) => {
	try {
		const newPackageItem = await Api.saveAsPackageItem(packageData);
		
		// Initialize Packages object if it doesn't exist
		if (!quotationItems.value.Packages) {
			quotationItems.value = { ...quotationItems.value, Packages: {} };
		}
		
		// Initialize category array if it doesn't exist and add the new package
		if (!quotationItems.value.Packages[packageData.category]) {
			quotationItems.value.Packages = {
				...quotationItems.value.Packages,
				[packageData.category]: [newPackageItem]
			};
		} else {
			// Add to existing category
			quotationItems.value.Packages[packageData.category] = [
				...quotationItems.value.Packages[packageData.category],
				newPackageItem
			];
		}
		
		// Replace all selected items with just the new package
		selectedItems.value = [{
			itemCode: newPackageItem.itemCode || newPackageItem.item_code,
			itemName: newPackageItem.itemName || newPackageItem.item_name,
			qty: 1,
			rate: newPackageItem.standardRate || newPackageItem.standard_rate || packageData.rate,
			standardRate: newPackageItem.standardRate || newPackageItem.standard_rate || packageData.rate,
			bom: newPackageItem.bom || null,
			uom: newPackageItem.uom || newPackageItem.stockUom || newPackageItem.stock_uom || 'Nos',
			discountAmount: null,
			discountPercentage: null,
			discountType: 'currency'
		}];
		
		notificationStore.addSuccess("Package saved successfully", "success");
		showSavePackageModal.value = false;
	} catch (error) {
		console.error("Error saving package:", error);
		notificationStore.addNotification("Failed to save package", "error");
	}
};

const confirmSaveTemplate = async (templateData) => {
	try {
		const data = {
			templateName: templateData.templateName,
			description: templateData.description,
			company: company.currentCompany,
			sourceQuotation: estimate.value.name,
			projectTemplate: formData.projectTemplate,
			items: selectedItems.value.map(item => ({
				itemCode: item.itemCode,
				itemName: item.itemName,
				description: item.description,
				qty: item.qty,
				standardRate: item.standardRate,
				discountPercentage: item.discountPercentage
			}))
		};
		await Api.createEstimateTemplate(data);
		notificationStore.addSuccess("Template saved successfully", "success");
		showSaveTemplateModal.value = false;
	} catch (error) {
		console.error("Error saving template:", error);
		notificationStore.addNotification("Failed to save template", "error");
	}
};

const searchAddresses = async () => {
	const searchTerm = formData.address.trim();
	if (!searchTerm) return;

	try {
		const results = await Api.searchAddresses(searchTerm);
		addressSearchResults.value = results;

		if (results.length === 0) {
			notificationStore.addNotification(
				"No addresses found matching your search.",
				"warning",
			);
		} else {
			showAddressModal.value = true;
		}
	} catch (error) {
		console.error("Error searching addresses:", error);
		addressSearchResults.value = [];
		notificationStore.addNotification(
			"Failed to search addresses. Please try again.",
			"error",
		);
	}
};

const selectAddress = async (address) => {
	formData.address = address;
	selectedAddress.value = await Api.getAddressByFullAddress(address);
	formData.addressName = selectedAddress.value.name;
	contacts.value = selectedAddress.value.contacts;
	contactOptions.value = contacts.value.map((c) => ({
		label: `${c.firstName || ""} ${c.lastName || ""}`.trim() || c.name,
		value: c.name,
		email: c.emailId,
		phone: c.phone || c.mobileNo
	}));
	const primary = contacts.value.find((c) => c.name === selectedAddress.value.primaryContact);
	console.log("DEBUG: Selected address contacts:", contacts.value);
	const existingContactName = estimate.value ? contacts.value.find((c) => c.fullName === estimate.value.partyName)?.name || "" : null;
	// Check for contact query param, then existing contact, then primary, then first contact
	if (contactQuery.value) {
		const contactFromQuery = contacts.value.find((c) => c.name === contactQuery.value);
		formData.contact = contactFromQuery ? contactFromQuery.name : (primary ? primary.name : contacts.value[0]?.name || "");
	} else {
		formData.contact = estimate.value ? existingContactName : primary ? primary.name : contacts.value[0]?.name || "";
	}
	showAddressModal.value = false;
};

const addItem = (item) => {
	const existing = selectedItems.value.find((i) => i.itemCode === item.itemCode);
	if (!existing) {
		selectedItems.value.push({ ...item, qty: 1, rate: item.standardRate, discountAmount: null, discountPercentage: null, discountType: 'currency' });
	}
	showAddItemModal.value = false;
};

const addSelectedItems = (selectedRows) => {
	selectedRows.forEach((item) => {
		const existing = selectedItems.value.find((i) => i.itemCode === item.itemCode);
		if (existing) {
			// Increase quantity by 1 if item already exists
			existing.qty += 1;
		} else {
			// Add new item with quantity 1
			selectedItems.value.push({ ...item, qty: 1, rate: item.standardRate, discountAmount: null, discountPercentage: null, discountType: 'currency' });
		}
	});
	showAddItemModal.value = false;
};

const removeItem = (index) => {
	selectedItems.value.splice(index, 1);
};

const clearItems = () => {
	selectedItems.value = [];
};

const updateDiscountFromAmount = (item) => {
	const total = (item.qty || 0) * (item.rate || 0);
	if (total === 0) {
		item.discountPercentage = 0;
	} else {
		item.discountPercentage = ((item.discountAmount || 0) / total) * 100;
	}
};

const updateDiscountFromPercentage = (item) => {
	const total = (item.qty || 0) * (item.rate || 0);
	item.discountAmount = total * ((item.discountPercentage || 0) / 100);
};

const onQtyChange = (item) => {
	if (item.discountType === 'percentage') {
		updateDiscountFromPercentage(item);
	} else {
		updateDiscountFromAmount(item);
	}
};

const onRateChange = (item) => {
	if (item.discountType === 'percentage') {
		updateDiscountFromPercentage(item);
	} else {
		updateDiscountFromAmount(item);
	}
};

const saveDraft = async () => {
	if (!formData.projectTemplate) {
		notificationStore.addNotification("Project Template is required.", "error");
		return;
	}
	isSubmitting.value = true;
	try {
		const data = {
			address: formData.address,
			addressName: formData.addressName,
			contactName: selectedContact.value.name,
			customer: selectedAddress.value?.customer?.name,
			items: selectedItems.value.map((i) => ({
				itemCode: i.itemCode,
				qty: i.qty,
				rate: i.rate,
				discountAmount: i.discountAmount,
				discountPercentage: i.discountPercentage
			})),
			estimateName: formData.estimateName,
			requiresHalfPayment: formData.requiresHalfPayment,
			projectTemplate: formData.projectTemplate,
			fromOnsiteMeeting: formData.fromOnsiteMeeting,
			company: company.currentCompany
		};
		estimate.value = await Api.createEstimate(data);
		notificationStore.addSuccess(
			formData.estimateName ? "Estimate updated successfully" : "Estimate created successfully",
			"success"
		);

		// Redirect to view mode (remove new param)
		router.push(`/estimate?name=${encodeURIComponent(estimate.value.name)}`);
	} catch (error) {
		console.error("Error saving estimate:", error);
		notificationStore.addNotification("Failed to save estimate", "error");
	} finally {
		isSubmitting.value = false;
	}
};

const submitResponse = () => {
	Api.updateEstimateResponse(estimate.value.name, estimateResponseSelection.value, false);
	estimateResponse.value = estimateResponseSelection.value;
	showResponseModal.value = false;
}

const duplicateEstimate = () => {
	if (!estimate.value) return;

	// Preserve current items/quantities for the new estimate
	duplicatedItems.value = (selectedItems.value || []).map((item) => ({ ...item }));
	isDuplicating.value = true;

	// Navigate to new estimate mode without address/contact in query params
	router.push({ path: "/estimate", query: { new: "true" } });
};

const getResponseClass = (response) => {
	if (response === "Accepted") return "response-accepted";
	if (response === "Rejected") return "response-rejected";
	if (response === "Requested help") return "response-requested-help";
	return "response-no-response";
};

const getResponseText = (response) => {
	if (response === "Accepted") return "Accepted";
	if (response === "Rejected") return "Rejected";
	if (response === "Requested help") return "Requested Help";
	return "No response yet";
};

const initiateSendEstimate = () => {
	if (!formData.requiresHalfPayment) {
		showDownPaymentWarningModal.value = true;
	} else {
		showConfirmationModal.value = true;
	}
};

const proceedFromWarning = () => {
	showDownPaymentWarningModal.value = false;
	showConfirmationModal.value = true;
};

const confirmAndSendEstimate = async () => {
	loadingStore.setLoading(true, "Sending estimate...");
	const updatedEstimate = await Api.sendEstimateEmail(estimate.value.name);
	loadingStore.setLoading(false);
	notificationStore.addSuccess("Estimate sent successfully", "success");
	showConfirmationModal.value = false;
	notificationStore.addWarning("Estimate has been locked and can no longer be edited.", "warning");
	estimate.value = updatedEstimate;
};

const toggleDiscountType = (item, type) => {
	item.discountType = type;
};

const toggleItemExpansion = (itemCode) => {
	if (expandedSelectedItems.value.has(itemCode)) {
		expandedSelectedItems.value.delete(itemCode);
	} else {
		expandedSelectedItems.value.add(itemCode);
	}
	expandedSelectedItems.value = new Set(expandedSelectedItems.value);
};

const isItemExpanded = (itemCode) => {
	return expandedSelectedItems.value.has(itemCode);
};

const isPackageItem = (item) => {
	return item.bom && item.bom.items && item.bom.items.length > 0;
};

const onTabClick = () => {
	console.log('Bid notes tab clicked');
	console.log('Current showDrawer value:', showDrawer.value);
	console.log('bidMeeting:', bidMeeting.value);
	console.log('bidMeeting?.bidNotes:', bidMeeting.value?.bidNotes);
	showDrawer.value = true;
	console.log('Set showDrawer to true');
};

const totalCost = computed(() => {
	return (selectedItems.value || []).reduce((sum, item) => {
		const qty = item.qty || 0;
		const rate = item.rate || 0;
		const discount = item.discountAmount || 0;
		return sum + (qty * rate) - discount;
	}, 0);
});

watch(
	() => formData.contact,
	(newVal) => {
		selectedContact.value = contacts.value.find((c) => c.name === newVal) || null;
	},
);

watch(() => formData.projectTemplate, async (newValue) => {
	if (!newValue) {
		quotationItems.value = {};
		return;
	}
	isLoadingQuotationItems.value = true;
	try {
		quotationItems.value = await Api.getItemsByProjectTemplate(newValue);
		console.log("DEBUG: quotationItems after API call:", quotationItems.value);
		console.log("DEBUG: quotationItems type:", typeof quotationItems.value);
		console.log("DEBUG: quotationItems keys length:", quotationItems.value ? Object.keys(quotationItems.value).length : 0);
		console.log("DEBUG: hasQuotationItems computed value:", hasQuotationItems.value);
	} catch (error) {
		console.error("Error fetching items by project template:", error);
		notificationStore.addNotification("Failed to load items for selected project template", "error");
		quotationItems.value = {};
	} finally {
		isLoadingQuotationItems.value = false;
		console.log("DEBUG: Loading finished, isLoadingQuotationItems:", isLoadingQuotationItems.value);
	}
})

watch(() => company.currentCompany, () => {
	if (isNew.value) {
		fetchProjectTemplates();
	}
});

// Watch for query param changes to refresh page behavior
watch(
	() => route.query,
	async (newQuery, oldQuery) => {
		// If 'new' param or address changed, reload component state
		if (newQuery.new !== oldQuery.new || newQuery.address !== oldQuery.address || newQuery.name !== oldQuery.name) {
			const duplicating = isDuplicating.value;
			const preservedItems = duplicating
				? (duplicatedItems.value || []).map((item) => ({ ...item }))
				: [];

			// Reset all state, but keep items if duplicating
			formData.address = "";
			formData.addressName = "";
			formData.contact = "";
			formData.estimateName = null;
			selectedAddress.value = null;
			selectedContact.value = null;
			contacts.value = [];
			contactOptions.value = [];
			estimate.value = null;
			selectedItems.value = preservedItems;

			// Clear duplication state once applied
			if (duplicating) {
				isDuplicating.value = false;
				duplicatedItems.value = [];
				return;
			}

			// Reload data based on new query params
			const newIsNew = newQuery.new === "true";
			const newAddressQuery = newQuery.address;
			const newNameQuery = newQuery.name;
			const newFromMeetingQuery = newQuery["from-meeting"];
			const newProjectTemplateQuery = newQuery["project-template"];

			if (newAddressQuery && newIsNew) {
				// Creating new estimate - pre-fill address
				await selectAddress(newAddressQuery);
			} else if ((newNameQuery || newAddressQuery) && !newIsNew) {
				// Viewing existing estimate - load and populate all fields
				try {
					if (newNameQuery) {
						estimate.value = await Api.getEstimate(newNameQuery);
					} else {
						estimate.value = await Api.getEstimateFromAddress(newAddressQuery);
					}

					if (estimate.value) {
						formData.estimateName = estimate.value.name;
						const fullAddress = estimate.value.fullAddress || estimate.value.full_address;
						if (fullAddress) {
							await selectAddress(fullAddress);
						} else if (newAddressQuery) {
							await selectAddress(newAddressQuery);
						}

						formData.contact = estimate.value.contactPerson;
						selectedContact.value = contacts.value.find((c) => c.name === estimate.value.contactPerson) || null;

						formData.projectTemplate = estimate.value.customProjectTemplate || estimate.value.custom_project_template || null;

						// Load quotation items if project template is set (needed for item details)
						if (formData.projectTemplate) {
							quotationItems.value = await Api.getItemsByProjectTemplate(formData.projectTemplate);
						}

						if (estimate.value.items && estimate.value.items.length > 0) {
							selectedItems.value = estimate.value.items.map(item => {
								const fullItem = Object.values(quotationItems.value).flat().find(qi => qi.itemCode === item.itemCode);
								const discountPercentage = item.discountPercentage || item.discount_percentage || 0;
								const discountAmount = item.discountAmount || item.discount_amount || 0;
								return {
									itemCode: item.itemCode,
									itemName: item.itemName,
									qty: item.qty,
									standardRate: item.rate || fullItem?.standardRate || 0,
									discountAmount: discountAmount === 0 ? null : discountAmount,
									discountPercentage: discountPercentage === 0 ? null : discountPercentage,
									discountType: discountPercentage > 0 ? 'percentage' : 'currency'
								};
							});
						}
						formData.requiresHalfPayment = Boolean(estimate.value.requiresHalfPayment || estimate.value.custom_requires_half_payment);
						// If estimate has fromOnsiteMeeting, fetch bid meeting
						if (estimate.value.fromOnsiteMeeting) {
							try {
								bidMeeting.value = await Api.getBidMeeting(estimate.value.fromOnsiteMeeting);
							} catch (error) {
								console.error("Error fetching bid meeting for existing estimate:", error);
							}
						}
					}
				} catch (error) {
					console.error("Error loading estimate:", error);
					notificationStore.addNotification(
						"Failed to load estimate details.",
						"error"
					);
				}
			}

			// Handle from-meeting for new estimates
			if (newFromMeetingQuery && newIsNew) {
				formData.fromOnsiteMeeting = newFromMeetingQuery;
				try {
					bidMeeting.value = await Api.getBidMeeting(newFromMeetingQuery);
					if (bidMeeting.value?.bidNotes?.quantities) {
						// Ensure quotationItems is an object before using
						if (typeof quotationItems.value !== 'object' || quotationItems.value === null) {
							quotationItems.value = {};
						}
						selectedItems.value = bidMeeting.value.bidNotes.quantities.map(q => {
							const item = Object.values(quotationItems.value).flat().find(i => i.itemCode === q.item);
							return {
								itemCode: q.item,
								itemName: item?.itemName || q.item,
								qty: q.quantity,
								standardRate: item?.standardRate || 0,
								discountAmount: null,
								discountPercentage: null,
								discountType: 'currency'
							};
						});
					}
				} catch (error) {
					console.error("Error fetching bid meeting:", error);
				}
			}

			// Handle project-template
			if (newProjectTemplateQuery) {
				formData.projectTemplate = newProjectTemplateQuery;
			}
		}
	},
	{ deep: true }
);

onMounted(async () => {
	console.log("DEBUG: Query params:", route.query);
	// try {
	// 	quotationItems.value = await Api.getQuotationItems(selectedTemplate.value);
	// } catch (error) {
	// 	console.error("Error loading quotation items:", error);
	// }
	await fetchProjectTemplates();

	if (isNew.value) {
		// Handle from-meeting query parameter
		if (fromMeetingQuery.value) {
			formData.fromOnsiteMeeting = fromMeetingQuery.value;
			// Fetch the bid meeting to check for bidNotes
			try {
				bidMeeting.value = await Api.getBidMeeting(fromMeetingQuery.value);
				// If new estimate and bid notes have quantities, set default items
				if (isNew.value && bidMeeting.value?.bidNotes?.quantities) {
					// Ensure quotationItems is an object before using
					if (typeof quotationItems.value !== 'object' || quotationItems.value === null) {
						quotationItems.value = {};
					}
					selectedItems.value = bidMeeting.value.bidNotes.quantities.map(q => {
						const item = Object.values(quotationItems.value).flat().find(i => i.itemCode === q.item);
						return {
							itemCode: q.item,
							itemName: item?.itemName || q.item,
							qty: q.quantity,
							standardRate: item?.standardRate || 0,
							discountAmount: null,
							discountPercentage: null,
							discountType: 'currency'
						};
					});
				}
			} catch (error) {
				console.error("Error fetching bid meeting:", error);
			}
		}
	}

	// Handle project-template query parameter
	if (projectTemplateQuery.value) {
		formData.projectTemplate = projectTemplateQuery.value;
		quotationItems.value = await Api.getItemsByProjectTemplate(projectTemplateQuery.value);
	}

	if (addressQuery.value && isNew.value) {
		// Creating new estimate - pre-fill address
		await selectAddress(addressQuery.value);
	} else if ((nameQuery.value || addressQuery.value) && !isNew.value) {
		// Viewing existing estimate - load and populate all fields
		try {
			if (nameQuery.value) {
				estimate.value = await Api.getEstimate(nameQuery.value);
			} else {
				estimate.value = await Api.getEstimateFromAddress(addressQuery.value);
			}
			console.log("DEBUG: Loaded estimate:", estimate.value);

			if (estimate.value) {
				// Set the estimate name for upserting
				formData.estimateName = estimate.value.name;

				const fullAddress = estimate.value.fullAddress || estimate.value.full_address;
				if (fullAddress) {
					await selectAddress(fullAddress);
				} else if (addressQuery.value) {
					await selectAddress(addressQuery.value);
				}

				// Set the contact from the estimate
				formData.contact = estimate.value.contactPerson;
				selectedContact.value = contacts.value.find((c) => c.name === estimate.value.contactPerson) || null;

				formData.projectTemplate = estimate.value.customProjectTemplate || estimate.value.custom_project_template || null;

				// Load quotation items if project template is set (needed for item details)
				if (formData.projectTemplate) {
					quotationItems.value = await Api.getItemsByProjectTemplate(formData.projectTemplate);
				}
				
				// Populate items from the estimate
				if (estimate.value.items && estimate.value.items.length > 0) {
					selectedItems.value = estimate.value.items.map(item => {
						const discountPercentage = item.discountPercentage || item.discount_percentage || 0;
						const discountAmount = item.discountAmount || item.discount_amount || 0;
						return {
							itemCode: item.itemCode || item.item_code,
							itemName: item.itemName || item.item_name,
							qty: item.qty,
							rate: item.rate,
							standardRate: item.rate,
							bom: item.bom || null,
							uom: item.uom || item.stockUom || item.stock_uom || 'Nos',
							discountAmount: discountAmount === 0 ? null : discountAmount,
							discountPercentage: discountPercentage === 0 ? null : discountPercentage,
							discountType: discountPercentage > 0 ? 'percentage' : 'currency'
						};
					});
				}
				formData.requiresHalfPayment = Boolean(estimate.value.requiresHalfPayment || estimate.value.custom_requires_half_payment);
				// If estimate has fromOnsiteMeeting, fetch bid meeting
				if (estimate.value.fromOnsiteMeeting) {
					try {
						bidMeeting.value = await Api.getBidMeeting(estimate.value.fromOnsiteMeeting);
					} catch (error) {
						console.error("Error fetching bid meeting for existing estimate:", error);
					}
				}
				estimateResponse.value = estimate.value.customResponse;
				estimateResponseSelection.value = estimate.value.customResponse;
			}
		} catch (error) {
			console.error("Error loading estimate:", error);
			notificationStore.addNotification(
				"Failed to load estimate details.",
				"error"
			);
		}
	}
});
</script>

<style scoped>
.estimate-page {
	max-width: 1200px;
	margin: 0 auto;
	padding: 2rem;
}

.page-actions {
	display: flex;
	justify-content: flex-end;
	margin-bottom: 1rem;
}

.bid-notes-side-tab {
	position: fixed;
	right: -90px;
	top: 50%;
	transform: translateY(-50%);
	background-color: #2196f3;
	color: white;
	padding: 12px 8px;
	width: 110px;
	border-radius: 0 4px 4px 0;
	cursor: pointer;
	box-shadow: -2px 2px 8px rgba(0, 0, 0, 0.2);
	transition: all 0.3s ease;
	z-index: 1000;
	writing-mode: vertical-rl;
	text-orientation: upright;
}

.bid-notes-side-tab:hover {
	right: -80px;
	background-color: #1976d2;
}

.tab-content {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 8px;
}

.tab-content i {
	font-size: 1.1em;
}

.tab-text {
	font-weight: 500;
	font-size: 0.9em;
	white-space: nowrap;
}

.address-section,
.contact-section,
.project-template-section {
	margin-bottom: 1.5rem;
}

.field-label {
	display: block;
	margin-bottom: 0.5rem;
	font-weight: 500;
}

.required {
	color: red;
}

.address-input-group {
	display: flex;
	gap: 0.5rem;
	align-items: center;
}

.search-button {
	flex-shrink: 0;
}

.verification-info {
	margin-top: 0.5rem;
	font-size: 0.9rem;
	color: #666;
}

.items-section {
	margin-top: 2rem;
}

.items-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 1rem;
}

.items-header h3 {
	margin: 0;
}

.items-actions {
	display: flex;
	gap: 0.5rem;
}

.item-container {
	margin-bottom: 0.5rem;
}

.item-row {
	display: grid;
	grid-template-columns: 3fr 140px 30px 120px 220px 1.5fr auto;
	align-items: center;
	gap: 1rem;
	padding: 0.5rem;
	border: 1px solid #ddd;
	border-radius: 4px;
}

.item-name-wrapper {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.expand-button {
	padding: 0.25rem;
	min-width: auto;
}

.package-icon {
	color: #2196f3;
	font-size: 1.1em;
}

.item-bullet {
	color: #666;
	font-size: 0.5em;
}

.item-name {
	flex: 1;
}

.nested-items {
	margin-left: 2rem;
	margin-top: 0.5rem;
	padding: 0.5rem;
	background-color: #f9f9f9;
	border-left: 3px solid #2196f3;
	border-radius: 0 4px 4px 0;
}

.nested-item {
	display: flex;
	flex-direction: column;
	border-bottom: 1px solid #f0f0f0;
}

.nested-item:last-child {
	border-bottom: none;
}

.nested-item-content {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.25rem 0;
	color: #666;
	font-size: 0.9em;
}

.nested-expand-button {
	width: 1.5rem;
	height: 1.5rem;
	padding: 0;
	flex-shrink: 0;
}

.nested-item-name {
	flex: 1;
}

.deeply-nested-items {
	background-color: #fafafa;
	border-left: 2px solid #e0e0e0;
	margin-left: 1rem;
	margin-top: 0.25rem;
}

.nested-item .package-icon {
	font-size: 1em;
}

.nested-item .item-bullet {
	font-size: 0.4em;
}

.qty-input {
	width: 100%;
}

.qty-input :deep(.p-inputtext) {
	width: 40px;
	text-align: center;
	padding: 0.25rem;
}

.qty-input :deep(.p-button) {
	width: 2rem;
	padding: 0;
}

.rate-input {
	width: 100%;
}

.rate-input :deep(.p-inputtext) {
	width: 100%;
	padding: 0.5rem;
	text-align: right;
}

.discount-container {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.discount-input-wrapper {
	flex: 1;
}

.discount-input {
	width: 100%;
}

.discount-input :deep(.p-inputtext) {
	width: 100%;
	padding: 0.5rem;
	text-align: right;
}

.discount-toggle {
	display: flex;
	gap: 2px;
}

.discount-toggle .p-button {
	padding: 0.25rem 0.5rem;
	width: 2rem;
}

/* When viewing (not editing), adjust grid to remove delete button column */
.estimate-page:has(h2:contains("View")) .item-row {
	grid-template-columns: 3fr 140px 30px 120px 220px 1.5fr;
}

.total-section {
	margin-top: 1rem;
	font-size: 1.2rem;
	text-align: right;
}

.action-buttons {
	display: flex;
	gap: 1rem;
	justify-content: flex-end;
	margin-top: 1rem;
}

.modal-content {
	padding: 1rem;
	max-height: 70vh;
	overflow-y: auto;
}

.confirmation-buttons {
	display: flex;
	gap: 1rem;
	justify-content: flex-end;
	margin-top: 1rem;
}

.warning-text {
	margin-top: 1rem;
	padding: 0.75rem;
	background-color: #fff3cd;
	border: 1px solid #ffc107;
	border-radius: 4px;
	color: #856404;
}

.company-banner {
	margin-bottom: 0.75rem;
	padding: 0.6rem 0.9rem;
	background: linear-gradient(135deg, var(--theme-gradient-start), var(--theme-secondary-gradient-end));
	border: 1px solid var(--theme-primary-strong);
	border-radius: 8px;
	color: var(--theme-text-light);
	font-weight: 700;
	letter-spacing: 0.03em;
	text-transform: uppercase;
	box-shadow: 0 6px 14px rgba(0, 0, 0, 0.18);
}

.response-status {
	margin-top: 1rem;
	padding: 1rem;
	border-radius: 8px;
	background-color: #f9f9f9;
	border: 1px solid #e0e0e0;
}

.response-status h4 {
	margin: 0 0 0.5rem 0;
	font-size: 1.1em;
	color: #333;
}

.response-accepted {
	color: #28a745;
	font-weight: bold;
}

.response-rejected {
	color: #dc3545;
	font-weight: bold;
}

.response-requested-help {
	color: #ffc107;
	font-weight: bold;
}

.response-no-response {
	color: #6c757d;
	font-weight: bold;
}

.address-search-results {
	min-height: 200px;
}

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

.no-results i {
	font-size: 2em;
	color: #f39c12;
	margin-bottom: 10px;
	display: block;
}

.results-list {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.address-result-item {
	padding: 12px 16px;
	border: 1px solid #e0e0e0;
	border-radius: 6px;
	cursor: pointer;
	transition: all 0.2s ease;
	display: flex;
	align-items: center;
	gap: 12px;
}

.address-result-item:hover {
	background-color: #f8f9fa;
	border-color: #2196f3;
	transform: translateY(-1px);
	box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.address-result-item i {
	color: #2196f3;
	font-size: 1.1em;
}

.address-result-item span {
	flex: 1;
	font-size: 0.9em;
	color: #333;
}

.field-group {
	margin-bottom: 1rem;
}

.help-icon {
	margin-left: 0.5rem;
	font-size: 0.9rem;
	color: #2196f3;
	cursor: help;
}

.input-wrapper {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
}

.input-label {
	font-size: 0.8rem;
	color: #666;
	font-weight: 500;
}

.contact-option {
	display: flex;
	flex-direction: column;
}

.contact-name {
	font-weight: 500;
}

.contact-detail {
	font-size: 0.85rem;
	color: #666;
}

.loading-message {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	margin-top: 0.5rem;
	color: #2196f3;
	font-size: 0.9rem;
}

.loading-message i {
	font-size: 1.1rem;
}

.bid-notes-drawer {
	box-shadow: -4px 0 8px rgba(0, 0, 0, 0.1);
}

.drawer-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 1rem;
	border-bottom: 1px solid #e0e0e0;
	background-color: #f8f9fa;
}

.drawer-header h3 {
	margin: 0;
	color: #333;
}

.drawer-content {
	padding: 1rem;
	height: calc(100vh - 80px);
	overflow-y: auto;
}
</style>
<parameter name="filePath"></parameter>
