<template>
	<Modal
		:visible="isVisible"
		:options="modalOptions"
		@update:visible="handleVisibilityChange"
		@close="handleClose"
	>
		<template #title> Create New Client </template>

		<!-- Status Message -->
		<div v-if="statusMessage" class="status-message" :class="`status-${statusType}`">
			<i :class="getStatusIcon(statusType)" class="status-icon"></i>
			{{ statusMessage }}
		</div>

		<Form
			ref="formRef"
			:fields="formFields"
			:form-data="formData"
			:show-cancel-button="true"
			:validate-on-change="false"
			:validate-on-blur="true"
			:validate-on-submit="true"
			:loading="isSubmitting"
			:disable-on-loading="true"
			submit-button-text="Create Client"
			cancel-button-text="Cancel"
			@submit="handleSubmit"
			@cancel="handleCancel"
		/>
	</Modal>
</template>

<script setup>
import { ref, reactive, computed, watch } from "vue";
import { useModalStore } from "@/stores/modal";
import Modal from "@/components/common/Modal.vue";
import Form from "@/components/common/Form.vue";
import Api from "@/api";
import DataUtils from "../../utils";

const modalStore = useModalStore();

// Modal visibility computed property
const isVisible = computed(() => modalStore.isModalOpen("createClient"));
const customerNames = ref([]);
// Form reference for controlling its state
const formRef = ref(null);
// Form data
const formData = reactive({
	customertype: "",
	customerName: "",
	addressLine1: "",
	phone: "",
	email: "",
	pincode: "",
	city: "",
	state: "",
});

// Available cities for the selected zipcode
const availableCities = ref([]);

// Loading state for zipcode lookup
const isLoadingZipcode = ref(false);

// Status message for user feedback
const statusMessage = ref("");
const statusType = ref("info"); // 'info', 'warning', 'error', 'success'

// Modal configuration
const modalOptions = {
	maxWidth: "600px",
	persistent: false,
	showActions: false,
	title: "Create New Client",
	overlayColor: "rgb(59, 130, 246)", // Blue background
	overlayOpacity: 0.8,
	cardClass: "create-client-modal",
	closeOnOutsideClick: true,
	closeOnEscape: true,
};

// Form field definitions
const formFields = computed(() => [
	{
		name: "addressTitle",
		label: "Address Title",
		type: "text",
		required: true,
		placeholder: "Enter address title",
		helpText: "A short title to identify this address (e.g., Johnson Home, Johnson Office)",
		cols: 12,
		md: 6,
	},
	{
		name: "customertype",
		label: "Client Type",
		type: "select",
		required: true,
		placeholder: "Select client type",
		cols: 12,
		md: 6,
		options: [
			{ label: "Individual", value: "Individual" },
			{ label: "Company", value: "Company" },
		],
		helpText: "Select whether this is an individual or company client",
	},
	{
		name: "customerName",
		label: "Client Name",
		type: "autocomplete",
		required: true,
		placeholder: "Type or select client name",
		cols: 12,
		md: 6,
		options: customerNames.value,
		forceSelection: false, // Allow custom entries not in the list
		dropdown: true,
		helpText: "Select an existing client or enter a new client name",
	},
	{
		name: "addressLine1",
		label: "Address",
		type: "text",
		required: true,
		placeholder: "Enter street address",
		cols: 12,
		md: 12,
	},
	{
		name: "phone",
		label: "Phone Number",
		type: "text",
		required: true,
		placeholder: "Enter phone number",
		format: "tel",
		cols: 12,
		md: 6,
		validate: (value) => {
			if (value && !/^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/.test(value)) {
				return "Please enter a valid phone number";
			}
			return null;
		},
	},
	{
		name: "email",
		label: "Email Address",
		type: "text",
		required: true,
		placeholder: "Enter email address",
		format: "email",
		cols: 12,
		md: 6,
	},
	{
		name: "pincode",
		label: "Zip Code",
		type: "text",
		required: true,
		placeholder: "Enter 5-digit zip code",
		cols: 12,
		md: 4,
		maxLength: 5,
		inputMode: "numeric",
		pattern: "[0-9]*",
		onChangeOverride: handleZipcodeChange,
		onInput: (value) => {
			// Only allow numbers and limit to 5 digits
			return value.replace(/\D/g, "").substring(0, 5);
		},
		validate: (value) => {
			if (value && !/^\d{5}$/.test(value)) {
				return "Please enter a valid 5-digit zip code";
			}
			return null;
		},
	},
	{
		name: "city",
		label: "City",
		type: availableCities.value.length > 0 ? "select" : "text",
		required: true,
		disabled: false,
		showClear: availableCities.value.length > 1,
		placeholder: availableCities.value.length > 0 ? "Select city" : "Enter city name",
		options: availableCities.value.map((place) => ({
			label: place["place name"],
			value: place["place name"],
		})),
		cols: 12,
		md: 4,
		helpText: isLoadingZipcode.value
			? "Loading cities..."
			: availableCities.value.length > 0
				? "Select from available cities"
				: "Enter city manually (auto-lookup unavailable)",
	},
	{
		name: "state",
		label: "State",
		type: "select",
		options: DataUtils.US_STATES.map((stateAbbr) => ({
			label: stateAbbr,
			value: stateAbbr,
		})),
		required: true,
		disabled: availableCities.value.length > 0,
		placeholder:
			availableCities.value.length > 0 ? "Auto-populated" : "Enter state (e.g., CA, TX, NY)",
		cols: 12,
		md: 4,
		helpText:
			availableCities.value.length > 0
				? "Auto-populated from zip code"
				: "Enter state abbreviation manually",
		validate: (value) => {
			// Only validate manually entered states (when API lookup failed)
			if (availableCities.value.length === 0 && value) {
				const upperValue = value.toUpperCase();
				if (!DataUtils.US_STATES.includes(upperValue)) {
					return "Please enter a valid US state abbreviation (e.g., CA, TX, NY)";
				}
			}
			return null;
		},
	},
]);

