<script>
	import LineEditor from '../../Components/LineEditor.svelte';
    import Autocomplete from '../../Components/Autocomplete.svelte';

	import { api, drop, patch, post } from '../../urls.svelte';
	import { error, yikes } from '../../warn.svelte';
	import { t }  from '../../translations.svelte';
	let { account, addToFilter = tag => {}, transaction, users } = $props();
	let hidden = $state(false);

	function deleteTransaction(ev){
		if (confirm(t('confirm_delete',{element:transaction.purpose}))){
			const url = api(`accounting/transaction/${transaction.id}`);
			const res = drop(url);
			if (res.ok){
				yikes();
			} else error(res);
		}
	}

	async function dropTag(tag){
		var url = api(`accounting/transaction/${transaction.id}/tag`)
		var res = await drop(url,{tag});
		if (res.ok){
			yikes();
			transaction.tags = transaction.tags.filter(t => t != tag);
			return true;
		}
		error(res);
		return false;
	}

	async function getCandidates(key){
		if (!key) return;
		var url = api(`accounting/${account.id}/tags`)
		var res = await post(url,key);
		if (res.ok){
		    yikes();
		    const input = await res.json();
		    return Object.values(input).map(mapDisplay);
		} else {
		    error(res);
		    return {};
		}
	}

	function mapDisplay(object){
		if (object.display){
			return object;
		} else if (object.name) {
			return {...object, display: object.name};
		} else {
		    return { display : object }
		}
	}

	async function onCommit(tag){
		let url = api(`accounting/transaction/${transaction.id}`);
		let res = await patch(url,{tag:tag.display});
		if (res.ok) {
			yikes();
			transaction.tags.push(tag.display);
			transaction.tags.sort();
			return true;
		}
		error(res);
		return false;
	}

	async function setAmount(amount){
		let result = await update({amount});
		hidden = (amount == 0);
		return result;
	}
	async function setDate(date){
		return await update({date});
	}

	async function setDestination(destination){
		return await update({destination});
	}

	async function setPurpose(purpose){
		return await update({purpose});
	}

	async function setSource(source){
		return await update({source});
	}

	async function update(changes){
		let url = api('accounting/transaction/'+transaction.id);
		let res = await patch(url,changes);
		if (res.ok){
			yikes();
			for (let [k,v] of Object.entries(changes)) transaction[k]=v;
			return true;
		}
		error(res);
		return false;
	}
</script>

{#if !hidden}
<tr>
	<td>
		<LineEditor type="date" wrapper="span" editable="true" value={transaction.date} onSet={setDate} />
	</td>
	{#each Object.entries(users) as [id,user]}
	<td class="amount">
		{#if id == transaction.source.id}
		-<LineEditor type="number" wrapper="span" editable="true" value={(+transaction.amount).toFixed(2)} onSet={setAmount} title={t('Set to zero in order to drop the transaction')} />&nbsp;{account.currency}
		{/if}
		{#if id == transaction.destination.id}
		<LineEditor type="number" wrapper="span" editable="true" value={(+transaction.amount).toFixed(2)} onSet={setAmount} title={t('Set to zero in order to drop the transaction')} />&nbsp;{account.currency}
		{/if}
	</td>
	{/each}
	<td class="party">
		{#if !transaction.source.id}
		← <LineEditor wrapper="span" editable="true" value={transaction.source.value} onSet={setSource} />
		{/if}
		{#if !transaction.destination.id}
		→ <LineEditor wrapper="span" editable="true" value={transaction.destination.value} onSet={setDestination} />
		{/if}
	</td>
	<td class="purpose">
		<LineEditor wrapper="span" editable="true" value={transaction.purpose} onSet={setPurpose} />
	</td>
	<td class="taglist">
		{#each transaction.tags as tag,i}
		<span class="tag">
			<span onclick={() => addToFilter(tag)}>{tag}</span>&nbsp;<button onclick={() => dropTag(tag)} class="symbol"></button>
		</span>
		{/each}
		<span class="tag editor">
	        <Autocomplete {getCandidates} {onCommit} />
	    </span>
	</td>
	<td class="actions">
		<button class="symbol" onclick={deleteTransaction}></button>
	</td>
</tr>
{/if}
