<script lang="ts">
	import { onMount } from 'svelte';
	import { page } from '$app/stores';
	import { goto } from '$app/navigation';
	import { get } from 'svelte/store';
	import { addNotification } from '$lib/core/stores/noti.js';
	import { departmentStore } from '$lib/core/stores/departments.js';
	import { permission as currentPerms } from '$lib/core/stores/permissions.js';
	import { referenceFromPage } from '$lib/core/stores/recipeStore.js';
	import {
		clearSheetPriceSentTypes,
		getCountryPrimaryLanguage,
		getPriceFromCells,
		lastRequestSheetPrice,
		sheetPriceLoading,
		type PriceSlot,
		type PriceSlotProduct
	} from '$lib/core/stores/sheetStore.js';
	import { requestSheetPrice } from '$lib/core/services/sheetService.js';
	import { waitForOpenSocket } from '$lib/core/stores/websocketStore.js';

	import Button from '$lib/components/ui/button/button.svelte';
	import Input from '$lib/components/ui/input/input.svelte';
	import * as Dialog from '$lib/components/ui/dialog/index.js';
	import * as Select from '$lib/components/ui/select/index.js';
	import * as Table from '$lib/components/ui/table/index.js';
	import Badge from '$lib/components/ui/badge/badge.svelte';
	import { Calculator, RefreshCw, Save, RotateCcw, Search } from '@lucide/svelte/icons';

	type AdjustmentMode =
		| 'increase_percent'
		| 'increase_amount'
		| 'decrease_amount'
		| 'decrease_percent';

	const adjustmentModeLabels: Record<AdjustmentMode, string> = {
		increase_percent: 'Increase by Percentage (%)',
		increase_amount: 'Increase by Fixed Amount',
		decrease_amount: 'Decrease by Fixed Amount',
		decrease_percent: 'Decrease by Percentage (%)'
	};

	const mockProducts: PriceSlotProduct[] = [
		{
			product_code: '12-01-01-0001',
			name: 'HOT ESPRESSO | เอสเพรสโซ่ร้อน',
			price: 30,
			row_index: 2
		},
		{ product_code: '12-01-01-0003', name: 'HOT AMERICANO | กาแฟดำร้อน', price: 35, row_index: 3 },
		{ product_code: '12-01-01-0004', name: 'HOT LATTE | ลาเต้ร้อน', price: 40, row_index: 5 },
		{ product_code: '12-01-01-0006', name: 'HOT MOCHA | มอคค่าร้อน', price: 55, row_index: 7 },
		{
			product_code: '12-01-02-0001',
			name: 'Iced AMERICANO | กาแฟดำเย็น',
			price: 40,
			row_index: 16
		},
		{ product_code: '12-01-02-0002', name: 'ICED LATTE | ลาเต้เย็น', price: 50, row_index: 17 },
		{ product_code: '12-01-02-0003', name: 'ICED MOCHA | มอคค่าเย็น', price: 60, row_index: 18 },
		{
			product_code: '12-02-01-0002',
			name: 'Hot THAI MILK TEA | ชาไทยร้อน',
			price: 40,
			row_index: 27
		},
		{
			product_code: '12-02-01-0004',
			name: 'Hot MATCHA LATTE | มัทฉะลาเต้ร้อน',
			price: 50,
			row_index: 29
		}
	];

	function buildMockSlots(): PriceSlot[] {
		return Array.from({ length: 10 }, (_, index) => {
			const slot = index + 1;
			const increase = slot === 1 ? 15 : slot === 2 ? 25 : slot * 5;

			return {
				slot,
				name: slot <= 2 ? `ProfileIncrease${increase}` : `PriceSlot${slot}`,
				description: slot <= 2 ? `increase price ${increase}%` : '',
				products: mockProducts.map((product) => ({
					...product,
					price:
						product.price === null
							? null
							: slot <= 2
								? Math.ceil((product.price * (1 + increase / 100)) / 5) * 5
								: product.price
				}))
			};
		});
	}

	let selectedCountry = $state<string>($page.params.country || get(departmentStore) || '');
	let enabledCountries = $state<string[]>([]);
	let selectedSlot = $state(1);
	const initialSlots = buildMockSlots();
	let slots = $state<PriceSlot[]>(initialSlots);
	let savedSnapshot = $state<PriceSlot[]>(structuredClone(initialSlots));
	let loading = $state(false);
	let productCodeSearch = $state('');
	let createDialogOpen = $state(false);
	let adjustmentMode = $state<AdjustmentMode>('increase_percent');
	let adjustmentValue = $state(15);
	let createName = $state('ProfileIncrease15');
	let createDescription = $state('increase price 15%');

	let currentSlot = $derived(slots.find((slot) => slot.slot === selectedSlot) ?? slots[0]);
	let selectedCountryLanguage = $derived(getCountryPrimaryLanguage(selectedCountry));
	let basePriceCells = $derived(
		$lastRequestSheetPrice[selectedCountry.toLowerCase()] ||
			$lastRequestSheetPrice[selectedCountry] ||
			{}
	);
	let basePricesLoadedCount = $derived(
		mockProducts.filter((product) => getBasePrice(product) !== null).length
	);
	let basePriceLoading = $derived($sheetPriceLoading);
	let filteredProducts = $derived(
		currentSlot.products.filter((product) => {
			const keyword = productCodeSearch.trim().toLowerCase();
			if (!keyword) return true;

			return product.product_code.toLowerCase().includes(keyword);
		})
	);
	let changedCount = $derived(countChangedProducts(currentSlot, savedSnapshot[selectedSlot - 1]));
	let hasHeaderChanges = $derived(
		currentSlot.name !== savedSnapshot[selectedSlot - 1]?.name ||
			currentSlot.description !== savedSnapshot[selectedSlot - 1]?.description
	);
	let hasChanges = $derived(changedCount > 0 || hasHeaderChanges);

	onMount(() => {
		referenceFromPage.set('priceslot');

		if (selectedCountry) {
			departmentStore.set(selectedCountry);
		}

		const userPerms = get(currentPerms).filter((x) => x.startsWith('document.write'));
		enabledCountries = userPerms.map((x) => x.split('.')[2]);
	});

	function getBasePrice(product: PriceSlotProduct): number | null {
		const cells = basePriceCells[product.product_code];
		if (cells?.length > 0) {
			const price = getPriceFromCells(selectedCountry.toLowerCase(), cells, 'cash_price');
			const parsed = Number(price);
			if (!Number.isNaN(parsed)) return parsed;
		}

		return product.price;
	}

	function getProductNames(product: PriceSlotProduct) {
		const [englishName = '', localName = ''] = product.name.split('|').map((name) => name.trim());

		return {
			english: englishName || product.name,
			local: localName || englishName || product.name
		};
	}

	function calculateAdjustedPrice(basePrice: number | null): number | null {
		if (basePrice === null) return null;

		const value = Number(adjustmentValue);
		if (Number.isNaN(value)) return basePrice;

		const nextPrice =
			adjustmentMode === 'increase_percent'
				? basePrice * (1 + value / 100)
				: adjustmentMode === 'increase_amount'
					? basePrice + value
					: adjustmentMode === 'decrease_percent'
						? basePrice * (1 - value / 100)
						: basePrice - value;

		return Math.max(0, Math.round(nextPrice));
	}

	async function loadBasePrices() {
		const productCodes = mockProducts.map((product) => product.product_code);
		if (productCodes.length === 0) return;

		const socket = await waitForOpenSocket();
		if (!socket) {
			addNotification('WARN:WebSocket not connected. Using local base price sample.');
			return;
		}

		clearSheetPriceSentTypes();
		const sent = requestSheetPrice(selectedCountry, productCodes);
		if (!sent) {
			addNotification('ERR:Failed to request base prices');
		}
	}

	function applyCreateTemplate() {
		const value = Number(adjustmentValue);
		const formattedValue = Number.isNaN(value) ? 0 : value;
		const isPercent =
			adjustmentMode === 'increase_percent' || adjustmentMode === 'decrease_percent';
		const isIncrease =
			adjustmentMode === 'increase_percent' || adjustmentMode === 'increase_amount';
		const action = isIncrease ? 'Increase' : 'Decrease';
		const valueLabel = isPercent ? `${formattedValue}%` : `${formattedValue}`;
		const nameSuffix = isPercent ? `${formattedValue}` : `Fixed${formattedValue}`;

		createName = `Profile${action}${nameSuffix}`;
		createDescription = `${isIncrease ? 'increase' : 'decrease'} price ${valueLabel}`;
	}

	function openCreateDialog() {
		applyCreateTemplate();
		createDialogOpen = true;
	}

	function createPriceSlotFromBase() {
		const nextSlotNumber = Math.max(0, ...slots.map((slot) => slot.slot)) + 1;

		const products = mockProducts.map((product) => ({
			...product,
			price: calculateAdjustedPrice(getBasePrice(product))
		}));

		const nextSlot: PriceSlot = {
			slot: nextSlotNumber,
			name: createName.trim() || `PriceSlot${nextSlotNumber}`,
			description: createDescription.trim(),
			products
		};

		slots = [...slots, nextSlot];
		savedSnapshot = [...savedSnapshot, structuredClone(nextSlot)];
		selectedSlot = nextSlotNumber;
		createDialogOpen = false;
		addNotification(`INFO:Created PriceSlot${nextSlotNumber} from base prices`);
	}

	function countChangedProducts(current: PriceSlot, saved: PriceSlot | undefined): number {
		if (!saved) return 0;

		return current.products.filter((product) => {
			const savedProduct = saved.products.find(
				(item) => item.product_code === product.product_code
			);
			return savedProduct?.price !== product.price;
		}).length;
	}

	function updateSlotField(field: 'name' | 'description', value: string) {
		slots = slots.map((slot) => (slot.slot === selectedSlot ? { ...slot, [field]: value } : slot));
	}

	function updateProductPrice(productCode: string, value: string) {
		const price = value === '' ? null : Number(value);

		slots = slots.map((slot) => {
			if (slot.slot !== selectedSlot) return slot;

			return {
				...slot,
				products: slot.products.map((product) =>
					product.product_code === productCode
						? { ...product, price: Number.isNaN(price) ? product.price : price }
						: product
				)
			};
		});
	}

	function resetSlot() {
		const savedSlot = savedSnapshot[selectedSlot - 1];
		if (!savedSlot) return;

		slots = slots.map((slot) => (slot.slot === selectedSlot ? structuredClone(savedSlot) : slot));
		addNotification(`INFO:Reset PriceSlot${selectedSlot}`);
	}

	function saveSlot() {
		savedSnapshot = savedSnapshot.map((slot) =>
			slot.slot === selectedSlot ? structuredClone(currentSlot) : slot
		);
		addNotification('WARN:PriceSlot backend is not ready. Changes are kept in this UI only.');
	}

	function loadPriceSlots() {
		loading = true;
		setTimeout(() => {
			loading = false;
			addNotification('WARN:PriceSlot backend is not ready. Showing UI mock data.');
		}, 250);
	}
