---
import SiteFooter from "../../../components/royal-pop/SiteFooter.astro";
import { colorways } from "../../../data/royalPop";
import BaseLayout from "../../../layouts/BaseLayout.astro";
import styles from "../client.module.scss";

const apiBaseUrl = process.env.API_BASE_URL || (import.meta.env.PROD ? "" : "http://localhost:8081");
const finishOptions = [{ id: "silver", label: "Silver" }];

const stockCardClass = styles.stockCard;
const stockCardMediaClass = styles.stockCardMedia;
const stockCardBodyClass = styles.stockCardBody;
const stockCardHeaderClass = styles.stockCardHeader;
const stockTitleClass = styles.stockTitle;
const stockSubtitleClass = styles.stockSubtitle;
const stockBadgeClass = styles.stockBadge;
const inlineFieldClass = styles.inlineField;
const stockCardFooterClass = styles.stockCardFooter;
const stockMetaClass = styles.stockMeta;
const emptyStateClass = styles.emptyState;
const ghostLinkClass = styles.ghostLink;
const toolbarClass = styles.toolbar;
const searchControlsClass = styles.searchControls;
const searchActionsClass = styles.searchActions;
const searchHintClass = styles.searchHint;
const selectFieldClass = styles.selectField;
const textareaFieldClass = styles.textareaField;
const primaryCtaClass = styles.primaryCta;
const secondaryCtaClass = styles.secondaryCta;
const sectionKickerClass = styles.sectionKicker;
const statRowClass = styles.statRow;
---

<BaseLayout
	title="Royal Pop Client Stock"
	description="Private Royal Pop stock workspace for reviewing and updating inventory levels."
	noindex={true}
