<script lang="ts">
	import { onDestroy, onMount } from 'svelte';
	import type { RecipelistMaterial } from './columns';
	import {
		convertFromInterProductCode,
		extractMaterialIdFromDisplay,
		getMaterialType
	} from '$lib/data/recipeService';
	import Label from '../ui/label/label.svelte';
	import Input from '../ui/input/input.svelte';
	import Separator from '$lib/components/ui/separator/separator.svelte';
	import Button from '../ui/button/button.svelte';
	import { PencilIcon } from '@lucide/svelte/icons';
	import * as Tooltip from '../ui/tooltip/index';
	import {
		latestRecipeToppingData,
		recipeDataEvent,
		toppingGroupFromServerQuery,
		toppingListFromServerQuery,
		toppingGroupFromMachineQuery,
		toppingListFromMachineQuery,
		referenceFromPage
	} from '$lib/core/stores/recipeStore';
	import { get } from 'svelte/store';

	let {
		row_uid,
		mat_id,
		onDetectToppingSlot,
		onDetectMixOrder,
		onEditValue,
		string_param,
		mix_order,
		feed,
		water,
		powder,
		syrup,
		stir_time
	}: {
		row_uid: number;
		mat_id: string;
		onDetectToppingSlot: any;
		onDetectMixOrder: any;
		onEditValue: any;
	} & RecipelistMaterial['values'] = $props();

	let currentMaterialType = $state('');
	let hasMixOrder = $state(false);
	let currentStringParams: any = $state({});
	let currentMaterialInt: number = $state(0);

	// toppings
	let currentToppings: any = $state([]);
	//    current topping of this row
	let currentToppingInRow: any = $state();
	let selectableToppingInGroup: any[] = $state([]);

	let unsubRecipeDataEvent: any;

	function isToppingId(mat_id: string): boolean {
		let mat_num = extractMaterialIdFromDisplay(mat_id);
		currentMaterialInt = mat_num;
		return mat_num > 8110 && mat_num < 8131;
	}

	function getToppingSlot() {
		return currentMaterialInt - 8110 - 1;
	}

	function extractStringParam() {
		if (string_param && string_param !== '') {
			let plist = string_param.split(',');

			for (let param of plist) {
				if (param !== '') {
					let kv = param.split('=');
					let key = kv[0];
					let value = kv[1] ?? '';

					console.log('key', key, 'value', value);
					currentStringParams[key] = value;
				}
			}
		}
	}

	function getPowderSyrupValue() {
		if (currentMaterialType === 'powder' || currentMaterialType === 'bean') {
			return powder.gram;
		} else if (currentMaterialType === 'syrup') {
			return syrup.gram;
		}
		return 0;
	}

	function getStirTimeName() {
		switch (currentMaterialType) {
			case 'whipper':
				return 'Mix';
			case 'bean':
				return 'Grinder';
			case 'others':
				if (currentMaterialInt == 8001 || currentMaterialInt == 8002) {
					return 'Clean';
				}
			default:
				return '';
		}
	}

	function getToppingDisplay() {
		let refFrom = get(referenceFromPage);
		let current_row_topping = currentToppings[getToppingSlot()];
		let groupQuery = get(
			refFrom === 'overview' ? toppingGroupFromServerQuery : toppingGroupFromMachineQuery
		);
		let listQuery = get(
			refFrom === 'overview' ? toppingListFromServerQuery : toppingListFromMachineQuery
		);

		// console.log(JSON.stringify(groupQuery[0]));
		// console.log(JSON.stringify(listQuery[0]));

		let groupData = groupQuery.find(
			(x: any) => x.groupID.toString() === current_row_topping['groupID']
		);
		let listData = listQuery.filter(
			(x: any) =>
				groupData &&
				Object.keys(groupData).includes('idInGroup') &&
				groupData['idInGroup'].split(',').includes(x.id.toString())
		);

		console.log('topping data', JSON.stringify(groupData), 'list', listData.length);

		currentToppingInRow =
			current_row_topping['groupID'] === 0 || current_row_topping['groupID'] === '0'
				? {
						name: 'Empty',
						otherName: 'Empty',
						id: 0
					}
				: groupData;
		selectableToppingInGroup =
			currentToppingInRow.id === 0
				? [
						{
							name: 'Empty',
							otherName: 'Empty',
							id: 0
						}
					]
				: listData;
	}

	function getCurrentSelectedToppingGroup() {
		if (currentToppingInRow) {
			return currentToppingInRow['otherName'] ?? currentToppingInRow['name'];
		} else {
			return 'Unknown';
		}
	}

	function getCurrentSelectedToppingList() {
		// FIXME: show unknown on preview

		let current_selected = selectableToppingInGroup.find(
			(x) => x.id === currentToppings[getToppingSlot()]['ListGroupID'][0]
		);
		if (currentToppings[getToppingSlot()]['ListGroupID'][0] === 0) {
			return 'Empty';
		}
		if (current_selected === undefined || current_selected === null) {
			return 'Unknown';
		}

		return current_selected.otherName ?? current_selected.name;
	}

	function initialize() {
		currentToppings = get(latestRecipeToppingData);

		hasMixOrder = mix_order == 1;

		extractStringParam();

		if (isToppingId(mat_id) && onDetectToppingSlot) {
			currentMaterialType = 'topping';

			getToppingDisplay();
			onDetectToppingSlot();
		} else {
			let mat_num = extractMaterialIdFromDisplay(mat_id);

			currentMaterialInt = mat_num;

			let mat_type_t1 = getMaterialType(mat_num);
			let mat_type_t2 = getMaterialType(convertFromInterProductCode(mat_num));

			// console.log('type get', mat_type_t1, mat_type_t2);
			currentMaterialType = mat_type_t1 === mat_type_t2 ? mat_type_t1 : mat_type_t2;

			if (hasMixOrder) {
				console.log('detect mix order', mat_num);
			}

			if (feed.parameter > 0 || feed.pattern > 0) {
				console.log('has feed fields', JSON.stringify(feed));
			}
		}
	}

	function handleEvents(event: { event_type: string; payload: any; index: number | undefined }) {
		// console.log('triggered event', event.event_type, JSON.stringify(event.payload));
		if (event.event_type === 'mat_change') {
			// update value, do re-render
			initialize();
		} else if (event.event_type === 'edit_mat_field') {
			console.log('request edit mat');
			// pack all shown data
			recipeDataEvent.set({
				event_type: 'edit_mat_field_prep',
				payload: {
					mat_id: currentMaterialInt,
					mat_type: currentMaterialType,
					mat_name: mat_id,
					params: currentStringParams,
					toppings: currentToppings,
					current_topping_group: currentToppingInRow,
					current_topping_list: selectableToppingInGroup,
					has_mix_ord: hasMixOrder,
					feed,
					water,
					powder,
					syrup,
					stir_time
				},
				index: row_uid
			});
		} else if (event.event_type === 'save_mat_field') {
			console.log('receive saving process mat, do refresh...');
			let change_values = event.payload.change;

			// apply now
			let keys = Object.keys(change_values);
			console.log('change keys', JSON.stringify(keys));
		}
	}

	onMount(() => {
		initialize();
		unsubRecipeDataEvent = recipeDataEvent.subscribe((event) => {
			if (event !== null && event.index !== undefined && event.index === row_uid) {
				// has some event
				handleEvents(event);
			}
		});
	});

	onDestroy(() => {
		if (unsubRecipeDataEvent) {
			unsubRecipeDataEvent();
		}
	});
