<script lang="ts">
	import * as Tabs from '$lib/components/ui/tabs/index';
	import * as Card from '$lib/components/ui/card/index';
	import Label from '$lib/components/ui/label/label.svelte';
	import Input from '$lib/components/ui/input/input.svelte';
	import Button from '$lib/components/ui/button/button.svelte';
	import Spinner from '$lib/components/ui/spinner/spinner.svelte';
	import { Badge } from '$lib/components/ui/badge/index';
	import * as Item from '$lib/components/ui/item/index';
	import { createEventDispatcher, onDestroy, onMount } from 'svelte';
	import RecipelistTable from './recipelist-table.svelte';

	import * as adb from '$lib/core/adb/adb';
	import { columns, type RecipelistMaterial } from './columns';
	import { get, readable, writable } from 'svelte/store';
	import {
		currentEditingRecipeProductCode,
		latestRecipeToppingData,
		materialFromMachineQuery,
		materialFromServerQuery
	} from '$lib/core/stores/recipeStore';
	import { generateIcing } from '$lib/helpers/icingGen';
	import { getMachineStatus, machineInfoStore } from '$lib/core/stores/machineInfoStore';
	import MachineInfo from '../machine-info.svelte';
	import { v4 as uuidv4 } from 'uuid';
	import { addNotification } from '$lib/core/stores/noti';
	import { env } from '$env/dynamic/public';
	import { sendCommand, sendReset } from '$lib/core/brew/command';
	import { isAdbWriterAvailable } from '$lib/core/stores/adbWriter';
	import { sendToAndroid } from '$lib/core/stores/adbWriter';

	//
	let {
		recipeData,
		onPendingChange,
		productCode,
		refPage
	}: { recipeData: any; onPendingChange: any; productCode: string; refPage: string } = $props();

	let menuName: string = $state('');

	let materialSnapshot: any = $state();
	let machineInfoSnapshot: any = $state();

	let recipeListMatState: RecipelistMaterial[] = $state([]);
	let recipeListOriginal: RecipelistMaterial[] = $state([]);

	let toppingSlotState: any = $state([]);

	const recipeDetailDispatch = createEventDispatcher();

	function remappingToColumn(data: any[]): RecipelistMaterial[] {
		let ret: RecipelistMaterial[] = [];
		// expect recipelist
		if (materialSnapshot) {
			let d_cnt = 0;
			for (let rpl of data) {
				let mat = materialSnapshot.filter(
					(x: any) => x['id'].toString() === rpl['materialPathId'].toString()
				)[0];

				// console.log('mat filter get', Object(mat), Object.keys(mat));

				let name = mat ? mat['materialOtherName'] : rpl['materialPathId'];

				if (rpl['materialPathId'] === 0) {
					name = '-';
				}

				// let gen_id = generateRowId();

				// console.log(`generated for ${rpl['materialPathId']} = ${gen_id}`);

				ret.push({
					id: d_cnt,
					material_id: `${name} (${rpl['materialPathId']})`,
					is_use: rpl['isUse'],
					values: {
						string_param: rpl['StringParam'],
						mix_order: rpl['MixOrder'],
						stir_time: rpl['stirTime'],
						feed: {
							pattern: rpl['FeedPattern'],
							parameter: rpl['FeedParameter']
						},
						powder: {
							gram: rpl['powderGram'],
							time: rpl['powderTime']
						},
						syrup: {
							gram: rpl['syrupGram'],
							time: rpl['syrupTime']
						},
						water: {
							cold: rpl['waterCold'],
							yield: rpl['waterYield']
						}
					}
				});
				d_cnt++;
			}
		}

		return ret;
	}

	async function getCurrentQueue() {
		let inst = adb.getAdbInstance();
		if (inst) {
			let current_brewing = await adb.pull(env.PUBLIC_BREW_CURRENT_RECIPE);
			// console.log(`current brewing queue: ${current_brewing}`);
			if (current_brewing === '') {
				current_brewing = '{}';
			}

			return JSON.parse(current_brewing ?? '{}');
		}

		return {
			error: 'instance lost'
		};
	}

	async function resetAllPendingCmds() {
		// send reset to brew
		try {
			await sendReset();
			addNotification(`INFO:Reset completed!`);
		} catch (e) {
			addNotification(`ERR:${e}`);
		}
	}

	async function saveRecipe() {
		recipeDetailDispatch('saveRecipe');
	}

	async function sendTriggerBrewNow() {
		// check queue ready
		// let currentBrewingQueue = await getCurrentQueue();
		// console.log('checking queue ... ', Object.keys(currentBrewingQueue).length);

		await sendToAndroid({
			type: 'brew_prep',
			payload: {
				start: new Date().toLocaleTimeString()
			}
		});

		// if (Object.keys(currentBrewingQueue).length != 0) {
		// 	addNotification('ERR:Brewing queue is full, please check machine or press `reset`');
		// 	return;
		// }

		//
		let inst = adb.getAdbInstance();
		if (inst) {
			console.log('check adb writer', isAdbWriterAvailable());
			recipeDetailDispatch('brewNow');
		} else {
			console.log('result check fail');
		}
	}

	async function checkChanges(productCode: string, original: any) {
		// console.log('old', original, 'updated', recipeListMatState);
		if (recipeListOriginal.length == 0) {
			recipeListOriginal = original;
		}

		if (original !== recipeListMatState) {
			await onPendingChange({
				target: 'recipeList',
				ref_pd: productCode,
				value: original
			});
		}
	}

	onMount(() => {
		machineInfoSnapshot = get(machineInfoStore);

		if (recipeData) {
			menuName =
				recipeData['name'] ?? (recipeData['otherName'] ? recipeData['otherName'] : 'Not set');

			if (refPage == 'overview') {
				materialSnapshot = get(materialFromServerQuery);
			} else if (refPage == 'brew') {
				materialSnapshot = get(materialFromMachineQuery);
			}

			recipeListMatState = remappingToColumn(recipeData['recipes']);
			toppingSlotState = recipeData['ToppingSet'];

			latestRecipeToppingData.set(toppingSlotState);

			currentEditingRecipeProductCode.set(productCode);

			// save old value\
		}
	});
