<template>
	<div class="client-page">
		<!-- Client Header -->
		<GeneralClientInfo
			v-if="client.customerName"
			:client-data="client"
		/>
		<AdditionalInfoBar :address="client.addresses[selectedAddressIdx]" v-if="client.customerName" />

		<!-- Address Selector (only shows if multiple addresses) -->
		<AddressSelector
			v-if="!isNew && client.addresses && client.addresses.length > 1"
			:addresses="client.addresses"
			:selected-address-idx="selectedAddressIdx"
			:contacts="client.contacts"
			@update:selected-address-idx="handleAddressChange"
		/>

		<!-- Main Content Tabs -->
		<Tabs value="0" class="overview-tabs">
			<TabList>
				<Tab value="0">Overview</Tab>
				<Tab value="1">Projects</Tab>
				<Tab value="2">Financials</Tab>
			</TabList>
			<TabPanels>
				<!-- Overview Tab -->
				<TabPanel value="0">
					<Overview
						:selected-address="selectedAddressData"
						:all-contacts="client.contacts"
						:edit-mode="editMode"
						:is-new="isNew"
						:full-address="fullAddress"
						:client="client"
						@edit-mode-enabled="enableEditMode"
						@update:address-contacts="handleAddressContactsUpdate"
						@update:primary-contact="handlePrimaryContactUpdate"
						@update:client="handleClientUpdate"
					/>
				</TabPanel>

				<!-- Projects Tab -->
				<TabPanel value="1">
					<div class="coming-soon-section">
						<i class="pi pi-wrench"></i>
						<h3>Projects</h3>
						<p>Section coming soon</p>
					</div>
				</TabPanel>

				<!-- Financials Tab -->
				<TabPanel value="2">
					<div class="coming-soon-section">
						<i class="pi pi-dollar"></i>
						<h3>Financials</h3>
						<p>Section coming soon</p>
					</div>
				</TabPanel>
			</TabPanels>
		</Tabs>

		<!-- Form Actions (for edit mode or new client) -->
		<div class="form-actions" v-if="editMode || isNew">
			<Button
				@click="handleCancel"
				label="Cancel"
				severity="secondary"
				:disabled="isSubmitting"
			/>
			<Button
				@click="handleSubmit"
				:label="isNew ? 'Create Client' : 'Save Changes'"
				:loading="isSubmitting"
			/>
		</div>
	</div>
</template>
<script setup>
import { computed, onMounted, ref, watch } from "vue";
import Tabs from "primevue/tabs";
import TabList from "primevue/tablist";
import Tab from "primevue/tab";
import TabPanels from "primevue/tabpanels";
import TabPanel from "primevue/tabpanel";
import Button from "primevue/button";
import Api from "../../api";
import { useRoute, useRouter } from "vue-router";
import { useLoadingStore } from "../../stores/loading";
import { useNotificationStore } from "../../stores/notifications-primevue";
import { useCompanyStore } from "../../stores/company";
import DataUtils from "../../utils";
import AddressSelector from "../clientView/AddressSelector.vue";
import GeneralClientInfo from "../clientView/GeneralClientInfo.vue";
import AdditionalInfoBar from "../clientView/AdditionalInfoBar.vue";
import Overview from "../clientView/Overview.vue";

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

const address = (route.query.address || '').trim();
const clientName = route.query.client || null;
const isNew = computed(() => route.query.new === "true" || false);

const clientNames = ref([]);
const client = ref({});
const geocode = ref({});

const selectedAddress = ref(address);

const selectedAddressObject = computed(() =>
	client.value.addresses?.find(
		(addr) => DataUtils.calculateFullAddress(addr) === selectedAddress.value,
	),
);
const addresses = computed(() => {
	if (client.value && client.value.addresses) {
		return client.value.addresses.map((addr) => DataUtils.calculateFullAddress(addr).trim());
	}
	return [];
});

const nextVisitDate = ref(null); // Placeholder, update as needed

// Tab and edit state
const editMode = ref(false);
const isSubmitting = ref(false);