</script>

<div class="min-h-screen bg-background">
	<div class="w-full px-6 py-8 lg:px-8">
		<div class="mb-7 flex flex-wrap items-start justify-between gap-5">
			<div class="min-w-0">
				<h1 class="text-4xl leading-tight font-bold tracking-normal">
					PriceSlot [ {selectedCountry.toUpperCase()} ]
				</h1>
				<p class="mt-4 text-muted-foreground">
					Edit sheet PriceSlot names, descriptions, and product prices.
				</p>
			</div>
			<div class="flex flex-wrap items-center gap-3">
				{#if enabledCountries.length > 0}
					<Select.Root
						type="single"
						value={selectedCountry}
						onValueChange={(v) => {
							if (v) {
								selectedCountry = v;
								goto(`/sheet/priceslot/${v}`);
							}
						}}
					>
						<Select.Trigger
							class="h-11 w-40 rounded-lg border-border/80 bg-card/70 px-4 font-semibold"
						>
							{selectedCountry.toUpperCase()}
						</Select.Trigger>
						<Select.Content>
							{#each enabledCountries as country}
								<Select.Item value={country}>
									{country.toUpperCase()}
								</Select.Item>
							{/each}
						</Select.Content>
					</Select.Root>
				{/if}

				<Button
					variant="outline"
					class="h-11 rounded-lg"
					onclick={loadPriceSlots}
					disabled={loading}
				>
					<RefreshCw class="mr-2 h-4 w-4" />
					Refresh
				</Button>
			</div>
		</div>

		<div class="mb-5 flex gap-2 overflow-x-auto border-b">
			{#each slots as slot}
				<button
					class={[
						'min-w-28 border-b-2 px-4 py-3 text-sm font-semibold transition-colors',
						selectedSlot === slot.slot
							? 'border-emerald-500 text-foreground'
							: 'border-transparent text-muted-foreground hover:text-foreground'
					]}
					onclick={() => (selectedSlot = slot.slot)}
				>
					PriceSlot{slot.slot}
				</button>
			{/each}
		</div>

		<div class="mb-5 rounded-lg border border-border/80 bg-card p-4 shadow-sm">
			<div
				class="grid grid-cols-1 items-end gap-4 xl:grid-cols-[180px_minmax(220px,1fr)_minmax(280px,1.25fr)_auto]"
			>
				<div class="flex min-w-0 flex-col justify-end gap-2 pb-1">
					<div class="flex items-center gap-3">
						<h2 class="text-xl font-bold tracking-normal">PriceSlot{selectedSlot}</h2>
						<Badge variant={hasChanges ? 'default' : 'secondary'}>
							{hasChanges ? `${changedCount} changes` : 'No changes'}
						</Badge>
					</div>
					<!-- <p class="text-sm text-muted-foreground">Column K/L</p> -->
				</div>

				<div class="space-y-1.5">
					<label class="text-xs font-medium text-muted-foreground" for="priceslot-name">Name</label>
					<Input
						id="priceslot-name"
						class="h-10"
						value={currentSlot.name}
						oninput={(event) => updateSlotField('name', event.currentTarget.value)}
					/>
				</div>

				<div class="space-y-1.5">
					<label class="text-xs font-medium text-muted-foreground" for="priceslot-description">
						Description
					</label>
					<Input
						id="priceslot-description"
						class="h-10"
						value={currentSlot.description}
						oninput={(event) => updateSlotField('description', event.currentTarget.value)}
					/>
				</div>

				<div class="flex flex-wrap items-end justify-start gap-2 xl:justify-end">
					<Button class="h-11 rounded-lg" onclick={openCreateDialog}>
						<Calculator class="mr-2 h-4 w-4" />
						Create PriceSlot
					</Button>
					<Button class="h-11 rounded-lg px-4" onclick={saveSlot} disabled={!hasChanges}>
						<Save class="mr-2 h-4 w-4" />
						Save Draft
					</Button>
					<Button
						variant="outline"
						class="h-11 rounded-lg px-4"
						onclick={resetSlot}
						disabled={!hasChanges}
					>
						<RotateCcw class="mr-2 h-4 w-4" />
						Reset
					</Button>
				</div>
			</div>
		</div>

		<div class="mx-auto w-full max-w-6xl">
			<div class="mb-3 flex flex-wrap items-end justify-between gap-3">
				<div class="w-full max-w-sm space-y-2">
					<label class="text-sm font-medium" for="product-code-search">Search ProductCode</label>
					<div class="relative">
						<Search
							class="pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground"
						/>
						<Input
							id="product-code-search"
							class="pl-9 font-mono"
							placeholder="12-01-01-0001"
							bind:value={productCodeSearch}
						/>
					</div>
				</div>
				<p class="text-sm text-muted-foreground">
					Showing {filteredProducts.length} of {currentSlot.products.length} products
				</p>
			</div>

			<div class="w-full overflow-hidden rounded-lg border">
				<Table.Root>
					<Table.Header>
						<Table.Row>
							<Table.Head class="w-[190px]">ProductCode</Table.Head>
							<Table.Head>ProductName [{selectedCountryLanguage}]</Table.Head>
							<Table.Head>ProductNameEng</Table.Head>
							<Table.Head class="w-[150px] text-right">Price</Table.Head>
						</Table.Row>
					</Table.Header>
					<Table.Body>
						{#each filteredProducts as product (product.product_code)}
							{@const productNames = getProductNames(product)}
							<Table.Row>
								<Table.Cell class="font-mono text-sm font-semibold">
									{product.product_code}
								</Table.Cell>
								<Table.Cell class="min-w-64 font-medium">{productNames.local}</Table.Cell>
								<Table.Cell class="min-w-64 text-muted-foreground">{productNames.english}</Table.Cell>
								<Table.Cell>
									<Input
										type="number"
										min="0"
										step="1"
										class="ml-auto w-32 text-right font-semibold"
										value={product.price ?? ''}
										oninput={(event) =>
											updateProductPrice(product.product_code, event.currentTarget.value)}
									/>
								</Table.Cell>
							</Table.Row>
						{/each}
						{#if filteredProducts.length === 0}
							<Table.Row>
								<Table.Cell colspan={4} class="h-28 text-center text-muted-foreground">
									No product code found.
								</Table.Cell>
							</Table.Row>
						{/if}
					</Table.Body>
				</Table.Root>
			</div>
		</div>
	</div>
</div>

<Dialog.Root bind:open={createDialogOpen}>
	<Dialog.Content class="sm:max-w-2xl">
		<Dialog.Header>
			<Dialog.Title>Create PriceSlot</Dialog.Title>
			<Dialog.Description>
				Choose how to adjust base prices before creating a new PriceSlot.
			</Dialog.Description>
		</Dialog.Header>

		<div class="space-y-5">
			<!-- <div class="flex items-center justify-between rounded-lg border bg-muted/30 px-4 py-3">
				<div>
					<p class="text-sm font-semibold">Base prices</p>
					<p class="text-sm text-muted-foreground">
						{basePriceLoading ? 'Loading prices from backend' : `${basePricesLoadedCount} products ready`}
					</p>
				</div>
				<Button variant="outline" onclick={loadBasePrices} disabled={basePriceLoading}>
					<RefreshCw class="mr-2 h-4 w-4" />
					Load Base
				</Button>
			</div> -->

			<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
				<div class="space-y-2">
					<label class="text-sm font-medium" for="adjustment-mode">Adjustment Mode</label>
					<Select.Root
						type="single"
						value={adjustmentMode}
						onValueChange={(v) => {
							if (v) adjustmentMode = v as AdjustmentMode;
							applyCreateTemplate();
						}}
					>
						<Select.Trigger id="adjustment-mode" class="h-10 rounded-lg">
							{adjustmentModeLabels[adjustmentMode]}
						</Select.Trigger>
						<Select.Content>
							<Select.Item value="increase_percent">Increase by Percentage (%)</Select.Item>
							<Select.Item value="increase_amount">Increase by Fixed Amount</Select.Item>
							<Select.Item value="decrease_percent">Decrease by Percentage (%)</Select.Item>
							<Select.Item value="decrease_amount">Decrease by Fixed Amount</Select.Item>
						</Select.Content>
					</Select.Root>
				</div>

				<div class="space-y-2">
					<label class="text-sm font-medium" for="adjustment-value">
						Adjustment Value
						{adjustmentMode === 'increase_percent' || adjustmentMode === 'decrease_percent'
							? '(%)'
							: ''}
					</label>
					<Input
						id="adjustment-value"
						type="number"
						min="0"
						step="1"
						value={adjustmentValue}
						oninput={(event) => {
							adjustmentValue = Number(event.currentTarget.value);
							applyCreateTemplate();
						}}
					/>
				</div>

				<div class="space-y-2">
					<label class="text-sm font-medium" for="create-name">Name</label>
					<Input
						id="create-name"
						value={createName}
						oninput={(event) => (createName = event.currentTarget.value)}
					/>
				</div>

				<div class="space-y-2">
					<label class="text-sm font-medium" for="create-description">Description</label>
					<Input
						id="create-description"
						value={createDescription}
						oninput={(event) => (createDescription = event.currentTarget.value)}
					/>
				</div>
			</div>
		</div>

		<Dialog.Footer>
			<Button variant="outline" onclick={() => (createDialogOpen = false)}>Cancel</Button>
			<Button onclick={createPriceSlotFromBase}>
				<Calculator class="mr-2 h-4 w-4" />
				Confirm Create
			</Button>
		</Dialog.Footer>
	</Dialog.Content>
</Dialog.Root>