</script>

<!-- show info -->
<!-- latest edit date -->
<!-- Menu Status -->

<div class="-mb-4 flex w-full flex-col gap-6">
	<Tabs.Root value="info">
		<div class="flex flex-row justify-between">
			<Tabs.List>
				<Tabs.Trigger value="info">Info</Tabs.Trigger>
				<Tabs.Trigger value="details">Details</Tabs.Trigger>
			</Tabs.List>
			{#if refPage === 'brew'}
				<div>
					<Button type="button" variant="default" onclick={() => saveRecipe()}>Save</Button>

					{#if $machineInfoStore?.status == 'IDLE' || $machineInfoStore?.status == ''}
						<Button type="button" variant="default" onclick={async () => sendTriggerBrewNow()}
							>Test Brew</Button
						>
					{/if}
				</div>
			{/if}
		</div>

		<Tabs.Content value="info">
			<Card.Root>
				<Card.Header>
					<Card.Title>Info</Card.Title>
					<Card.Description>Info about this menu</Card.Description>
				</Card.Header>

				<Card.Content class="grid gap-6">
					<div class="grid grid-flow-row gap-3">
						<Label for="tabs-menu-name">Name</Label>
						<Input id="tabs-menu-name" value={recipeData['name'] ?? ''} />
						<Label for="tabs-menu-other-name">Other Name</Label>
						<Input id="tabs-menu-other-name" value={recipeData['otherName'] ?? ''} />
					</div>

					<div class="grid gap-3"></div>
				</Card.Content>
			</Card.Root>
		</Tabs.Content>

		<Tabs.Content value="details">
			<!-- hide by machine state -->

			{#if $machineInfoStore?.status == 'IDLE' || $machineInfoStore?.status == '' || refPage == 'overview'}
				<RecipelistTable
					data={recipeListMatState}
					{columns}
					onStateChange={checkChanges}
					{productCode}
				/>
			{:else}
				<Card.Root>
					<Card.Content>
						<div class="grid h-[60vh] w-full place-items-center rounded-md border">
							<div class="m-4 flex flex-row gap-2">
								<Spinner />Machine is working. Please wait for a moment.
							</div>
						</div>
					</Card.Content>
				</Card.Root>
			{/if}
		</Tabs.Content>
	</Tabs.Root>
</div>