// Handle zipcode change and API lookup
async function handleZipcodeChange(value, fieldName, currentFormData) {
	if (value.length < 5) {
		return;
	}
	if (fieldName === "pincode" && value && value.length >= 5) {
		// Only process if it's a valid zipcode format
		const zipcode = value.replace(/\D/g, "").substring(0, 5);

		if (zipcode.length === 5) {
			isLoadingZipcode.value = true;

			try {
				const places = await Api.getCityStateByZip(zipcode);
				console.log("API response for zipcode", zipcode, ":", places);

				if (places && places.length > 0) {
					availableCities.value = places;

					// Update the reactive formData directly to ensure reactivity
					// Use "state abbreviation" instead of "state" for proper abbreviation format
					const stateValue = places[0]["state abbreviation"] || places[0].state;
					console.log("Setting state to:", stateValue, "from place object:", places[0]);
					formData.state = stateValue;

					// If only one city, auto-select it
					if (places.length === 1) {
						formData.city = places[0]["place name"];
						showStatusMessage(
							`Location found: ${places[0]["place name"]}, ${places[0]["state abbreviation"] || places[0].state}`,
							"success",
						);
					} else {
						// Clear city selection if multiple cities
						formData.city = "";
						showStatusMessage(
							`Found ${places.length} cities for this zip code. Please select one.`,
							"info",
						);
					}
				} else {
					// No results found - enable manual entry
					handleApiFailure("No location data found for this zip code");
				}
			} catch (error) {
				console.error("Error fetching city/state data:", error);

				// Check if it's a network/CORS error
				if (error.code === "ERR_NETWORK" || error.message.includes("Network Error")) {
					handleApiFailure(
						"Unable to fetch location data. Please enter city and state manually.",
					);
				} else {
					handleApiFailure(
						"Location lookup failed. Please enter city and state manually.",
					);
				}
			} finally {
				isLoadingZipcode.value = false;
			}
		}
	}
}

// Handle API failure by enabling manual entry
function handleApiFailure(message) {
	console.warn("Zipcode API failed:", message);

	// Clear existing data
	availableCities.value = [];
	formData.city = "";
	formData.state = "";

	// Show user-friendly message
	showStatusMessage(message, "warning");
}

