<script lang="ts">
	import { onMount } from 'svelte';
	import { slide } from 'svelte/transition';
	import { page } from '$app/state';
	import { api } from '$lib/api';
	import { t, getLocale } from '$lib/i18n';
	import { telegramBotsCache, emailBotsCache, matrixBotsCache } from '$lib/stores/caches.svelte';
	import PageHeader from '$lib/components/PageHeader.svelte';
	import Card from '$lib/components/Card.svelte';
	import Loading from '$lib/components/Loading.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, snackInfo } from '$lib/stores/snackbar.svelte';
	import { highlightFromUrl } from '$lib/highlight';
	import type { TelegramBot, TelegramChat, EmailBot, MatrixBot } from '$lib/types';

	type BotTab = 'telegram' | 'email' | 'matrix';
	let activeTab = $derived((page.url.searchParams.get('tab') as BotTab | null) || 'telegram');

	let bots = $derived(telegramBotsCache.items);
	let emailBots = $derived(emailBotsCache.items);
	let matrixBots = $derived(matrixBotsCache.items);
	let loaded = $state(false);
	let showForm = $state(false);
	let editing = $state<number | null>(null);
	let form = $state({ name: '', icon: '', token: '' });
	let error = $state('');
	let submitting = $state(false);
	let confirmDelete = $state<any>(null);

	// Global settings (loaded for webhook mode checks)
	let settings = $state<any>({});

	// Per-bot expandable sections
	let chats = $state<Record<number, TelegramChat[]>>({});
	let chatsLoading = $state<Record<number, boolean>>({});
	let expandedSection = $state<Record<number, string>>({});

	// Webhook status per bot
	let webhookStatus = $state<Record<number, any>>({});

	onMount(load);
	async function load() {
		try {
			[, settings] = await Promise.all([
				telegramBotsCache.fetch(true),
				api('/settings'),
				emailBotsCache.fetch(true),
				matrixBotsCache.fetch(true),
			]);
		} catch (err: any) { error = err.message || t('common.loadError'); snackError(error); }
		finally { loaded = true; highlightFromUrl(); }
	}

	function openNew() { form = { name: '', icon: '', token: '' }; editing = null; showForm = true; }
	function editBot(bot: any) { form = { name: bot.name, icon: bot.icon || '', token: '' }; editing = bot.id; showForm = true; }

	async function saveBot(e: SubmitEvent) {
		e.preventDefault(); error = ''; submitting = true;
		try {
			if (editing) {
				await api(`/telegram-bots/${editing}`, { method: 'PUT', body: JSON.stringify({ name: form.name, icon: form.icon }) });
				snackSuccess(t('snack.botUpdated'));
			} else {
				await api('/telegram-bots', { method: 'POST', body: JSON.stringify(form) });
				snackSuccess(t('snack.botRegistered'));
			}
			form = { name: '', icon: '', token: '' }; showForm = false; editing = null; await load();
		} catch (err: any) { error = err.message; snackError(err.message); }
		finally { submitting = false; }
	}

	function remove(id: number) {
		confirmDelete = {
			id,
			onconfirm: async () => {
				try { await api(`/telegram-bots/${id}`, { method: 'DELETE' }); await load(); snackSuccess(t('snack.botDeleted')); }
				catch (err: any) { error = err.message; snackError(err.message); }
				finally { confirmDelete = null; }
			}
		};
	}

	function toggleSection(botId: number, section: string) {
		if (expandedSection[botId] === section) {
			expandedSection = { ...expandedSection, [botId]: '' };
			return;
		}
		expandedSection = { ...expandedSection, [botId]: section };
		if (section === 'chats') loadChats(botId);
	}

	async function loadChats(botId: number) {
		chatsLoading = { ...chatsLoading, [botId]: true };
		try { chats = { ...chats, [botId]: await api(`/telegram-bots/${botId}/chats`) }; } catch { chats = { ...chats, [botId]: [] }; }
		chatsLoading = { ...chatsLoading, [botId]: false };
	}

	async function discoverChats(botId: number) {
		chatsLoading = { ...chatsLoading, [botId]: true };
		try {
			chats = { ...chats, [botId]: await api(`/telegram-bots/${botId}/chats/discover`, { method: 'POST' }) };
			snackSuccess(t('telegramBot.chatsDiscovered'));
		} catch (err: any) { snackError(err.message); }
		chatsLoading = { ...chatsLoading, [botId]: false };
	}

	async function deleteChat(botId: number, chatDbId: number) {
		try {
			await api(`/telegram-bots/${botId}/chats/${chatDbId}`, { method: 'DELETE' });
			chats[botId] = (chats[botId] || []).filter((c: any) => c.id !== chatDbId);
			snackSuccess(t('telegramBot.chatDeleted'));
		} catch (err: any) { snackError(err.message); }
	}

	let chatTesting = $state<Record<string, boolean>>({});

	let modeChanging = $state<Record<number, boolean>>({});

	// Listener status: command trackers using this bot
	let botListenerStatus = $state<Record<number, any[]>>({});
	let botListenerLoading = $state<Record<number, boolean>>({});

	async function loadListenerStatus(botId: number) {
		botListenerLoading = { ...botListenerLoading, [botId]: true };
		try {
			// Load all command trackers and filter for ones that have this bot as a listener
			const trackers = await api('/command-trackers');
			const matched: any[] = [];
			for (const trk of trackers) {
				try {
					const listeners = await api(`/command-trackers/${trk.id}/listeners`);
					const hasBot = listeners.some((l: any) => l.listener_type === 'telegram_bot' && l.listener_id === botId);
					if (hasBot) matched.push(trk);
				} catch { /* ignore */ }
			}
			botListenerStatus = { ...botListenerStatus, [botId]: matched };
		} catch { botListenerStatus = { ...botListenerStatus, [botId]: [] }; }
		botListenerLoading = { ...botListenerLoading, [botId]: false };
	}

	async function syncCommands(botId: number) {
		modeChanging = { ...modeChanging, [botId]: true };
		try {
			const res = await api(`/telegram-bots/${botId}/sync-commands`, { method: 'POST' });
			if (res.success) snackSuccess(t('telegramBot.commandsSynced'));
			else snackError(res.error || 'Failed');
		} catch (err: any) { snackError(err.message); }
		modeChanging = { ...modeChanging, [botId]: false };
	}

	async function switchMode(botId: number, mode: string) {
		modeChanging = { ...modeChanging, [botId]: true };
		try {
			const res = await api(`/telegram-bots/${botId}`, { method: 'PUT', body: JSON.stringify({ update_mode: mode }) });
			await load();
			if (mode === 'webhook') {
				// Load webhook status after switching
				await loadWebhookStatus(botId);
			}
			snackSuccess(t('snack.botUpdated'));
		} catch (err: any) { snackError(err.message); }
		modeChanging = { ...modeChanging, [botId]: false };
	}

	async function loadWebhookStatus(botId: number) {
		try {
			webhookStatus = { ...webhookStatus, [botId]: await api(`/telegram-bots/${botId}/webhook/status`) };
		} catch { webhookStatus = { ...webhookStatus, [botId]: null }; }
	}

	async function registerWebhook(botId: number) {
		modeChanging = { ...modeChanging, [botId]: true };
		try {
			const res = await api(`/telegram-bots/${botId}/webhook/register`, { method: 'POST' });
			if (res.success) {
				snackSuccess(res.verified ? t('telegramBot.webhookVerified') : t('telegramBot.webhookRegistered'));
				await loadWebhookStatus(botId);
			} else {
				snackError(res.error || 'Failed to register webhook');
			}
		} catch (err: any) { snackError(err.message); }
		modeChanging = { ...modeChanging, [botId]: false };
	}

	async function unregisterWebhook(botId: number) {
		modeChanging = { ...modeChanging, [botId]: true };
		try {
			const res = await api(`/telegram-bots/${botId}/webhook/unregister`, { method: 'POST' });
			if (res.success) { snackSuccess(t('telegramBot.webhookUnregistered')); await loadWebhookStatus(botId); }
			else snackError(res.error || 'Failed');
		} catch (err: any) { snackError(err.message); }
		modeChanging = { ...modeChanging, [botId]: false };
	}

	function copyChatId(e: Event, chatId: string) {
		e.stopPropagation();
		navigator.clipboard.writeText(chatId);
		snackInfo(`${t('snack.copied')}: ${chatId}`);
	}

	async function testChat(e: Event, botId: number, chatId: string) {
		e.stopPropagation();
		const key = `${botId}_${chatId}`;
		if (chatTesting[key]) return;
		chatTesting = { ...chatTesting, [key]: true };
		try {
			const res = await api(`/telegram-bots/${botId}/chats/${chatId}/test?locale=${getLocale()}`, { method: 'POST' });
			if (res.success) snackSuccess(t('snack.targetTestSent'));
			else snackError(res.error || 'Failed');
		} catch (err: any) { snackError(err.message); }
		chatTesting = { ...chatTesting, [key]: false };
	}

	function chatTypeLabel(type: string): string {
		const map: Record<string, string> = {
			private: t('telegramBot.private'),
			group: t('telegramBot.group'),
			supergroup: t('telegramBot.supergroup'),
			channel: t('telegramBot.channel'),
		};
		return map[type] || type;
	}

	// --- Email Bot state ---
	let showEmailForm = $state(false);
	let editingEmail = $state<number | null>(null);
	let emailSubmitting = $state(false);
	let emailTesting = $state<Record<number, boolean>>({});
	let confirmDeleteEmail = $state<any>(null);
	const defaultEmailForm = () => ({
		name: '', icon: '', email: '', smtp_host: '', smtp_port: 587,
		smtp_username: '', smtp_password: '', smtp_use_tls: true,
	});
	let emailForm = $state(defaultEmailForm());

	function openNewEmail() { emailForm = defaultEmailForm(); editingEmail = null; showEmailForm = true; }
	function editEmailBot(bot: EmailBot) {
		emailForm = {
			name: bot.name, icon: bot.icon || '', email: bot.email,
			smtp_host: bot.smtp_host, smtp_port: bot.smtp_port,
			smtp_username: bot.smtp_username, smtp_password: '',
			smtp_use_tls: bot.smtp_use_tls,
		};
		editingEmail = bot.id; showEmailForm = true;
	}

	async function saveEmailBot(e: SubmitEvent) {
		e.preventDefault(); error = ''; emailSubmitting = true;
		try {
			const body = { ...emailForm };
			if (editingEmail) {
				// Don't send empty password on update (means "keep current")
				if (!body.smtp_password) delete (body as any).smtp_password;
				await api(`/email-bots/${editingEmail}`, { method: 'PUT', body: JSON.stringify(body) });
				snackSuccess(t('snack.emailBotUpdated'));
			} else {
				await api('/email-bots', { method: 'POST', body: JSON.stringify(body) });
				snackSuccess(t('snack.emailBotCreated'));
			}
			emailForm = defaultEmailForm(); showEmailForm = false; editingEmail = null; await load();
		} catch (err: any) { error = err.message; snackError(err.message); }
		finally { emailSubmitting = false; }
	}

	function removeEmail(id: number) {
		confirmDeleteEmail = {
			id,
			onconfirm: async () => {
				try { await api(`/email-bots/${id}`, { method: 'DELETE' }); await load(); snackSuccess(t('snack.emailBotDeleted')); }
				catch (err: any) { error = err.message; snackError(err.message); }
				finally { confirmDeleteEmail = null; }
			}
		};
	}

	async function testEmailBot(botId: number) {
		emailTesting = { ...emailTesting, [botId]: true };
		try {
			const res = await api(`/email-bots/${botId}/test`, { method: 'POST' });
			if (res.success) snackSuccess(t('snack.emailBotTestSent'));
			else snackError(res.error || 'Failed');
		} catch (err: any) { snackError(err.message); }
		emailTesting = { ...emailTesting, [botId]: false };
	}

	// --- Matrix Bot state ---
	let showMatrixForm = $state(false);
	let editingMatrix = $state<number | null>(null);
	let matrixSubmitting = $state(false);
	let matrixTesting = $state<Record<number, boolean>>({});
	let confirmDeleteMatrix = $state<any>(null);
	const defaultMatrixForm = () => ({
		name: '', icon: '', homeserver_url: '', access_token: '', display_name: '',
	});
	let matrixForm = $state(defaultMatrixForm());

	function openNewMatrix() { matrixForm = defaultMatrixForm(); 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 || '',
		};
		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(); showMatrixForm = false; editingMatrix = null; await load();
		} catch (err: any) { error = err.message; snackError(err.message); }
		finally { matrixSubmitting = false; }
	}

	function removeMatrix(id: number) {
		confirmDeleteMatrix = {
			id,
			onconfirm: async () => {
				try { await api(`/matrix-bots/${id}`, { method: 'DELETE' }); await load(); snackSuccess(t('snack.matrixBotDeleted')); }
				catch (err: any) { error = err.message; snackError(err.message); }
				finally { confirmDeleteMatrix = null; }
			}
		};
	}

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

