<script>
	import { onMount } from 'svelte';
	import { useTinyRouter } from 'svelte-tiny-router';

	import LineEditor     from '../../Components/LineEditor.svelte';
	import MarkdownEditor from '../../Components/MarkdownEditor.svelte';
	import Permissions    from '../../Components/PermissionEditor.svelte';

	import { api, get, patch, post } from '../../urls.svelte';
	import { error, yikes } from '../../warn.svelte';
	import { t } from '../../translations.svelte';
    import { user }          from '../../user.svelte.js';

	let { id } = $props();
	let visible_to_guests = false;
	let new_option = $state({name:'',description:{'source':'',rendered:''}});
	let new_weight = $state({description:'',weight:0});
	let poll = $state(null);
	let members = $state([]);

	function addMember(member){
		for (let [id,name] of Object.entries(member)) update_permissions({user_id:+id,permission:4});
		return true;
	}

	function dropMember(member){
		let user_id = member.user.id;
		if (update_permissions({user_id,permission:0})){
			members = members.filter(m => m.user.id != user_id);
		}
	}

	async function load(){
		let url = api('poll/'+id);
		let res = await get(url);
		if (res.ok){
			poll = await res.json();
			for (let perm of Object.values(poll.permission)){
				members.push({ user : { name : perm.name, id : perm.id }, permission: { name : perm.permission.name, code: perm.permission.code}});
			}
			visible_to_guests = !poll.private;
			yikes();
		} else error(res);
	}

	async function patch_poll(field, newVal){
		let url = api(`poll/${id}`);
		let data = {}
		data[field] = newVal;
		let res = await patch(url,data);
		if (res.ok) {
			yikes();
			const json = await res.json();
			poll = { ...poll, ...json };
			return true;

		}
		error(res);
		return false;
	}


	async function patch_option(option, field, newVal){
		let url = api(`poll/${id}/option/${option.id}`);
		let res = await patch(url,{[field]: newVal});
		if (res.ok) {
			yikes();
			const json = await res.json();
			if (field == 'name' && newVal == ''){
				poll.options = poll.options.filter(o => o.id !== option.id);
			} else poll.options = json.options;
			return true;
		}
		error(res);
		return false;
	}

	async function patch_weight(data){
		let url = api(`poll/${id}/weight`);
		let res = await patch(url,data);
		if (res.ok) {
			yikes();
			const json = await res.json();
			const weights = json.weights;
			for (let weight of Object.keys(data)){
				let desc = data[weight];
				if (desc) {
					poll.weights[weight] = desc;
				} else delete poll.weights[weight]; // TODO: this corrupts the display of the following element!
			}
			return true;
		}
		error(res);
		return false;
	}


	async function save_new_option(){
		if (!new_option.name) return;
		let url = api('poll/'+id+'/option');
		let res = await post(url,new_option);
		if (res.ok){
			yikes();
			const json = await res.json();
			poll.options = json.options;
		} else error(res);
	}

	function save_new_weight(e){
		const data = {};
		data[new_weight.weight] = new_weight.description;
		patch_weight(data);
	}

	function toggle_guest(e){
		patch_poll('private',!visible_to_guests);
	}

	async function update_permissions(data){
		let url = api(`poll/${id}/permissions`);
		let res = await post(url,data);
		if (res.ok) {
			yikes();
			let json = await res.json();
			members = members.filter(m => m.user.id != json.user.id);
			members.push(json);
			console.log({members});
			return true;
		}
		error(res);
		return false;
	}

	onMount(load);

</script>

<fieldset>
	<legend>{t('edit poll',{id:id})}</legend>
	{#if poll && poll.name}
	<fieldset>
		<legend>{t('name')}</legend>
		<LineEditor bind:value={poll.name} editable={true} onSet={name => patch_poll('name',name)} />
	</fieldset>
	<fieldset>
		<legend>{t('description')}</legend>
		<MarkdownEditor bind:value={poll.description} onSet={desc => patch_poll('description',desc)} />
	</fieldset>
	<fieldset>
		<legend>{t('permissions')}</legend>
		<Permissions {addMember} {members} {dropMember} updatePermission={(user_id,perm) => update_permissions({user_id,permission:perm.code})} />
		<label>
			<input type="checkbox" bind:checked={visible_to_guests} onchange={toggle_guest} />
			{t('visible_to_guests')}
		</label>
	</fieldset>
	<fieldset>
		<legend>{t('options')}</legend>
		<table>
			<thead>
				<tr>
					<th>{t('name')}</th>
					<th>{t('description')}</th>
				</tr>
			</thead>
			<tbody>
				{#each Object.entries(poll.options) as [option_id, option]}
				<tr>
					<td>
						<LineEditor editable={true} value={option.name} onSet={name => patch_option(option,'name',name)} title={t('clear to remove')} />
					</td>
					<td>
						<MarkdownEditor bind:value={option.description}  onSet={desc => patch_option(option,'description',desc)} />
					</td>
				</tr>
				{/each}
				<tr>
					<td class="new_option">
						{t('add element',{element:t('options')})}
						<input type="text" bind:value={new_option.name} />
					</td>
					<td>
						<MarkdownEditor simple={true} bind:value={new_option.description} />
						<button onclick={save_new_option}>{t('save')}</button>
					</td>
				</tr>
			</tbody>
		</table>
	</fieldset>
	<fieldset>
		<legend>{t('weights')}</legend>
		<table>
			<thead>
				<tr>
					<th>{t('weight')}</th>
					<th>{t('description')}</th>
				</tr>
			</thead>
			<tbody>
			{#each Object.entries(poll.weights) as [weight,descr] (weight)}
				<tr>
					<td>
						<input type="number" value={weight} />
					</td>
					<td>
						<LineEditor editable={true} value={descr} onSet={desc => patch_weight({[weight]: desc})} />
					</td>
				</tr>
			{/each}
				<tr>
					<td>
						<input type="number" bind:value={new_weight.weight} />
					</td>
					<td>
						<input type="text" bind:value={new_weight.description} />
						<button onclick={save_new_weight}>{t('save')}</button>
					</td>
				</tr>
			</tbody>
		</table>
	</fieldset>
	{/if}
</fieldset>