</script>

<div>
	{#if currentMaterialType === 'topping'}
		<!-- do topping layout -->
		<div>
			<!-- get name of topping -->
			<div class="mx-auto my-4 flex flex-row gap-8">
				<p class="text-muted-foreground">
					<b>
						{getCurrentSelectedToppingGroup()}
					</b>, {getCurrentSelectedToppingList()}
				</p>
			</div>
		</div>
	{:else}
		<div>
			<div class="flex w-full flex-row gap-4">
				<!-- string param -->
				{#if !hasMixOrder}
					<!-- check if param is esp-v2-press-value -->

					{#if currentStringParams['esp-v2-press-value']}
						<div class="my-4">
							<!-- <Label class="font-bold" for={`esp_v2_press_${row_uid}`}>Press</Label>
						<div class="flex flex-row items-center space-x-2 text-center">
							<Input
								class="w-16"
								id={`esp_v2_press_${row_uid}`}
								type="number"
								value={currentStringParams['esp-v2-press-value']}
								onchangecapture={(v) =>
									triggerEditChange(`${v.currentTarget.id}=${v.currentTarget.value}`)}
							/>
							<p>mA</p>
						</div> -->

							<p class="text-muted-foreground">
								<b> Press </b>
								{currentStringParams['esp-v2-press-value']} mA
							</p>
						</div>
					{/if}

					{#if water.yield > 0}
						<div class="my-4">
							<!-- <Label class="font-bold" for={`water_yield_volume_${row_uid}`}>Hot</Label>
						<div class="flex flex-row items-center space-x-2 text-center">
							<Input
								class="w-16"
								type="number"
								id={`water_yield_volume_${row_uid}`}
								value={water.yield}
								onchangecapture={(v) =>
									triggerEditChange(`${v.currentTarget.id}=${v.currentTarget.value}`)}
							/>
							<p>ml</p>
						</div> -->

							<p class="text-muted-foreground">
								<b> Hot </b>
								{water.yield} ml
							</p>
						</div>
					{/if}

					{#if water.cold > 0}
						<div class="my-4">
							<!-- <Label class="font-bold" for={`water_cold_volume_${row_uid}`}>Cold</Label>
						<div class="flex flex-row items-center space-x-2 text-center">
							<Input
								class="w-16"
								type="number"
								id={`water_cold_volume_${row_uid}`}
								value={water.cold}
								onchangecapture={(v) =>
									triggerEditChange(`${v.currentTarget.id}=${v.currentTarget.value}`)}
							/>
							<p>ml</p>
						</div> -->
							<p class="text-muted-foreground">
								<b> Hot </b>
								{water.cold} ml
							</p>
						</div>
					{/if}

					{#if currentMaterialType !== 'cup' && currentMaterialType !== 'topping' && stir_time > 0}
						<div class="my-4">
							<!-- <Label class="font-bold" for={`stir_time_${row_uid}`}>{getStirTimeName()}</Label>
						<div class="flex flex-row items-center space-x-2 text-center">
							<Input
								class="w-16"
								type="number"
								id={`stir_time_${row_uid}`}
								value={stir_time / 10}
								onchangecapture={(v) =>
									triggerEditChange(`${v.currentTarget.id}=${v.currentTarget.value}`)}
							/>
							<p>sec</p>
						</div> -->
							<p class="text-muted-foreground">
								<b>{getStirTimeName()}</b>
								{stir_time / 10} sec(s)
							</p>
						</div>
					{/if}
				{/if}

				<!-- display powder/syrup -->
				{#if currentMaterialType === 'syrup' || currentMaterialType === 'powder' || currentMaterialType === 'bean'}
					<div class="my-4">
						<!-- <Label class="font-bold" for={`powder_syrup_volume_${row_uid}`}>Volume</Label>
					<div class="flex flex-row items-center space-x-2 text-center">
						<Input
							class="w-16"
							type="number"
							id={`powder_syrup_volume_${row_uid}`}
							value={getPowderSyrupValue()}
							onchangecapture={(v) =>
								triggerEditChange(`${v.currentTarget.id}=${v.currentTarget.value}`)}
						/>
						<p>gram</p> -->
						<p class="text-muted-foreground">
							<b> Volume </b>
							{getPowderSyrupValue()} gram
						</p>
					</div>
				{/if}
			</div>
			<!-- feed pattern -->
			{#if feed.parameter > 0 || feed.pattern > 0}
				<div class="mx-auto my-4 flex items-center gap-8 text-center">
					<p class="text-muted-foreground">Style {feed.pattern}</p>
					<p class="text-muted-foreground">Level {feed.parameter}</p>
				</div>
			{/if}
		</div>
	{/if}

	<!-- show sheet -->
</div>