const selectedAddressIdx = computed({
	get: () => addresses.value.indexOf(selectedAddress.value),
	set: (idx) => {
		if (idx >= 0 && idx < addresses.value.length) {
			selectedAddress.value = addresses.value[idx];
		}
	}
});

// Find the address data object that matches the selected address string
const selectedAddressData = computed(() => {
	if (!client.value?.addresses || !selectedAddress.value) {
		return null;
	}
	return client.value.addresses.find(
		(addr) => DataUtils.calculateFullAddress(addr).trim() === selectedAddress.value.trim()
	);
});

// Calculate full address for display
const fullAddress = computed(() => {
	if (!selectedAddressData.value) return "N/A";
	return DataUtils.calculateFullAddress(selectedAddressData.value);
});

const getClientNames = async (type) => {
	loadingStore.setLoading(true);
	try {
		const names = await Api.getClientNames(type);
		clientNames.value = names;
	} catch (error) {
		console.error("Error fetching client names in Client.vue: ", error.message || error);
	} finally {
		loadingStore.setLoading(false);
	}
};

const getClient = async (name) => {
	loadingStore.setLoading(true);
	try {
		const clientData = await Api.getClient(name);
		client.value = clientData || {};
		// Set initial selected address if provided in route or use first address
		if (address && client.value.addresses) {
			const fullAddresses = client.value.addresses.map((addr) =>
				DataUtils.calculateFullAddress(addr).trim(),
			);
			const trimmedAddress = address.trim();
			if (fullAddresses.includes(trimmedAddress)) {
				selectedAddress.value = trimmedAddress;
			} else if (fullAddresses.length > 0) {
				selectedAddress.value = fullAddresses[0];
			}
		} else if (client.value.addresses && client.value.addresses.length > 0) {
			selectedAddress.value = DataUtils.calculateFullAddress(client.value.addresses[0]);
		}
		if (
			selectedAddressObject.value?.customLongitude &&
			selectedAddressObject.value?.customLatitude
		) {
			geocode.value = {
				longitude: selectedAddressObject.value.customLongitude || selectedAddressObject.value.longitude,
				latitude: selectedAddressObject.value.customLatitude || selectedAddressObject.value.latitude,
			};
		} else if (selectedAddress.value) {
			// geocode.value = await Api.getGeocode(selectedAddress.value);
		}

		// Check if client is associated with current company
		if (companyStore.currentCompany && client.value.companies) {
			const clientHasCompany = client.value.companies.some(company => company.company === companyStore.currentCompany);
			if (!clientHasCompany) {
				notificationStore.addWarning(
					`The selected company is not linked to this client.`,
				);
			}
		}
	} catch (error) {
		console.error("Error fetching client data in Client.vue: ", error.message || error);
	} finally {
		loadingStore.setLoading(false);
	}
};

onMounted(async () => {
	if (clientName) {
		await getClient(clientName);
		console.log("Displaying existing client data");
	}
	console.debug(
		"DEBUG: Client.vue mounted with clientName:",
		clientName,
		"isNew:",
		isNew.value,
		"address:",
		address,
		"addresses:",
		addresses.value,
		"selectedAddress:",
		selectedAddress.value,
		"Does selected address match an address in addresses?:",
		selectedAddress.value && addresses.value.includes(selectedAddress.value),
		"geocode:",
		geocode.value,
	);
});

watch(
	() => route.query,
	async (newQuery, oldQuery) => {
		const clientName = newQuery.client || null;
		const isNewClient = newQuery.new === "true" || false;
		const address = newQuery.address || null;

		// Clear client data if switching to new client mode
		if (isNewClient) {
			client.value = {};
			selectedAddress.value = null;
			geocode.value = {};
			console.log("Switched to new client mode - cleared client data");
		} else if (clientName && clientName !== oldQuery.client) {
			// Load client data if switching to existing client
			await getClient(clientName);
			console.log("Route query changed - displaying existing client data");
		}
	},
);

