<script lang="ts">
	import { put } from '$lib/utils';
	import IconPicker from './IconPicker.svelte';
	import Rect from './Rect.svelte';
	import type { Node, ActionType, LinkNode } from './types';

	//
	// consts
	//
	const connectionPointSize = 10;

	//
	//
	//

	let hover = $state(false);
	let iconSelector: HTMLDialogElement;

	let {
		node = $bindable(),
		grid_size,
		canvasX,
		canvasY,
		mouseAction,
		onremove,
		linkMode,
		onNodePointClick,
		linkSource
	}: {
		node: Node;
		grid_size: number;
		canvasX: (x: number) => number;
		canvasY: (y: number) => number;
		mouseAction: ActionType;
		onremove: () => void;
		linkMode: boolean;
		onNodePointClick: (x: number, y: number) => void;
		linkSource: LinkNode | undefined;
	} = $props();

	let cx = $derived(canvasX(node.x));
	let cy = $derived(canvasY(node.y));

	async function save() {
		try {
			const r = await put('user/status/node', node);
			node = r;
		} catch (e) {
			console.log('TODO inform the user', e);
		}
	}
</script>

<Rect x={cx - 1} y={cy - 1} height={node.height * grid_size + 1} width={node.width * grid_size + 1}>
	<div
		class="bg-white shadow-lg border-slate-300 border-solid border rounded-lg w-full h-full flex flex-col justify-center items-center gap-2 relative"
		role="none"
		onmouseenter={() => {
			if (mouseAction === undefined || mouseAction === 'link') {
				hover = true;
			}
		}}
		onmouseleave={() => {
			if (hover) {
				hover = false;
			}
		}}
	>
		<button
			disabled={node.permission !== 0}
			onclick={() => {
				iconSelector.showModal();
			}}
		>
			<h1>
				{#if node.icon}
					<span class="bi bi-{node.icon}"></span>
				{:else}
					Select an icon
				{/if}
			</h1>
		</button>
		<div class="p-2">
			{#if node.permission === 0}
				<input bind:value={node.name} class="finput text-center" onblur={save} />
			{:else}
				{node.name}
			{/if}
		</div>
		{#if node.permission === 0 && !linkMode}
			<button
				class="bg-red-400 hover:bg-red-800 -top-[10px] -right-[10px] rounded-full h-[20px] w-[20px] absolute text-center text-white leading-none"
				onclick={onremove}
			>
				<div class="bi bi-x mt-[2px]"></div>
			</button>
			<!-- Controll items -->
			<div class="absolute flex gap-1 top-1 left-1">
				<button
					class="text-purple-400 hover:text-purple-800 rounded-full h-[20px] w-[20px] text-center leading-none"
					onclick={async () => {
						node.visible = !node.visible;
						try {
							await put('user/status/node', node);
						} catch (e) {
							console.log('TODO inform the user', e);
						}
					}}
				>
					{#if node.visible}
						<div class="bi bi-eye-fill mt-[2px]"></div>
					{:else}
						<div class="bi bi-eye-slash-fill mt-[2px]"></div>
					{/if}
				</button>
				<button
					class="text-purple-400 hover:text-purple-800 rounded-full h-[20px] w-[20px] text-center leading-none"
					onclick={async () => {
						node.endable = !node.endable;
						try {
							await put('user/status/node', node);
						} catch (e) {
							console.log('TODO inform the user', e);
						}
					}}
				>
					{#if node.endable}
						<div class="bi bi-align-end mt-[2px]"></div>
					{:else}
						<div class="bi bi-align-start mt-[2px]"></div>
					{/if}
				</button>
			</div>
		{/if}
	</div>

	<!--
        Node connections ponints
    -->
	{#if hover && linkMode}
		<!-- Top -->
		{#each { length: node.width } as _, i}
			{@const adjust = grid_size / 2 + grid_size * i - connectionPointSize / 2}
			<button
				class="{linkSource?.x === i + 1 && linkSource?.y === 0
					? 'bg-red-200 hover:bg-red-800'
					: 'bg-blue-200 hover:bg-blue-800'} rounded-full absolute"
				style="top: 0px; left: {adjust}px; width: {connectionPointSize}px; height: {connectionPointSize}px;"
				onclick={() => onNodePointClick(i, -1)}
			></button>
		{/each}

		<!-- Bottom -->
		{#each { length: node.width } as _, i}
			{@const adjust = grid_size / 2 + grid_size * i - connectionPointSize / 2}
			<button
				class="{linkSource?.x === i + 1 && linkSource?.y === node.height
					? 'bg-red-200 hover:bg-red-800'
					: 'bg-blue-200 hover:bg-blue-800'} rounded-full absolute"
				style="bottom: 0px; left: {adjust}px; width: {connectionPointSize}px; height: {connectionPointSize}px;"
				onclick={() => onNodePointClick(i, node.height)}
			></button>
		{/each}

		<!-- Left -->
		{#each { length: node.height } as _, i}
			{@const adjust = grid_size / 2 + grid_size * i - connectionPointSize / 2}
			<button
				class="{linkSource?.x === 0 && linkSource?.y === i + 1
					? 'bg-red-200 hover:bg-red-800'
					: 'bg-blue-200 hover:bg-blue-800'} rounded-full absolute"
				style="left: 0px; top: {adjust}px; width: {connectionPointSize}px; height: {connectionPointSize}px;"
				onclick={() => onNodePointClick(-1, i)}
			></button>
		{/each}

		<!-- Right -->
		{#each { length: node.height } as _, i}
			{@const adjust = grid_size / 2 + grid_size * i - connectionPointSize / 2}
			<button
				class="{linkSource?.x === node.width && linkSource?.y === i + 1
					? 'bg-red-200 hover:bg-red-800'
					: 'bg-blue-200 hover:bg-blue-800'} rounded-full absolute"
				style="right: 0px; top: {adjust}px; width: {connectionPointSize}px; height: {connectionPointSize}px;"
				onclick={() => onNodePointClick(node.width, i)}
			></button>
		{/each}
	{/if}
</Rect>

<IconPicker
	bind:dialog={iconSelector}
	onselect={(text) => {
		node.icon = text;
		window.requestAnimationFrame(() => {
			save();
		});
	}}
/>