{#if !loaded}<Loading />{:else}

{#if activeTab === 'telegram'}
<PageHeader title={t('telegramBot.title')} description={t('telegramBot.description')}>
	<button onclick={() => { showForm ? (showForm = false, editing = null) : openNew(); }}
		class="px-3 py-1.5 bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded-md text-sm font-medium hover:opacity-90">
		{showForm ? t('common.cancel') : t('telegramBot.addBot')}
	</button>
</PageHeader>

{#if showForm}
	<Card class="mb-6">
		{#if error}<div class="bg-[var(--color-error-bg)] text-[var(--color-error-fg)] text-sm rounded-md p-3 mb-4">{error}</div>{/if}
		<form onsubmit={saveBot} class="space-y-3">
			<div>
				<label for="bot-name" class="block text-sm font-medium mb-1">{t('telegramBot.name')}</label>
				<div class="flex gap-2">
					<IconPicker value={form.icon} onselect={(v: string) => form.icon = v} />
					<input id="bot-name" bind:value={form.name} required placeholder={t('telegramBot.namePlaceholder')}
						class="flex-1 px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
				</div>
			</div>
			{#if !editing}
			<div>
				<label for="bot-token" class="block text-sm font-medium mb-1">{t('telegramBot.token')}</label>
				<input id="bot-token" bind:value={form.token} required placeholder={t('telegramBot.tokenPlaceholder')}
					class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)] font-mono" />
			</div>
			{/if}
			<button type="submit" disabled={submitting}
				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">
				{submitting ? t('common.loading') : (editing ? t('common.save') : t('telegramBot.addBot'))}
			</button>
		</form>
	</Card>
{/if}

{#if bots.length === 0 && !showForm}
	<Card>
		<EmptyState icon="mdiRobot" message={t('telegramBot.noBots')} />
	</Card>
{:else}
	<div class="space-y-3 stagger-children">
		{#each bots as bot}
			<Card hover entityId={bot.id}>
				<div class="flex items-center justify-between">
					<div>
						<div class="flex items-center gap-2">
							<span style="color: var(--color-primary);"><MdiIcon name={bot.icon || 'mdiRobot'} size={20} /></span>
							<p class="font-medium">{bot.name}</p>
							{#if bot.bot_username}
								<span class="text-xs text-[var(--color-muted-foreground)]">@{bot.bot_username}</span>
							{/if}
							<!-- Mode badge -->
							<span class="text-xs px-1.5 py-0.5 rounded font-mono {bot.update_mode === 'webhook'
								? 'bg-blue-500/10 text-blue-500'
								: 'bg-emerald-500/10 text-emerald-500'}">
								{bot.update_mode === 'webhook' ? t('telegramBot.webhook') : t('telegramBot.polling')}
							</span>
						</div>
						<p class="text-xs text-[var(--color-muted-foreground)] font-mono">{bot.token_preview}</p>
					</div>
					<div class="flex items-center gap-1">
						<IconButton icon="mdiPencil" title={t('common.edit')} onclick={() => editBot(bot)} />
						<button onclick={() => toggleSection(bot.id, 'chats')}
							class="text-xs text-[var(--color-muted-foreground)] hover:underline px-2 py-1">
							{t('telegramBot.chats')} {expandedSection[bot.id] === 'chats' ? '▲' : '▼'}
						</button>
						<button onclick={() => { toggleSection(bot.id, 'listeners'); if (expandedSection[bot.id] === 'listeners') loadListenerStatus(bot.id); }}
							class="text-xs text-[var(--color-muted-foreground)] hover:underline px-2 py-1">
							{t('commandTracker.listeners')} {expandedSection[bot.id] === 'listeners' ? '▲' : '▼'}
						</button>
						<button onclick={() => syncCommands(bot.id)} disabled={modeChanging[bot.id]}
							class="text-xs text-[var(--color-primary)] hover:underline px-2 py-1 flex items-center gap-1">
							<MdiIcon name="mdiSync" size={14} />
							{t('telegramBot.syncCommands')}
						</button>
						<IconButton icon="mdiDelete" title={t('common.delete')} onclick={() => remove(bot.id)} variant="danger" />
					</div>
				</div>

				<!-- Chats section -->
				{#if expandedSection[bot.id] === 'chats'}
					<div class="mt-3 border-t border-[var(--color-border)] pt-3" in:slide>
						{#if chatsLoading[bot.id]}
							<p class="text-xs text-[var(--color-muted-foreground)]">{t('common.loading')}</p>
						{:else if (chats[bot.id] || []).length === 0}
							<p class="text-xs text-[var(--color-muted-foreground)]">{t('telegramBot.noChats')}</p>
						{:else}
							<div class="space-y-1">
								{#each chats[bot.id] as chat}
									<div class="flex items-center justify-between text-sm px-2 py-1 rounded hover:bg-[var(--color-muted)] cursor-pointer"
										onclick={(e: MouseEvent) => copyChatId(e, chat.chat_id)}
										title={t('telegramBot.clickToCopy')}
										role="button" tabindex="0">
										<div class="flex items-center gap-2">
											<span class="font-medium">{chat.title || chat.username || 'Unknown'}</span>
											<span class="text-xs px-1.5 py-0.5 rounded bg-[var(--color-muted)] text-[var(--color-muted-foreground)]">{chatTypeLabel(chat.type)}</span>
											<span class="text-xs text-[var(--color-muted-foreground)] font-mono">{chat.chat_id}</span>
										</div>
										<div class="flex items-center gap-1">
										<IconButton icon="mdiSend" title="Test message" size={14}
											onclick={(e: MouseEvent) => testChat(e, bot.id, chat.chat_id)}
											disabled={chatTesting[`${bot.id}_${chat.chat_id}`]} />
										<IconButton icon="mdiDelete" title={t('common.delete')} size={14}
											onclick={(e: MouseEvent) => { e.stopPropagation(); deleteChat(bot.id, chat.id); }} variant="danger" />
									</div>
									</div>
								{/each}
							</div>
						{/if}
						<button onclick={() => discoverChats(bot.id)}
							class="text-xs text-[var(--color-primary)] hover:underline mt-2 flex items-center gap-1">
							<MdiIcon name="mdiSync" size={14} />
							{t('telegramBot.discoverChats')}
						</button>
					</div>
				{/if}
				<!-- Listener Status section -->
				{#if expandedSection[bot.id] === 'listeners'}
					<div class="mt-3 border-t border-[var(--color-border)] pt-3 space-y-3" in:slide>
						{#if botListenerLoading[bot.id]}
							<p class="text-xs text-[var(--color-muted-foreground)]">{t('common.loading')}</p>
						{:else if (botListenerStatus[bot.id] || []).length === 0}
							<p class="text-xs text-[var(--color-muted-foreground)]">{t('commandTracker.noListeners')}</p>
						{:else}
							<div class="space-y-1">
								{#each botListenerStatus[bot.id] as trk}
									<div class="flex items-center justify-between text-sm px-2 py-1 rounded hover:bg-[var(--color-muted)]">
										<div class="flex items-center gap-2">
											<MdiIcon name={trk.icon || 'mdiConsoleLine'} size={14} />
											<span class="font-medium">{trk.name}</span>
											<span class="text-xs px-1.5 py-0.5 rounded font-mono {trk.enabled
												? 'bg-emerald-500/10 text-emerald-500'
												: 'bg-red-500/10 text-red-500'}">
												{trk.enabled ? t('commandTracker.enabled') : t('commandTracker.disabled')}
											</span>
										</div>
										<a href="/command-trackers" class="text-xs text-[var(--color-primary)] hover:underline">
											{t('common.edit')}
										</a>
									</div>
								{/each}
							</div>
						{/if}

						<!-- Update mode -->
						<div class="border-t border-[var(--color-border)] pt-3">
							<p class="text-xs font-medium mb-2">{t('telegramBot.updateMode')}</p>
							<div class="flex items-center gap-3 flex-wrap">
								<div class="flex items-center rounded-md border border-[var(--color-border)] overflow-hidden">
									<button onclick={() => switchMode(bot.id, 'polling')}
										disabled={modeChanging[bot.id] || bot.update_mode === 'polling'}
										class="px-3 py-1 text-xs transition-colors {bot.update_mode === 'polling'
											? 'bg-[var(--color-primary)] text-[var(--color-primary-foreground)]'
											: 'hover:bg-[var(--color-muted)]'} disabled:opacity-70">
										<MdiIcon name="mdiSync" size={14} />
										{t('telegramBot.polling')}
									</button>
									<button onclick={() => switchMode(bot.id, 'webhook')}
										disabled={modeChanging[bot.id] || bot.update_mode === 'webhook'}
										class="px-3 py-1 text-xs transition-colors {bot.update_mode === 'webhook'
											? 'bg-[var(--color-primary)] text-[var(--color-primary-foreground)]'
											: 'hover:bg-[var(--color-muted)]'} disabled:opacity-70">
										<MdiIcon name="mdiWebhook" size={14} />
										{t('telegramBot.webhook')}
									</button>
								</div>

								{#if bot.update_mode === 'polling'}
									<span class="text-xs text-emerald-500 flex items-center gap-1">
										<MdiIcon name="mdiCheckCircle" size={14} />
										{t('telegramBot.pollingActive')}
									</span>
								{/if}

								{#if bot.update_mode === 'webhook'}
									<button onclick={() => registerWebhook(bot.id)} disabled={modeChanging[bot.id]}
										class="px-2 py-1 text-xs border border-[var(--color-border)] rounded-md hover:bg-[var(--color-muted)] disabled:opacity-50">
										{t('telegramBot.registerWebhook')}
									</button>
									<button onclick={() => unregisterWebhook(bot.id)} disabled={modeChanging[bot.id]}
										class="px-2 py-1 text-xs text-[var(--color-muted-foreground)] hover:underline disabled:opacity-50">
										{t('telegramBot.unregisterWebhook')}
									</button>
									{#if webhookStatus[bot.id]}
										{@const ws = webhookStatus[bot.id]}
										<span class="text-xs font-mono {ws.url ? 'text-blue-500' : 'text-[var(--color-muted-foreground)]'}">
											{ws.url ? t('telegramBot.webhookActive') : t('telegramBot.webhookNotSet')}
											{#if ws.pending_update_count > 0}
												({ws.pending_update_count} {t('telegramBot.pendingUpdates')})
											{/if}
										</span>
										{#if ws.last_error_message}
											<span class="text-xs text-red-500">{t('telegramBot.webhookError')}: {ws.last_error_message}</span>
										{/if}
									{:else}
										<button onclick={() => loadWebhookStatus(bot.id)}
											class="text-xs text-[var(--color-primary)] hover:underline">
											{t('telegramBot.webhookStatus')}
										</button>
									{/if}
								{/if}

								{#if !settings.external_url && bot.update_mode === 'webhook'}
									<span class="text-xs text-amber-500 flex items-center gap-1">
										<MdiIcon name="mdiAlert" size={14} />
										{t('telegramBot.noExternalDomain')}
									</span>
								{/if}
							</div>
						</div>
					</div>
				{/if}
			</Card>
		{/each}
	</div>
{/if}

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

<!-- ======= Email Bots Section ======= -->
{#if activeTab === 'email'}
<PageHeader title={t('emailBot.title')} description={t('emailBot.description')}>
	<button onclick={() => { showEmailForm ? (showEmailForm = false, editingEmail = null) : openNewEmail(); }}
		class="px-3 py-1.5 bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded-md text-sm font-medium hover:opacity-90">
		{showEmailForm ? t('common.cancel') : t('emailBot.addBot')}
	</button>
</PageHeader>

{#if showEmailForm}
	<Card class="mb-6">
		{#if error}<div class="bg-[var(--color-error-bg)] text-[var(--color-error-fg)] text-sm rounded-md p-3 mb-4">{error}</div>{/if}
		<form onsubmit={saveEmailBot} class="space-y-3">
			<div>
				<label for="ebot-name" class="block text-sm font-medium mb-1">{t('emailBot.name')}</label>
				<div class="flex gap-2">
					<IconPicker value={emailForm.icon} onselect={(v: string) => emailForm.icon = v} />
					<input id="ebot-name" bind:value={emailForm.name} required placeholder={t('emailBot.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="ebot-email" class="block text-sm font-medium mb-1">{t('emailBot.email')}</label>
				<input id="ebot-email" bind:value={emailForm.email} required type="email" placeholder="notify@example.com"
					class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
			</div>
			<div class="grid grid-cols-2 gap-3">
				<div>
					<label for="ebot-host" class="block text-sm font-medium mb-1">{t('emailBot.smtpHost')}</label>
					<input id="ebot-host" bind:value={emailForm.smtp_host} required placeholder="smtp.gmail.com"
						class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
				</div>
				<div>
					<label for="ebot-port" class="block text-sm font-medium mb-1">{t('emailBot.smtpPort')}</label>
					<input id="ebot-port" bind:value={emailForm.smtp_port} type="number" min="1" max="65535"
						class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
				</div>
			</div>
			<div class="grid grid-cols-2 gap-3">
				<div>
					<label for="ebot-user" class="block text-sm font-medium mb-1">{t('emailBot.smtpUsername')}</label>
					<input id="ebot-user" bind:value={emailForm.smtp_username} placeholder={t('emailBot.smtpUsernamePlaceholder')}
						class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
				</div>
				<div>
					<label for="ebot-pass" class="block text-sm font-medium mb-1">{t('emailBot.smtpPassword')}</label>
					<input id="ebot-pass" bind:value={emailForm.smtp_password} type="password" placeholder={editingEmail ? t('emailBot.passwordUnchanged') : ''}
						class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
				</div>
			</div>
			<label class="flex items-center gap-2 text-sm cursor-pointer">
				<input type="checkbox" bind:checked={emailForm.smtp_use_tls} />
				{t('emailBot.useTls')}
			</label>
			<button type="submit" disabled={emailSubmitting}
				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">
				{emailSubmitting ? t('common.loading') : (editingEmail ? t('common.save') : t('emailBot.addBot'))}
			</button>
		</form>
	</Card>
{/if}

{#if emailBots.length === 0 && !showEmailForm}
	<Card>
		<EmptyState icon="mdiEmailOutline" message={t('emailBot.noBots')} />
	</Card>
{:else}
	<div class="space-y-3 stagger-children">
		{#each emailBots as bot}
			<Card hover entityId={bot.id}>
				<div class="flex items-center justify-between">
					<div>
						<div class="flex items-center gap-2">
							<span style="color: var(--color-primary);"><MdiIcon name={bot.icon || 'mdiEmailOutline'} size={20} /></span>
							<p class="font-medium">{bot.name}</p>
						</div>
						<div class="flex items-center gap-2 mt-1 flex-wrap">
							<span class="text-xs text-[var(--color-muted-foreground)] font-mono">{bot.email}</span>
							<span class="text-xs px-1.5 py-0.5 rounded bg-[var(--color-muted)] text-[var(--color-muted-foreground)]">{bot.smtp_host}:{bot.smtp_port}</span>
							{#if bot.smtp_use_tls}
								<span class="text-xs px-1.5 py-0.5 rounded bg-emerald-500/10 text-emerald-500">TLS</span>
							{/if}
						</div>
					</div>
					<div class="flex items-center gap-1">
						<IconButton icon="mdiEmailSend" title={t('emailBot.testConnection')} onclick={() => testEmailBot(bot.id)} disabled={emailTesting[bot.id]} />
						<IconButton icon="mdiPencil" title={t('common.edit')} onclick={() => editEmailBot(bot)} />
						<IconButton icon="mdiDelete" title={t('common.delete')} onclick={() => removeEmail(bot.id)} variant="danger" />
					</div>
				</div>
			</Card>
		{/each}
	</div>
{/if}

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

<!-- ======= Matrix Bots Section ======= -->
{#if activeTab === 'matrix'}
<PageHeader title={t('matrixBot.title')} description={t('matrixBot.description')}>
	<button onclick={() => { showMatrixForm ? (showMatrixForm = false, editingMatrix = null) : openNewMatrix(); }}
		class="px-3 py-1.5 bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded-md text-sm font-medium hover:opacity-90">
		{showMatrixForm ? t('common.cancel') : t('matrixBot.addBot')}
	</button>
</PageHeader>

{#if showMatrixForm}
	<Card class="mb-6">
		{#if error}<div class="bg-[var(--color-error-bg)] text-[var(--color-error-fg)] text-sm rounded-md p-3 mb-4">{error}</div>{/if}
		<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} 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="space-y-3 stagger-children">
		{#each matrixBots as bot}
			<Card hover entityId={bot.id}>
				<div class="flex items-center justify-between">
					<div>
						<div class="flex items-center gap-2">
							<span style="color: var(--color-primary);"><MdiIcon name={bot.icon || 'mdiMatrix'} size={20} /></span>
							<p class="font-medium">{bot.name}</p>
						</div>
						<div class="flex items-center gap-2 mt-1 flex-wrap">
							<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>
					<div class="flex items-center gap-1">
						<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} />
{/if}

{/if}