watch(
	() => companyStore.currentCompany,
	(newCompany) => {
		console.log("############# Company changed to:", newCompany);
		if (!newCompany || !client.value.customerName) return;

		// Check if client is associated with the company
		let clientHasCompany = false;
		if (client.value.companies) {
			clientHasCompany = client.value.companies.some(company => company.company === newCompany);
		}

		// Check if selected address is associated with the company
		let addressHasCompany = false;
		if (selectedAddressData.value?.companies) {
			addressHasCompany = selectedAddressData.value.companies.some(company => company.company === newCompany);
		}

		// Show warnings for missing associations
		if (!clientHasCompany) {
			notificationStore.addWarning(
				`The selected company is not linked to this client.`,
			);
		} else if (!addressHasCompany) {
			notificationStore.addWarning(
				`The selected company is not linked to this address.`,
			);
		}
	}
)

// Handle address change
const handleAddressChange = (newIdx) => {
	selectedAddressIdx.value = newIdx;
	// TODO: Update route query with new address
};

// Enable edit mode
const enableEditMode = () => {
	editMode.value = true;
};

// Handle cancel edit or new
const handleCancel = () => {
	if (isNew.value) {
		// For new client, clear the form data
		client.value = {};
	} else {
		editMode.value = false;
		// Restore original data if editing
	}
};

// Handle save edit or create new
const handleSubmit = async () => {
	isSubmitting.value = true;
	try {
		if (isNew.value) {
			const createdClient = await Api.createClient(client.value);
			console.log("Created client:", createdClient);
			notificationStore.addSuccess("Client created successfully!");
			const strippedName = createdClient.name.split("-#-")[0].trim();
			// Navigate to the created client
			router.push('/client?client=' + encodeURIComponent(strippedName));
		} else {
			// TODO: Implement save logic
			notificationStore.addSuccess("Changes saved successfully!");
			editMode.value = false;
		}
	} catch (error) {
		console.error("Error submitting:", error);
		notificationStore.addError(isNew.value ? "Failed to create client" : "Failed to save changes");
	} finally {
		isSubmitting.value = false;
	}
};

// Handle address contacts update
const handleAddressContactsUpdate = (contactNames) => {
	console.log("Address contacts updated:", contactNames);
	// TODO: Store this for saving
};

// Handle primary contact update
const handlePrimaryContactUpdate = (contactName) => {
	console.log("Primary contact updated:", contactName);
	// TODO: Store this for saving
};

// Handle client update from forms
const handleClientUpdate = (newClientData) => {
	client.value = { ...client.value, ...newClientData };
};
</script>
<style lang="css">
.tab-info-alert {
	background-color: #a95e46;
	border-radius: 10px;
	color: white;
	padding-left: 5px;
	padding-right: 5px;
	padding-top: 2px;
	padding-bottom: 2px;
}

.overview-tabs {
	margin-bottom: 1rem;
}

.coming-soon-section {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 1rem;
	padding: 4rem 2rem;
	text-align: center;
	background: var(--surface-card);
	border-radius: 12px;
	border: 1px solid var(--surface-border);
}

.coming-soon-section i {
	font-size: 4rem;
	color: var(--text-color-secondary);
	opacity: 0.5;
}

.coming-soon-section h3 {
	margin: 0;
	font-size: 1.75rem;
	font-weight: 600;
	color: var(--text-color);
}

.coming-soon-section p {
	margin: 0;
	font-size: 1.1rem;
	color: var(--text-color-secondary);
}

.client-page {
	padding-bottom: 5rem; /* Add padding to prevent content from being hidden behind fixed buttons */
}

.form-actions {
	position: fixed;
	bottom: 0;
	left: 0;
	right: 0;
	display: flex;
	justify-content: flex-end;
	gap: 1rem;
	padding: 1.5rem;
	background: var(--surface-card);
	border-radius: 0;
	border: 1px solid var(--surface-border);
	border-bottom: none;
	border-left: none;
	border-right: none;
	box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1);
	z-index: 1000;
}
</style>
