<script lang="ts">
	import { api, getBlockedBy, type BlockedByDetail , errMsg} from '$lib/api';
	import BlockedByModal from '$lib/components/BlockedByModal.svelte';
	import { t, getLocale } from '$lib/i18n';
	import { matrixBotsCache } from '$lib/stores/caches.svelte';
	import PageHeader from '$lib/components/PageHeader.svelte';
	import Card from '$lib/components/Card.svelte';
	import IconPicker from '$lib/components/IconPicker.svelte';
	import MdiIcon from '$lib/components/MdiIcon.svelte';
	import EmptyState from '$lib/components/EmptyState.svelte';
	import ConfirmModal from '$lib/components/ConfirmModal.svelte';
	import IconButton from '$lib/components/IconButton.svelte';
	import { snackSuccess, snackError } from '$lib/stores/snackbar.svelte';
	import Button from '$lib/components/Button.svelte';
	import ErrorBanner from '$lib/components/ErrorBanner.svelte';
	import MetaStrip, { type MetaTile } from '$lib/components/MetaStrip.svelte';
	import type { MatrixBot } from '$lib/types';

	let { onreload }: { onreload: () => Promise<void> } = $props();

	let matrixBots = $derived(matrixBotsCache.items);
	let showMatrixForm = $state(false);
	let editingMatrix = $state<number | null>(null);
	let matrixSubmitting = $state(false);
	let matrixTesting = $state<Record<number, boolean>>({});
	let confirmDeleteMatrix = $state<{ id: number; onconfirm: () => Promise<void> } | null>(null);
	let error = $state('');

	const defaultMatrixForm = () => ({
		name: '', icon: '', homeserver_url: '', access_token: '', display_name: '',
	});
	let matrixForm = $state(defaultMatrixForm());
	let nameManuallyEdited = $state(false);

	const DEFAULT_BOT_NAME = 'Matrix Bot';
	$effect(() => {
		if (showMatrixForm && !nameManuallyEdited && !editingMatrix) {
			matrixForm.name = DEFAULT_BOT_NAME;
		}
	});

	function matrixBotTiles(bot: MatrixBot): MetaTile[] {
		const tiles: MetaTile[] = [];
		let host = bot.homeserver_url;
		try { host = new URL(bot.homeserver_url).host; } catch { /* keep raw */ }
		tiles.push({
			icon: 'mdiServerNetwork',
			label: host,
			hint: bot.homeserver_url,
			href: bot.homeserver_url,
			tone: 'lavender',
			mono: true,
		});
		if (bot.display_name) {
			tiles.push({
				icon: 'mdiAccountCircleOutline',
				label: bot.display_name,
				tone: 'sky',
			});
		}
		return tiles;
	}

	function openNewMatrix() { matrixForm = defaultMatrixForm(); nameManuallyEdited = false; editingMatrix = null; showMatrixForm = true; }
	function editMatrixBot(bot: MatrixBot) {
		matrixForm = {
			name: bot.name, icon: bot.icon || '',
			homeserver_url: bot.homeserver_url, access_token: '',
			display_name: bot.display_name || '',
		};
		nameManuallyEdited = true;
		editingMatrix = bot.id; showMatrixForm = true;
	}

	async function saveMatrixBot(e: SubmitEvent) {
		e.preventDefault(); error = ''; matrixSubmitting = true;
		try {
			const body = { ...matrixForm };
			if (editingMatrix && !body.access_token) delete (body as any).access_token;
			if (editingMatrix) {
				await api(`/matrix-bots/${editingMatrix}`, { method: 'PUT', body: JSON.stringify(body) });
				snackSuccess(t('snack.matrixBotUpdated'));
			} else {
				await api('/matrix-bots', { method: 'POST', body: JSON.stringify(body) });
				snackSuccess(t('snack.matrixBotCreated'));
			}
			matrixForm = defaultMatrixForm(); nameManuallyEdited = false; showMatrixForm = false; editingMatrix = null; await onreload();
		} catch (err: unknown) { const __m = errMsg(err); error = __m; snackError(__m); }
		finally { matrixSubmitting = false; }
	}

	let blockedBy = $state<BlockedByDetail | null>(null);
	function removeMatrix(id: number) {
		confirmDeleteMatrix = {
			id,
			onconfirm: async () => {
				try { await api(`/matrix-bots/${id}`, { method: 'DELETE' }); await onreload(); snackSuccess(t('snack.matrixBotDeleted')); }
				catch (err: unknown) {
					const bb = getBlockedBy(err);
					if (bb) { blockedBy = bb; return; }
					const m = errMsg(err); error = m; snackError(m);
				}
				finally { confirmDeleteMatrix = null; }
			}
		};
	}

	async function testMatrixBot(botId: number) {
		matrixTesting = { ...matrixTesting, [botId]: true };
		try {
			const res = await api(`/matrix-bots/${botId}/test?locale=${getLocale()}`, { method: 'POST' });
			if (res.success) snackSuccess(t('snack.matrixBotTestOk'));
			else snackError(res.error || t('matrixBot.operationFailed'));
		} catch (err: unknown) { snackError(errMsg(err)); }
		matrixTesting = { ...matrixTesting, [botId]: false };
	}