// Show status message to user
function showStatusMessage(message, type = "info") {
	statusMessage.value = message;
	statusType.value = type;

	// Auto-clear message after 5 seconds
	setTimeout(() => {
		statusMessage.value = "";
	}, 5000);
}

// Get icon class for status messages
function getStatusIcon(type) {
	switch (type) {
		case "warning":
			return "pi pi-exclamation-triangle";
		case "error":
			return "pi pi-times-circle";
		case "success":
			return "pi pi-check-circle";
		default:
			return "pi pi-info-circle";
	}
}

// Submission state to prevent double submission
const isSubmitting = ref(false);

// Handle form submission
async function handleSubmit(formDataFromEvent) {
	// Prevent double submission with detailed logging
	if (isSubmitting.value) {
		console.warn(
			"CreateClientModal: Form submission already in progress, ignoring duplicate submission",
		);
		return;
	}

	console.log(
		"CreateClientModal: Form submission started with data:",
		formDataFromEvent || formData,
	);

	isSubmitting.value = true;

	try {
		showStatusMessage("Creating client...", "info");

		// Use the form data from the event if provided, otherwise use reactive formData
		const dataToSubmit = formDataFromEvent || formData;

		console.log("CreateClientModal: Calling API with data:", dataToSubmit);

		// Call API to create client
		const response = await Api.createClient(dataToSubmit);

		console.log("CreateClientModal: API response received:", response);

		if (response && response.success) {
			showStatusMessage("Client created successfully!", "success");

			// Close modal after a brief delay
			setTimeout(() => {
				handleClose();
			}, 1500);
		} else {
			throw new Error(response?.message || "Failed to create client");
		}
	} catch (error) {
		console.error("CreateClientModal: Error creating client:", error);
		showStatusMessage(error.message || "Failed to create client. Please try again.", "error");
	} finally {
		isSubmitting.value = false;
		// Also reset the Form component's internal submission state
		if (formRef.value && formRef.value.stopLoading) {
			formRef.value.stopLoading();
		}
		console.log("CreateClientModal: Form submission completed, isSubmitting reset to false");
	}
}

// Handle cancel action
function handleCancel() {
	handleClose();
}

// Handle modal close
function handleClose() {
	modalStore.closeModal("createClient");
	resetForm();
}

// Handle visibility changes
function handleVisibilityChange(visible) {
	if (!visible) {
		handleClose();
	}
}

// Reset form data
function resetForm() {
	Object.keys(formData).forEach((key) => {
		formData[key] = "";
	});
	availableCities.value = [];
	isLoadingZipcode.value = false;
	statusMessage.value = "";
	statusType.value = "info";
}

// Initialize modal in store when component mounts
modalStore.initializeModal("createClient", {
	closeOnEscape: true,
	closeOnOutsideClick: true,
});

watch(isVisible, async () => {
	if (isVisible.value) {
		try {
			const names = await Api.getCustomerNames();
			customerNames.value = names;
		} catch (error) {
			console.error("Error loading customer names:", error);
		}
	}
});
</script>

<style scoped>
.create-client-modal {
	border-radius: 12px;
}

/* Custom styling for the modal content */
:deep(.modal-header) {
	background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
	color: white;
}

:deep(.modal-title) {
	font-weight: 600;
	font-size: 1.25rem;
}

:deep(.modal-close-btn) {
	color: white !important;
}

:deep(.modal-content) {
	padding: 24px;
}

/* Status message styling */
.status-message {
	padding: 12px 16px;
	margin-bottom: 16px;
	border-radius: 6px;
	display: flex;
	align-items: center;
	font-size: 0.9rem;
	border-left: 4px solid;
}

.status-icon {
	margin-right: 8px;
	font-size: 1rem;
}

.status-info {
	background-color: #e3f2fd;
	color: #1565c0;
	border-left-color: #2196f3;
}

.status-warning {
	background-color: #fff3e0;
	color: #ef6c00;
	border-left-color: #ff9800;
}

.status-error {
	background-color: #ffebee;
	color: #c62828;
	border-left-color: #f44336;
}

.status-success {
	background-color: #e8f5e8;
	color: #2e7d32;
	border-left-color: #4caf50;
}
</style>
