<script lang="ts">
	import { apiMutate } from '$lib/api/client.js';
	import type { BgpCommunity, DomainEntry, DomainEntryCreate } from '$lib/api/types.js';
	import {
		communityLabel,
		communityOptionLabel,
		fromNullableSelect,
		NONE_OPTION,
		nullableSelectValue
	} from '$lib/components/modules/module-helpers.js';
	import { Button } from '@evobgp/ui/components/button/index.js';
	import { Input } from '@evobgp/ui/components/input/index.js';
	import { Label } from '@evobgp/ui/components/label/index.js';
	import {
		Dialog,
		DialogContent,
		DialogHeader,
		DialogTitle,
		DialogFooter
	} from '@evobgp/ui/components/dialog/index.js';
	import {
		Select,
		SelectContent,
		SelectItem,
		SelectTrigger
	} from '@evobgp/ui/components/select/index.js';
	import { notify, notifyApiError } from '$lib/ui/app/toast.js';

	type Props = {
		open: boolean;
		moduleId: string;
		edit: DomainEntry | null;
		communities: BgpCommunity[];
		onSaved: () => void | Promise<void>;
		onClose: () => void;
	};

	let { open = $bindable(), moduleId, edit, communities, onSaved, onClose }: Props = $props();

	let saving = $state(false);
	let form = $state<DomainEntryCreate>({ fqdn: '', community_id: null });
	let initKey = $state('');

	function resetForm() {
		form = edit
			? { fqdn: edit.fqdn, community_id: edit.community_id }
			: { fqdn: '', community_id: null };
	}

	$effect(() => {
		if (!open) {
			initKey = '';
			return;
		}
		const nextKey = edit?.id ?? 'new';
		if (nextKey !== initKey) {
			initKey = nextKey;
			resetForm();
		}
	});

	async function save() {
		saving = true;
		try {
			if (edit) {
				await apiMutate(`/v1/modules/${moduleId}/domain-entries/${edit.id}`, 'PATCH', form);
				notify.success('Домен обновлён');
			} else {
				await apiMutate(`/v1/modules/${moduleId}/domain-entries`, 'POST', form);
				notify.success('Домен добавлен');
			}
			open = false;
			await onSaved();
		} catch (e) {
			notifyApiError(e);
		} finally {
			saving = false;
		}
	}

	function handleOpenChange(next: boolean) {
		open = next;
		if (!next) onClose();
	}
</script>

<Dialog bind:open onOpenChange={handleOpenChange}>
	<DialogContent class="sm:max-w-sm">
		<DialogHeader>
			<DialogTitle>{edit ? 'Редактировать домен' : 'Новый домен'}</DialogTitle>
		</DialogHeader>
		<div class="space-y-4 py-2">
			<div class="space-y-1.5">
				<Label for="dom-fqdn">FQDN</Label>
				<Input id="dom-fqdn" placeholder="example.com" bind:value={form.fqdn} />
			</div>
			<div class="space-y-1.5">
				<Label for="dom-comm">Community</Label>
				<Select
					type="single"
					value={nullableSelectValue(form.community_id)}
					onValueChange={(v) => {
						form.community_id = fromNullableSelect(v);
					}}
				>
					<SelectTrigger id="dom-comm" class="w-full">
						{form.community_id ? communityLabel(form.community_id, communities) : 'Не выбрано'}
					</SelectTrigger>
					<SelectContent>
						<SelectItem value={NONE_OPTION}>Не выбрано</SelectItem>
						{#each communities as c (c.id)}
							<SelectItem value={c.id}>{communityOptionLabel(c)}</SelectItem>
						{/each}
					</SelectContent>
				</Select>
			</div>
		</div>
		<DialogFooter>
			<Button variant="outline" onclick={() => handleOpenChange(false)}>Отмена</Button>
			<Button onclick={save} disabled={saving}>
				{saving ? 'Сохранение…' : edit ? 'Сохранить' : 'Добавить'}
			</Button>
		</DialogFooter>
	</DialogContent>
</Dialog>
