<script lang="ts">
	import { run } from 'svelte/legacy';

	import { Button } from '$lib/components/common'
	import Select from '$lib/components/select/Select.svelte'
	import { safeSelectItems } from '$lib/components/select/utils.svelte'
	import type { Relations } from '$lib/gen'
	import { PostgresTriggerService } from '$lib/gen/services.gen'
	import { workspaceStore } from '$lib/stores'
	import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
	import { sendUserToast } from '$lib/toast'
	import { emptyString } from '$lib/utils'
	import { RefreshCw } from 'lucide-svelte'

	interface Props {
		items?: string[];
		can_write?: boolean;
		publication_name?: string;
		postgres_resource_path?: string;
		relations?: Relations[] | undefined;
		transaction_to_track?: string[];
		disabled?: boolean;
	}

	let {
		items = $bindable([]),
		can_write = true,
		publication_name = $bindable(''),
		postgres_resource_path = '',
		relations = $bindable(undefined),
		transaction_to_track = $bindable([]),
		disabled = false
	}: Props = $props();
	const triggerWs = getTriggerWorkspace()
	const wsId = $derived(triggerWs?.() ?? $workspaceStore)

	let loadingPublication: boolean = $state(false)
	let deletingPublication: boolean = $state(false)
	let updatingPublication: boolean = $state(false)
	async function listDatabasePublication() {
		try {
			loadingPublication = true
			const publications = await PostgresTriggerService.listPostgresPublication({
				path: postgres_resource_path,
				workspace: wsId!
			})

			items = publications
		} catch (error) {
			sendUserToast(error.body, true)
		} finally {
			loadingPublication = false
		}
	}

	async function updatePublication() {
		try {
			updatingPublication = true
			const message = await PostgresTriggerService.updatePostgresPublication({
				path: postgres_resource_path,
				workspace: wsId!,
				publication: publication_name,
				requestBody: {
					table_to_track: relations,
					transaction_to_track: transaction_to_track
				}
			})
			sendUserToast(message)
		} catch (error) {
			sendUserToast(error.body, true)
		} finally {
			updatingPublication = false
		}
	}

	async function deletePublication() {
		try {
			deletingPublication = true
			const message = await PostgresTriggerService.deletePostgresPublication({
				path: postgres_resource_path,
				workspace: wsId!,
				publication: publication_name
			})
			items = items.filter((item) => item != publication_name)
			relations = undefined
			transaction_to_track = ['Insert', 'Update', 'Delete']
			publication_name = ''
			sendUserToast(message)
		} catch (error) {
			sendUserToast(error.body, true)
		} finally {
			deletingPublication = false
		}
	}

	async function getAllRelations() {
		try {
			const publication_data = await PostgresTriggerService.getPostgresPublication({
				path: postgres_resource_path,
				workspace: wsId!,
				publication: publication_name
			})
			transaction_to_track = [...publication_data.transaction_to_track]
			relations =
				publication_data.table_to_track && publication_data.table_to_track.length > 0
					? publication_data.table_to_track
					: undefined
		} catch (error) {
			sendUserToast(error.body, true)
		}
	}

	listDatabasePublication()
	run(() => {
		publication_name && getAllRelations()
	});
</script>

<div class="flex gap-1">
	<Select
		loading={loadingPublication}
		disabled={!can_write || disabled}
		class="grow shrink"
		bind:value={publication_name}
		items={safeSelectItems(items)}
		placeholder="Choose a publication"
		clearable
		disablePortal
	/>
	<Button
		disabled={!can_write || disabled}
		variant="default"
		wrapperClasses="self-stretch"
		on:click={listDatabasePublication}
		startIcon={{ icon: RefreshCw }}
		iconOnly
	/>
	<Button
		loading={updatingPublication}
		size="xs"
		variant="default"
		disabled={emptyString(publication_name) || !can_write || disabled}
		on:click={updatePublication}>Update</Button
	>
	<Button
		loading={deletingPublication}
		size="xs"
		variant="default"
		disabled={emptyString(publication_name) || !can_write || disabled}
		on:click={deletePublication}>Delete</Button
	>
</div>
