<script lang="ts">
	import { Card, Badge, Spinner, Button, Modal, FormField } from '$lib/components';
	import {
		getCustomDomains,
		createCustomDomain,
		activateCustomDomain,
		deleteCustomDomain,
		getTenantSubdomains,
	} from '$lib/api/admin';
	import { toast } from '$lib/stores/toast.svelte';
	import { data } from '$lib/stores/data.svelte';
	import type { CustomDomain } from '$lib/types';
	import { Plus, Trash2, CheckCircle, Globe, Copy } from 'lucide-svelte';
	import { navbarExtra } from '$lib/stores/navbar-extra.svelte';
	import { onDestroy, onMount } from 'svelte';

	let domains = $state<CustomDomain[]>([]);
	let loading = $state(true);

	// Add modal
	let showAdd = $state(false);
	let addTenantId = $state('');
	let addDomain = $state('');
	let addTarget = $state('dashboard');
	let adding = $state(false);
	let tenantApps = $state<string[]>([]);
	let loadingApps = $state(false);

	// Delete confirmation
	let deleteTarget = $state<CustomDomain | null>(null);
	let deleting = $state(false);

	// Force activate
	let activatingId = $state<string | null>(null);

	// DNS hint expanded
	let expandedDnsId = $state<string | null>(null);

	async function loadDomains() {
		loading = true;
		try {
			domains = await getCustomDomains();
		} catch (e: any) {
			toast.error(e.message || 'Failed to load domains');
		} finally {
			loading = false;
		}
	}

	onMount(loadDomains);

	$effect(() => {
		navbarExtra.set(addBtn);
		return () => navbarExtra.set(null);
	});
	onDestroy(() => navbarExtra.set(null));

	async function handleAdd() {
		if (!addDomain.trim()) return;
		adding = true;
		try {
			const created = await createCustomDomain({
				tenant_id: addTenantId || data.tenants[0]?.id || '',
				domain: addDomain.trim().toLowerCase(),
				target: addTarget.trim() || 'dashboard',
			});
			domains = [created, ...domains];
			toast.success('Domain added — pending DNS verification');
			showAdd = false;
			resetAddForm();
		} catch (e: any) {
			toast.error(e.message || 'Failed to add domain');
		} finally {
			adding = false;
		}
	}

	async function handleActivate(d: CustomDomain) {
		activatingId = d.id;
		try {
			const updated = await activateCustomDomain(d.id);
			domains = domains.map(x => x.id === d.id ? updated : x);
			toast.success(`${d.domain} activated`);
		} catch (e: any) {
			toast.error(e.message || 'Failed to activate');
		} finally {
			activatingId = null;
		}
	}

	async function handleDelete() {
		if (!deleteTarget) return;
		deleting = true;
		try {
			await deleteCustomDomain(deleteTarget.id);
			domains = domains.filter(d => d.id !== deleteTarget!.id);
			toast.success('Domain removed');
			deleteTarget = null;
		} catch (e: any) {
			toast.error(e.message || 'Failed to remove domain');
		} finally {
			deleting = false;
		}
	}

	async function loadTenantApps(tenantId: string) {
		if (!tenantId) { tenantApps = []; return; }
		loadingApps = true;
		try {
			tenantApps = await getTenantSubdomains(tenantId);
		} catch {
			tenantApps = [];
		} finally {
			loadingApps = false;
		}
	}

	function resetAddForm() {
		addTenantId = data.tenants[0]?.id || '';
		addDomain = '';
		addTarget = 'dashboard';
		tenantApps = [];
	}

	function openAdd() {
		resetAddForm();
		showAdd = true;
		if (addTenantId) loadTenantApps(addTenantId);
	}

	function statusColor(status: CustomDomain['status']): 'green' | 'amber' | 'rose' {
		if (status === 'active') return 'green';
		if (status === 'pending') return 'amber';
		return 'rose';
	}

	function formatDate(d: string | null): string {
		if (!d) return '—';
		return new Date(d).toLocaleDateString();
	}

	async function copyToClipboard(text: string) {
		try {
			await navigator.clipboard.writeText(text);
			toast.success('Copied');
		} catch {
			toast.error('Copy failed');
		}
	}

	const pendingDomains = $derived(domains.filter(d => d.status === 'pending'));