</script>

<PageHeader
	title={t('matrixBot.title')}
	emphasis={t('matrixBot.titleEmphasis')}
	description={t('matrixBot.description')}
	crumb={t('crumbs.operatorsBots')}
	count={matrixBots.length}
	countLabel={t('matrixBot.countLabel')}
>
	<Button size="sm" onclick={() => { showMatrixForm ? (showMatrixForm = false, editingMatrix = null) : openNewMatrix(); }}>
		{showMatrixForm ? t('common.cancel') : t('matrixBot.addBot')}
	</Button>
</PageHeader>

{#if showMatrixForm}
	<Card class="mb-6">
		<ErrorBanner message={error} />
		<form onsubmit={saveMatrixBot} class="space-y-3">
			<div>
				<label for="mbot-name" class="block text-sm font-medium mb-1">{t('matrixBot.name')}</label>
				<div class="flex gap-2">
					<IconPicker value={matrixForm.icon} onselect={(v: string) => matrixForm.icon = v} />
					<input id="mbot-name" bind:value={matrixForm.name} oninput={() => nameManuallyEdited = true} required placeholder={t('matrixBot.namePlaceholder')}
						class="flex-1 px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
				</div>
			</div>
			<div>
				<label for="mbot-hs" class="block text-sm font-medium mb-1">{t('matrixBot.homeserverUrl')}</label>
				<input id="mbot-hs" bind:value={matrixForm.homeserver_url} required placeholder="https://matrix.org"
					class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
			</div>
			<div>
				<label for="mbot-token" class="block text-sm font-medium mb-1">{t('matrixBot.accessToken')}</label>
				<input id="mbot-token" bind:value={matrixForm.access_token} type="password"
					required={!editingMatrix}
					placeholder={editingMatrix ? t('matrixBot.tokenUnchanged') : t('matrixBot.tokenPlaceholder')}
					class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)] font-mono" />
			</div>
			<div>
				<label for="mbot-display" class="block text-sm font-medium mb-1">{t('matrixBot.displayName')}</label>
				<input id="mbot-display" bind:value={matrixForm.display_name} placeholder="Notify Bridge"
					class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
			</div>
			<button type="submit" disabled={matrixSubmitting}
				class="px-4 py-2 bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded-md text-sm font-medium hover:opacity-90 disabled:opacity-50">
				{matrixSubmitting ? t('common.loading') : (editingMatrix ? t('common.save') : t('matrixBot.addBot'))}
			</button>
		</form>
	</Card>
{/if}

{#if matrixBots.length === 0 && !showMatrixForm}
	<Card>
		<EmptyState icon="mdiMatrix" message={t('matrixBot.noBots')} />
	</Card>
{:else}
	<div class="list-stack stagger-children">
		{#each matrixBots as bot}
			<Card hover entityId={bot.id}>
				<div class="list-row">
					<div class="list-row__identity">
						<div class="flex items-center gap-2 min-w-0">
							<span style="color: var(--color-primary);" class="shrink-0"><MdiIcon name={bot.icon || 'mdiMatrix'} size={20} /></span>
							<p class="font-medium truncate">{bot.name}</p>
						</div>
						<div class="flex items-center gap-2 mt-1 flex-wrap list-row__secondary">
							<span class="text-xs text-[var(--color-muted-foreground)] font-mono">{bot.homeserver_url}</span>
							{#if bot.display_name}
								<span class="text-xs px-1.5 py-0.5 rounded bg-[var(--color-muted)] text-[var(--color-muted-foreground)]">{bot.display_name}</span>
							{/if}
						</div>
					</div>
					<MetaStrip tiles={matrixBotTiles(bot)} />
					<div class="list-row__actions">
						<IconButton icon="mdiConnection" title={t('matrixBot.testConnection')} onclick={() => testMatrixBot(bot.id)} disabled={matrixTesting[bot.id]} />
						<IconButton icon="mdiPencil" title={t('common.edit')} onclick={() => editMatrixBot(bot)} />
						<IconButton icon="mdiDelete" title={t('common.delete')} onclick={() => removeMatrix(bot.id)} variant="danger" />
					</div>
				</div>
			</Card>
		{/each}
	</div>
{/if}

<ConfirmModal open={confirmDeleteMatrix !== null} message={t('matrixBot.confirmDelete')}
	onconfirm={() => confirmDeleteMatrix?.onconfirm()} oncancel={() => confirmDeleteMatrix = null} />

<BlockedByModal open={!!blockedBy} detail={blockedBy} onclose={() => blockedBy = null} />