>
	<main class={styles.clientPage} data-client-stock-page>
		<header class={styles.topbar}>
			<div class={styles.topbarInner}>
				<a href="/client/" class={styles.backLink}>Royal Pop</a>

				<div class={styles.progress} aria-label="Client tools">
					<a href="/client/" class={ghostLinkClass}>Client dashboard</a>
					<a href="/client/orders/" class={ghostLinkClass}>Orders</a>
					<span class={styles.progressActive}>Stock</span>
				</div>

				<div class={styles.topbarActions}>
					<p class={styles.helpText}>Private access only</p>
					<button type="button" class={styles.logoutButton} data-client-logout hidden>Log out</button>
				</div>
			</div>
		</header>

		<section class={styles.hero}>
			<div class={styles.heroInner}>
				<div>
					<p class={styles.eyebrow}>Client stock</p>
					<h1 class={styles.heroTitle}>Keep storefront inventory aligned with the Royal Pop launch.</h1>
					<p class={styles.heroBody} data-stock-hero-body>
						Update inventory counts for the live buy page, keep preorder configurations open when needed, and leave notes for the next fulfilment pass.
					</p>
				</div>

				<div class={styles.heroMeta}>
					<div>
						<strong>Live storefront</strong>
						<span>These counts feed the public buy page availability states so customers see current stock at a glance.</span>
					</div>
					<div>
						<strong>Pre-order rule</strong>
						<span>Any configuration at 0 stays open as pre-order available, so the catalog never hard-locks by mistake.</span>
					</div>
					<div>
						<strong>Focused control</strong>
						<span>Use this dedicated page for counts and notes while leaving the orders workspace focused on fulfilment.</span>
					</div>
				</div>
			</div>
		</section>

		<section class={styles.dashboardSection}>
			<div class={styles.dashboardShell}>
				<section class={styles.loginPanel} data-client-login-panel>
					<div class={styles.panelHeader}>
						<p class={styles.sectionKicker}>Sign in</p>
						<h2>Open the stock console.</h2>
						<p>Use the same simple client credentials as the rest of the dashboard tools.</p>
					</div>

					<form class={styles.loginForm} data-client-login-form>
						<label class={styles.field}>
							<span>Username</span>
							<input type="text" name="username" autocomplete="username" required />
						</label>
						<label class={styles.field}>
							<span>Password</span>
							<input type="password" name="password" autocomplete="current-password" required />
						</label>

						<div class={styles.loginActions}>
							<button type="submit" class={styles.primaryCta} data-client-login-submit>Unlock stock</button>
						</div>

						<p class={styles.formStatus} data-client-auth-feedback data-state="info">
							Sign in to review and update storefront inventory.
						</p>
					</form>
				</section>

				<section class={styles.dashboardPanel} data-client-stock-panel hidden>
					<div class={toolbarClass}>
						<div class={styles.panelHeader}>
							<p class={styles.sectionKicker}>Stock workspace</p>
							<h2>Dedicated inventory management</h2>
							<p>Review current storefront counts, filter by style, and save notes for the next batch without leaving the Royal Pop client area.</p>
						</div>

						<form class={searchControlsClass} data-stock-filter-form>
							<label class={selectFieldClass}>
								<span>Style</span>
								<select name="styleFilter">
									<option value="">All styles</option>
									<option value="A">Style A</option>
									<option value="B">Style B</option>
								</select>
							</label>
							<div class={searchActionsClass}>
								<button type="submit" class={primaryCtaClass}>Apply filter</button>
								<button type="button" class={secondaryCtaClass} data-stock-reset>Show all</button>
							</div>
						</form>

						<p class={searchHintClass}>Tip: for now, the public buy page reflects the silver-finish rows shown here. Set quantity to 0 to keep a colorway open as pre-order available.</p>
					</div>

					<div class={styles.summaryGrid}>
						<article class={styles.summaryCard}>
							<p class={styles.sectionKicker}>Tracked configurations</p>
							<strong data-summary-tracked-configs>0</strong>
							<span>Visible colorways currently listed in this inventory view.</span>
						</article>
						<article class={styles.summaryCard}>
							<p class={styles.sectionKicker}>Units on hand</p>
							<strong data-summary-total-units>0</strong>
							<span>Total quantity currently assigned across the visible rows.</span>
						</article>
						<article class={styles.summaryCard}>
							<p class={styles.sectionKicker}>Low stock</p>
							<strong data-summary-low-stock>0</strong>
							<span>Rows with only 1 to 3 units remaining before pre-order fallback.</span>
						</article>
						<article class={styles.summaryCard}>
							<p class={styles.sectionKicker}>Pre-order configs</p>
							<strong data-summary-preorder>0</strong>
							<span>Rows currently set to 0 and therefore shown as pre-order available on the store.</span>
						</article>
					</div>

					<section class={styles.panel}>
						<div class={statRowClass}>
							<p class={styles.helpText}>Configurations</p>
							<strong data-stock-count>0 visible rows</strong>
						</div>
						<div class={styles.stockGrid} data-client-stock-grid></div>
					</section>

					<p class={styles.dashboardStatus} data-client-stock-feedback data-state="info">Stock console ready.</p>
				</section>
			</div>
		</section>

		<SiteFooter />

		<script
			define:vars={{
				apiBaseUrl,
				colorways,
				finishOptions,
				stockCardClass,
				stockCardMediaClass,
				stockCardBodyClass,
				stockCardHeaderClass,
				stockTitleClass,
				stockSubtitleClass,
				stockBadgeClass,
				inlineFieldClass,
				stockCardFooterClass,
				stockMetaClass,
				emptyStateClass,
				toolbarClass,
				searchControlsClass,
				searchActionsClass,
				searchHintClass,
				selectFieldClass,
				textareaFieldClass,
				primaryCtaClass,
				secondaryCtaClass,
				sectionKickerClass,
				statRowClass,
			}}
		>
			const normalizedApiBaseUrl = String(apiBaseUrl || "").replace(/\/$/, "");

			const initClientStockPage = () => {
				const root = document.querySelector("[data-client-stock-page]");
				if (!root || root.dataset.initialized === "true") return;
				root.dataset.initialized = "true";

				const loginPanel = root.querySelector("[data-client-login-panel]");
				const stockPanel = root.querySelector("[data-client-stock-panel]");
				const loginForm = root.querySelector("[data-client-login-form]");
				const loginSubmit = root.querySelector("[data-client-login-submit]");
				const authFeedback = root.querySelector("[data-client-auth-feedback]");
				const stockFeedback = root.querySelector("[data-client-stock-feedback]");
				const stockGrid = root.querySelector("[data-client-stock-grid]");
				const logoutButton = root.querySelector("[data-client-logout]");
				const filterForm = root.querySelector("[data-stock-filter-form]");
				const resetButton = root.querySelector("[data-stock-reset]");
				const stockCount = root.querySelector("[data-stock-count]");
				const summaryTrackedConfigs = root.querySelector("[data-summary-tracked-configs]");
				const summaryTotalUnits = root.querySelector("[data-summary-total-units]");
				const summaryLowStock = root.querySelector("[data-summary-low-stock]");
				const summaryPreorder = root.querySelector("[data-summary-preorder]");
				const heroBody = root.querySelector("[data-stock-hero-body]");
				const colorwayMap = new Map((colorways || []).map((colorway) => [colorway.id, colorway]));
				const finishMap = new Map((finishOptions || []).map((finish) => [finish.id, finish]));
				const SILVER_FINISH_ID = "silver";

				const state = {
					styleFilter: "",
					stock: [],
				};

				const setFeedback = (node, message, stateValue = "info") => {
					if (!node) return;
					node.textContent = message;
					node.dataset.state = stateValue;
				};

				const escapeHtml = (value) =>
					String(value ?? "")
						.replaceAll("&", "&amp;")
						.replaceAll("<", "&lt;")
						.replaceAll(">", "&gt;")
						.replaceAll('"', "&quot;")
						.replaceAll("'", "&#39;");

				const setAuthenticatedUi = (authenticated, username = "") => {
					if (loginPanel) loginPanel.hidden = authenticated;
					if (stockPanel) stockPanel.hidden = !authenticated;
					if (logoutButton) logoutButton.hidden = !authenticated;
					if (heroBody) {
						heroBody.textContent = authenticated
							? `Signed in as ${username || "client user"}. Update stock counts here and the public buy page will reflect the latest availability after each save.`
							: "Sign in to review and update storefront inventory without leaving the Royal Pop client area.";
					}
				};

				const mergeStockEntries = (entries) => {
					const entryMap = new Map(
						(entries || []).map((entry) => [`${entry.style}::${entry.colorwayId}::${entry.finishId}`, entry]),
					);

					return (colorways || []).map((colorway) => {
						const key = `${colorway.style}::${colorway.id}::${SILVER_FINISH_ID}`;
						const existing = entryMap.get(key);
						return {
							style: colorway.style,
							colorwayId: colorway.id,
							finishId: existing?.finishId || SILVER_FINISH_ID,
							quantityOnHand: Number(existing?.quantityOnHand || 0),
							notes: existing?.notes || "",
							updatedAt: existing?.updatedAt || "",
						};
					});
				};

				const getVisibleEntries = () => {
					return state.stock.filter((entry) => !state.styleFilter || entry.style === state.styleFilter);
				};

				const updateSummary = (entries) => {
					const visibleEntries = entries || [];
					const trackedConfigs = visibleEntries.length;
					const totalUnits = visibleEntries.reduce((sum, entry) => sum + Number(entry.quantityOnHand || 0), 0);
					const lowStock = visibleEntries.filter((entry) => Number(entry.quantityOnHand || 0) > 0 && Number(entry.quantityOnHand || 0) <= 3).length;
					const preorderConfigs = visibleEntries.filter((entry) => Number(entry.quantityOnHand || 0) <= 0).length;

					if (summaryTrackedConfigs) summaryTrackedConfigs.textContent = String(trackedConfigs);
					if (summaryTotalUnits) summaryTotalUnits.textContent = String(totalUnits);
					if (summaryLowStock) summaryLowStock.textContent = String(lowStock);
					if (summaryPreorder) summaryPreorder.textContent = String(preorderConfigs);
					if (stockCount) stockCount.textContent = `${trackedConfigs} visible row${trackedConfigs === 1 ? "" : "s"}`;
				};

				const renderStock = () => {
					if (!stockGrid) return;
					const visibleEntries = getVisibleEntries();
					updateSummary(visibleEntries);

					if (!visibleEntries.length) {
						stockGrid.innerHTML = `<div class="${emptyStateClass}">No stock rows match the current filter yet.</div>`;
						return;
					}

					stockGrid.innerHTML = visibleEntries
						.map((entry) => {
							const colorway = colorwayMap.get(entry.colorwayId);
							const finish = finishMap.get(entry.finishId);
							const availabilityLabel = Number(entry.quantityOnHand || 0) <= 0 ? "Sold Out/Pre-Order Available" : `${entry.quantityOnHand} available`;
							const updatedLabel = entry.updatedAt ? new Date(entry.updatedAt).toLocaleString("en-GB", { dateStyle: "medium", timeStyle: "short" }) : "Not saved yet";
							return `
								<article class="${stockCardClass}">
									<div class="${stockCardMediaClass}" style="background:${escapeHtml(colorway?.previewBackground || "#f5f5f7")}">
										<img src="${escapeHtml(colorway?.cardImage || colorway?.previewImage || "")}" alt="${escapeHtml(colorway?.name || entry.colorwayId)}" loading="lazy" />
									</div>
									<div class="${stockCardBodyClass}">
										<div class="${stockCardHeaderClass}">
											<div>
												<p class="${stockTitleClass}">${escapeHtml(colorway?.name || entry.colorwayId)}</p>
												<p class="${stockSubtitleClass}">${escapeHtml(colorway?.subtitle || "Royal Pop configuration")}</p>
												<p class="${stockMetaClass}">${escapeHtml(colorway?.styleText || `Style ${entry.style}`)} · ${escapeHtml(finish?.label || entry.finishId)}</p>
											</div>
											<span class="${stockBadgeClass}">${escapeHtml(availabilityLabel)}</span>
										</div>

										<form data-stock-form data-style="${escapeHtml(entry.style)}" data-colorway-id="${escapeHtml(entry.colorwayId)}" data-finish-id="${escapeHtml(entry.finishId)}">
											<div class="${inlineFieldClass}">
												<span>Quantity on hand</span>
												<input type="number" name="quantityOnHand" min="0" step="1" value="${escapeHtml(entry.quantityOnHand)}" />
											</div>
											<label class="${textareaFieldClass}">
												<span>Notes</span>
												<textarea name="notes" placeholder="Optional stock note for this configuration">${escapeHtml(entry.notes || "")}</textarea>
											</label>
											<div class="${stockCardFooterClass}">
												<p class="${stockMetaClass}">Last updated: ${escapeHtml(updatedLabel)}</p>
												<button type="submit" class="${primaryCtaClass}">Save stock</button>
											</div>
										</form>
									</div>
								</article>
							`;
						})
						.join("");
				};

				const loadStock = async () => {
					const response = await fetch(`${normalizedApiBaseUrl}/v1/client/stock`, { credentials: "include" });
					const payload = await response.json().catch(() => null);

					if (!response.ok) {
						throw new Error(payload?.error?.message || "The stock workspace could not load inventory levels.");
					}

					state.stock = mergeStockEntries(payload?.data?.stock || []);
					renderStock();
				};

				const syncSession = async () => {
					try {
						const response = await fetch(`${normalizedApiBaseUrl}/v1/client/session`, { credentials: "include" });
						const payload = await response.json().catch(() => null);
						const session = payload?.data;

						if (!response.ok || !session?.configured) {
							setAuthenticatedUi(false);
							setFeedback(authFeedback, session?.configured === false ? "Client dashboard credentials are not configured for this environment yet." : "Unable to verify dashboard access.", session?.configured === false ? "error" : "info");
							return;
						}

						if (!session.authenticated) {
							setAuthenticatedUi(false);
							setFeedback(authFeedback, "Sign in to review and update storefront inventory.", "info");
							return;
						}

						setAuthenticatedUi(true, session.username);
						setFeedback(stockFeedback, "Stock console ready.", "success");
						await loadStock();
					} catch (error) {
						setAuthenticatedUi(false);
						setFeedback(authFeedback, error instanceof Error ? error.message : "Unable to verify dashboard access.", "error");
					}
				};

				loginForm?.addEventListener("submit", async (event) => {
					event.preventDefault();
					const formData = new FormData(loginForm);
					const username = String(formData.get("username") || "").trim();
					const password = String(formData.get("password") || "");

					if (!username || !password) {
						setFeedback(authFeedback, "Enter both the username and password.", "error");
						return;
					}

					if (loginSubmit) {
						loginSubmit.disabled = true;
						loginSubmit.textContent = "Unlocking…";
					}
					setFeedback(authFeedback, "Checking credentials…", "info");

					try {
						const response = await fetch(`${normalizedApiBaseUrl}/v1/client/login`, {
							method: "POST",
							credentials: "include",
							headers: { "Content-Type": "application/json" },
							body: JSON.stringify({ username, password }),
						});
						const payload = await response.json().catch(() => null);
						if (!response.ok) {
							throw new Error(payload?.error?.message || "The dashboard credentials were rejected.");
						}

						setFeedback(authFeedback, "Access granted. Loading stock…", "success");
						loginForm.reset();
						await syncSession();
					} catch (error) {
						setFeedback(authFeedback, error instanceof Error ? error.message : "The dashboard credentials were rejected.", "error");
					} finally {
						if (loginSubmit) {
							loginSubmit.disabled = false;
							loginSubmit.textContent = "Unlock stock";
						}
					}
				});

				logoutButton?.addEventListener("click", async () => {
					await fetch(`${normalizedApiBaseUrl}/v1/client/logout`, {
						method: "POST",
						credentials: "include",
					});
					setAuthenticatedUi(false);
					setFeedback(authFeedback, "Signed out. Sign in again to reopen the stock console.", "info");
				});

				filterForm?.addEventListener("submit", (event) => {
					event.preventDefault();
					const formData = new FormData(filterForm);
					state.styleFilter = String(formData.get("styleFilter") || "").trim().toUpperCase();
					renderStock();
				});

				resetButton?.addEventListener("click", () => {
					state.styleFilter = "";
					filterForm?.reset();
					renderStock();
				});

				stockGrid?.addEventListener("submit", async (event) => {
					const form = event.target;
					if (!(form instanceof HTMLFormElement) || !form.matches("[data-stock-form]")) return;
					event.preventDefault();

					const submitButton = form.querySelector('button[type="submit"]');
					const formData = new FormData(form);
					const payload = {
						style: String(form.dataset.style || "").trim(),
						colorwayId: String(form.dataset.colorwayId || "").trim(),
						finishId: String(form.dataset.finishId || SILVER_FINISH_ID).trim(),
						quantityOnHand: Number(formData.get("quantityOnHand") || 0),
						notes: String(formData.get("notes") || "").trim(),
					};

					if (submitButton instanceof HTMLButtonElement) {
						submitButton.disabled = true;
						submitButton.textContent = "Saving…";
					}
					setFeedback(stockFeedback, `Saving ${payload.colorwayId}…`, "info");

					try {
						const response = await fetch(`${normalizedApiBaseUrl}/v1/client/stock`, {
							method: "PUT",
							credentials: "include",
							headers: { "Content-Type": "application/json" },
							body: JSON.stringify(payload),
						});
						const result = await response.json().catch(() => null);

						if (!response.ok) {
							throw new Error(result?.error?.message || "The stock entry could not be saved.");
						}

						setFeedback(stockFeedback, `Saved ${payload.colorwayId}.`, "success");
						await loadStock();
					} catch (error) {
						setFeedback(stockFeedback, error instanceof Error ? error.message : "The stock entry could not be saved.", "error");
					} finally {
						if (submitButton instanceof HTMLButtonElement) {
							submitButton.disabled = false;
							submitButton.textContent = "Save stock";
						}
					}
				});

				syncSession();
			};

			initClientStockPage();
			document.addEventListener("astro:page-load", initClientStockPage);
		</script>
	</main>
</BaseLayout>