</script>

{#snippet addBtn()}
	<Button variant="primary" size="sm" onclick={openAdd}>
		<Plus size={14} />
		Add Domain
	</Button>
{/snippet}

<div class="page">
	{#if loading}
		<div class="center"><Spinner /></div>
	{:else if domains.length === 0}
		<Card>
			<div class="empty">
				<Globe size={32} strokeWidth={1.5} />
				<p>No custom domains registered yet.</p>
				<Button variant="primary" onclick={openAdd}>
					<Plus size={14} />
					Add Your First Domain
				</Button>
			</div>
		</Card>
	{:else}
		<Card>
			<div class="table-scroll">
			<table>
				<thead>
					<tr>
						<th>Domain</th>
						<th>Tenant</th>
						<th>Target</th>
						<th>Status</th>
						<th>Verified</th>
						<th></th>
					</tr>
				</thead>
				<tbody>
					{#each domains as d (d.id)}
						<tr>
							<td class="domain-cell">
								<span class="domain-name">{d.domain}</span>
								{#if d.status === 'pending'}
									<button
										class="dns-toggle"
										onclick={() => expandedDnsId = expandedDnsId === d.id ? null : d.id}
										title="Show DNS verification instructions"
									>DNS?</button>
								{/if}
							</td>
							<td class="dim mono">{d.tenant_id}</td>
							<td class="dim">{d.target}</td>
							<td><Badge color={statusColor(d.status)}>{d.status}</Badge></td>
							<td class="dim small">{formatDate(d.verified_at)}</td>
							<td class="actions">
								{#if d.status === 'pending'}
									<Button
										size="sm"
										variant="secondary"
										loading={activatingId === d.id}
										onclick={() => handleActivate(d)}
									>Force Activate</Button>
								{/if}
								<Button
									size="sm"
									variant="danger"
									onclick={() => deleteTarget = d}
								><Trash2 size={13} /></Button>
							</td>
						</tr>
						{#if expandedDnsId === d.id}
							<tr class="dns-row">
								<td colspan="6">
									<div class="dns-hint">
										<p class="dns-label">Add this TXT record to prove ownership:</p>
										<div class="dns-record">
											<div class="dns-field">
												<span class="dns-key">Name</span>
												<code class="dns-val">_nanoclaw-verify.{d.domain}</code>
												<button class="copy-btn" onclick={() => copyToClipboard(`_nanoclaw-verify.${d.domain}`)}>
													<Copy size={12} />
												</button>
											</div>
											<div class="dns-field">
												<span class="dns-key">Value</span>
												<code class="dns-val">{d.verification_token}</code>
												<button class="copy-btn" onclick={() => copyToClipboard(d.verification_token)}>
													<Copy size={12} />
												</button>
											</div>
										</div>
										<p class="dns-note">The platform checks every 5 minutes. Or use Force Activate to bypass.</p>
									</div>
								</td>
							</tr>
						{/if}
					{/each}
				</tbody>
			</table>
			</div>
			<div class="mobile-domain-list">
				{#each domains as d (d.id)}
					<div class="mobile-domain-card">
						<div class="mobile-domain-top">
							<span class="domain-name">{d.domain}</span>
							<Badge color={statusColor(d.status)}>{d.status}</Badge>
						</div>
						<div class="mobile-domain-meta">
							<span class="mobile-meta-key">Tenant</span>
							<span class="mono dim">{d.tenant_id}</span>
						</div>
						<div class="mobile-domain-meta">
							<span class="mobile-meta-key">Target</span>
							<span class="dim">{d.target}</span>
						</div>
						{#if d.status === 'pending'}
							<div class="mobile-dns-section">
								<button
									class="dns-toggle"
									onclick={() => expandedDnsId = expandedDnsId === d.id ? null : d.id}
								>{expandedDnsId === d.id ? 'Hide DNS' : 'Show DNS'}</button>
								{#if expandedDnsId === d.id}
									<div class="dns-hint" style="margin-top: 8px;">
										<p class="dns-label">TXT record for verification:</p>
										<div class="dns-record">
											<div class="dns-field">
												<span class="dns-key">Name</span>
												<code class="dns-val">_nanoclaw-verify.{d.domain}</code>
												<button class="copy-btn" onclick={() => copyToClipboard('_nanoclaw-verify.' + d.domain)}>
													<Copy size={12} />
												</button>
											</div>
											<div class="dns-field">
												<span class="dns-key">Value</span>
												<code class="dns-val">{d.verification_token}</code>
												<button class="copy-btn" onclick={() => copyToClipboard(d.verification_token)}>
													<Copy size={12} />
												</button>
											</div>
										</div>
									</div>
								{/if}
							</div>
						{/if}
						<div class="mobile-domain-actions">
							{#if d.status === 'pending'}
								<Button size="sm" variant="secondary" loading={activatingId === d.id} onclick={() => handleActivate(d)}>Force Activate</Button>
							{/if}
							<Button size="sm" variant="danger" onclick={() => deleteTarget = d}><Trash2 size={13} /></Button>
						</div>
					</div>
				{/each}
			</div>
		</Card>
	{/if}
</div>

<!-- Add Domain Modal -->
<Modal open={showAdd} title="Add Custom Domain" onclose={() => showAdd = false}>
	<div class="form-stack">
		<FormField label="Tenant">
			<select
				value={addTenantId}
				onchange={(e) => {
					addTenantId = e.currentTarget.value;
					addTarget = 'dashboard';
					loadTenantApps(e.currentTarget.value);
				}}
			>
				{#each data.tenants as t}
					<option value={t.id}>{t.id}{t.name ? ` — ${t.name}` : ''}</option>
				{/each}
			</select>
		</FormField>
		<FormField label="Domain" hint="e.g. myapp.com or app.example.com">
			<input
				type="text"
				bind:value={addDomain}
				placeholder="myapp.com"
				autocomplete="off"
			/>
		</FormField>
		<FormField label="Target" hint="Point to the tenant dashboard or one of their deployed apps">
			{#if loadingApps}
				<select disabled><option>Loading apps…</option></select>
			{:else}
				<select bind:value={addTarget}>
					<option value="dashboard">dashboard (tenant panel)</option>
					{#each tenantApps as app}
						<option value={app}>{app}</option>
					{/each}
				</select>
			{/if}
		</FormField>
	</div>
	{#snippet footer()}
		<Button variant="secondary" onclick={() => showAdd = false}>Cancel</Button>
		<Button
			variant="primary"
			loading={adding}
			onclick={handleAdd}
			disabled={!addDomain.trim()}
		>Add Domain</Button>
	{/snippet}
</Modal>

<!-- Delete Confirmation -->
<Modal open={deleteTarget !== null} title="Remove Domain" onclose={() => deleteTarget = null}>
	<p class="confirm-text">Remove <strong>{deleteTarget?.domain}</strong>? This will also remove it from the Caddy routing config.</p>
	{#snippet footer()}
		<Button variant="secondary" onclick={() => deleteTarget = null}>Cancel</Button>
		<Button variant="danger" loading={deleting} onclick={handleDelete}>Remove</Button>
	{/snippet}
</Modal>

<style>
	.page {
		display: flex;
		flex-direction: column;
		gap: 20px;
	}
	.center {
		display: flex;
		justify-content: center;
		padding: 60px 0;
	}
	.empty {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 16px;
		padding: 48px 24px;
		color: var(--text-muted);
	}
	.empty p {
		font-size: var(--font-size-sm);
		color: var(--text-dim);
	}
	table {
		width: 100%;
		border-collapse: collapse;
	}
	th {
		text-align: left;
		padding: 10px 14px;
		font-size: var(--font-size-xs);
		text-transform: uppercase;
		letter-spacing: 0.05em;
		color: var(--text-muted);
		border-bottom: 1px solid var(--border-subtle);
		font-weight: 500;
	}
	td {
		padding: 10px 14px;
		border-bottom: 1px solid var(--border-subtle);
		font-size: var(--font-size-sm);
		color: var(--text);
	}
	tbody tr:last-child td {
		border-bottom: none;
	}
	tbody tr:not(.dns-row):hover td {
		background: var(--surface-1);
	}
	.domain-cell {
		display: flex;
		align-items: center;
		gap: 8px;
	}
	.domain-name {
		font-family: var(--font-mono);
		font-weight: 600;
		color: var(--text-bright);
	}
	.dns-toggle {
		font-size: 10px;
		font-family: var(--font-mono);
		padding: 1px 6px;
		border: 1px solid var(--amber);
		border-radius: 4px;
		background: color-mix(in srgb, var(--amber) 10%, transparent);
		color: var(--amber);
		cursor: pointer;
		transition: all var(--duration) var(--ease);
	}
	.dns-toggle:hover {
		background: color-mix(in srgb, var(--amber) 20%, transparent);
	}
	.dim { color: var(--text-dim); }
	.mono { font-family: var(--font-mono); font-size: var(--font-size-xs); }
	.small { font-size: var(--font-size-xs); }
	.actions {
		display: flex;
		gap: 6px;
		justify-content: flex-end;
		white-space: nowrap;
	}
	.dns-row td {
		padding: 0 14px 12px;
		border-bottom: 1px solid var(--border-subtle);
	}
	.dns-hint {
		background: color-mix(in srgb, var(--amber) 6%, transparent);
		border: 1px solid color-mix(in srgb, var(--amber) 25%, transparent);
		border-radius: var(--radius);
		padding: 12px 14px;
		display: flex;
		flex-direction: column;
		gap: 8px;
	}
	.dns-label {
		font-size: var(--font-size-xs);
		font-weight: 600;
		color: var(--amber);
	}
	.dns-record {
		display: flex;
		flex-direction: column;
		gap: 6px;
	}
	.dns-field {
		display: flex;
		align-items: center;
		gap: 10px;
	}
	.dns-key {
		font-size: var(--font-size-xs);
		color: var(--text-muted);
		width: 44px;
		flex-shrink: 0;
	}
	.dns-val {
		font-family: var(--font-mono);
		font-size: var(--font-size-xs);
		color: var(--text-bright);
		background: var(--surface-0);
		padding: 2px 8px;
		border-radius: var(--radius-sm);
		border: 1px solid var(--border-subtle);
		flex: 1;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
	.copy-btn {
		background: none;
		border: none;
		color: var(--text-muted);
		cursor: pointer;
		padding: 4px;
		border-radius: var(--radius-sm);
		display: flex;
		align-items: center;
		transition: color var(--duration) var(--ease);
		flex-shrink: 0;
	}
	.copy-btn:hover {
		color: var(--text);
	}
	.dns-note {
		font-size: var(--font-size-xs);
		color: var(--text-muted);
	}
	.form-stack {
		display: flex;
		flex-direction: column;
		gap: 14px;
	}
	.confirm-text {
		color: var(--text);
		line-height: 1.5;
	}

	.table-scroll { overflow-x: auto; }

	.mobile-domain-list { display: none; flex-direction: column; }
	.mobile-domain-card {
		padding: 14px 16px;
		border-bottom: 1px solid var(--border-subtle);
		display: flex;
		flex-direction: column;
		gap: 6px;
	}
	.mobile-domain-card:last-child { border-bottom: none; }
	.mobile-domain-top {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 8px;
		flex-wrap: wrap;
	}
	.mobile-domain-meta {
		display: flex;
		align-items: center;
		gap: 8px;
		font-size: var(--font-size-xs);
	}
	.mobile-meta-key {
		color: var(--text-muted);
		min-width: 48px;
	}
	.mobile-dns-section { display: flex; flex-direction: column; gap: 4px; }
	.mobile-domain-actions { display: flex; gap: 6px; margin-top: 4px; }

	@media (max-width: 768px) {
		table { display: none; }
		.mobile-domain-list { display: flex; }
	}
</style>
