<script lang="ts">
	import api from '$lib/api';
	import { ATTR_IN } from '@upnd/upend/constants';
	import { i18n } from '../i18n';
	import { Query, UpListing } from '@upnd/upend';
	import EntitySetEditor from './EntitySetEditor.svelte';
	import { Any } from '@upnd/upend/query';

	export let entities: string[];

	let groups: string[] = [];
	let groupListing: UpListing | undefined = undefined;
	async function updateGroups() {
		const currentEntities = entities.concat();
		const allGroups = await api.query(
			Query.matches(
				currentEntities.map((e) => `@${e}`),
				ATTR_IN,
				Any
			)
		);

		const commonGroups = new Set(
			allGroups.values
				.filter((v) => v.t == 'Address')
				.map((v) => v.c as string)
				.filter((groupAddr) => {
					return Object.values(allGroups.objects).every((obj) => {
						return obj.attr[ATTR_IN]?.some((v) => v.value.c === groupAddr);
					});
				})
		);

		if (entities.toString() == currentEntities.toString()) {
			groups = Array.from(commonGroups);
			groupListing = allGroups;
		}
	}
	$: entities && updateGroups();

	async function addGroup(address: string) {
		await api.putEntry(
			entities.map((entity) => ({
				entity,
				attribute: ATTR_IN,
				value: {
					t: 'Address',
					c: address
				}
			}))
		);
		await updateGroups();
	}

	async function removeGroup(address: string) {
		await Promise.all(
			entities.map((entity) => {
				const group = groupListing?.objects[entity].attr[ATTR_IN]?.find(
					(v) => v.value.c === address
				);
				if (group) {
					return api.deleteEntry(group.address);
				}
			})
		);
		await updateGroups();
	}
</script>

<EntitySetEditor
	entities={groups}
	header={$i18n.t('Common groups') || ''}
	on:add={(ev) => addGroup(ev.detail)}
	on:remove={(ev) => removeGroup(ev.detail)}
/>
