<script lang="ts">
	import { invalidateAll } from '$app/navigation';
	import { t } from 'svelte-i18n';
	import type { PageData } from './$types.js';

	let { data }: { data: PageData } = $props();

	let showForm = $state(false);
	let creating = $state(false);
	let err = $state<string | null>(null);

	let email = $state('');
	let role = $state<'user' | 'admin'>('user');
	let expiresInDays = $state(7);

	let createdUrl = $state<string | null>(null);

	async function submit(evt: SubmitEvent) {
		evt.preventDefault();
		err = null;
		creating = true;
		try {
			const res = await fetch('/api/admin/invites', {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({
					email: email || undefined,
					role,
					expiresInDays
				})
			});
			const json = await res.json();
			if (!json.success) {
				err = json.error ?? 'Failed to create invite';
				return;
			}
			createdUrl = json.data.url;
			email = '';
			role = 'user';
			expiresInDays = 7;
			showForm = false;
			await invalidateAll();
		} catch {
			err = 'Failed to create invite';
		} finally {
			creating = false;
		}
	}

	async function revoke(id: string) {
		err = null;
		try {
			const res = await fetch(`/api/admin/invites/${id}`, { method: 'DELETE' });
			const json = await res.json();
			if (!json.success) {
				err = json.error ?? 'Failed to revoke invite';
				return;
			}
			await invalidateAll();
		} catch {
			err = 'Failed to revoke invite';
		}
	}

	async function copyUrl(url: string) {
		try {
			await navigator.clipboard.writeText(url);
		} catch {
			/* ignore */
		}
	}

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

	function inviteStatus(inv: { usedAt: Date | string | null; expiresAt: Date | string }): string {
		if (inv.usedAt) return 'Used';
		if (new Date(inv.expiresAt) < new Date()) return 'Expired';
		return 'Active';
	}
</script>

<svelte:head>
	<title>{$t('admin.invites') ?? 'Invites'} — {$t('admin.panel') ?? 'Admin'}</title>
</svelte:head>

<div class="mx-auto max-w-4xl space-y-6 px-4 py-8">
	<div class="flex items-center justify-between">
		<div>
			<h1 class="text-2xl font-bold text-foreground">Invites</h1>
			<p class="mt-1 text-sm text-muted-foreground">
				Generate invite links so people can register even when public registration is disabled.
			</p>
		</div>
		{#if !showForm}
			<button
				type="button"
				onclick={() => (showForm = true)}
				class="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90"
			>
				Generate invite
			</button>
		{/if}
	</div>

	{#if err}
		<div class="rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive">
			{err}
		</div>
	{/if}

	{#if createdUrl}
		<div class="rounded-lg border border-yellow-500/50 bg-yellow-500/10 p-4">
			<h3 class="mb-1 text-sm font-semibold text-foreground">Invite created</h3>
			<p class="mb-3 text-xs text-muted-foreground">
				Share this link with the recipient. It will only be shown once.
			</p>
			<div class="flex items-center gap-2">
				<code
					class="flex-1 truncate rounded-md border border-input bg-background px-3 py-2 text-xs font-mono text-foreground"
				>
					{createdUrl}
				</code>
				<button
					type="button"
					onclick={() => createdUrl && copyUrl(createdUrl)}
					class="rounded-md bg-primary px-3 py-2 text-xs font-medium text-primary-foreground hover:bg-primary/90"
				>
					Copy
				</button>
			</div>
			<button
				type="button"
				onclick={() => (createdUrl = null)}
				class="mt-3 text-xs text-muted-foreground hover:text-foreground"
			>
				I have copied the link
			</button>
		</div>
	{/if}

	{#if showForm}
		<form
			onsubmit={submit}
			class="space-y-4 rounded-xl border border-border bg-card p-5"
		>
			<div>
				<label for="inv-email" class="mb-1 block text-sm font-medium text-card-foreground">
					Email <span class="text-xs font-normal text-muted-foreground">(optional — locks invite to one email)</span>
				</label>
				<input
					id="inv-email"
					type="email"
					bind:value={email}
					placeholder="jane@example.com"
					class="w-full rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground"
				/>
			</div>
			<div class="grid grid-cols-2 gap-4">
				<div>
					<label for="inv-role" class="mb-1 block text-sm font-medium text-card-foreground">Role</label>
					<select
						id="inv-role"
						bind:value={role}
						class="w-full rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground"
					>
						<option value="user">User</option>
						<option value="admin">Admin</option>
					</select>
				</div>
				<div>
					<label for="inv-expiry" class="mb-1 block text-sm font-medium text-card-foreground">
						Expires in (days)
					</label>
					<input
						id="inv-expiry"
						type="number"
						min="1"
						max="90"
						bind:value={expiresInDays}
						class="w-full rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground"
					/>
				</div>
			</div>
			<div class="flex justify-end gap-2">
				<button
					type="button"
					onclick={() => (showForm = false)}
					class="rounded-md border border-border px-3 py-2 text-sm text-foreground hover:bg-muted"
				>
					Cancel
				</button>
				<button
					type="submit"
					disabled={creating}
					class="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50"
				>
					{creating ? 'Creating…' : 'Create invite'}
				</button>
			</div>
		</form>
	{/if}

	<div class="overflow-hidden rounded-xl border border-border bg-card">
		<table class="w-full text-sm">
			<thead class="bg-muted/40 text-xs uppercase tracking-wide text-muted-foreground">
				<tr>
					<th class="px-4 py-3 text-left font-medium">Email</th>
					<th class="px-4 py-3 text-left font-medium">Role</th>
					<th class="px-4 py-3 text-left font-medium">Status</th>
					<th class="px-4 py-3 text-left font-medium">Expires</th>
					<th class="px-4 py-3 text-left font-medium">Created</th>
					<th class="px-4 py-3 text-right">
						<span class="sr-only">Actions</span>
					</th>
				</tr>
			</thead>
			<tbody>
				{#each data.invites as inv (inv.id)}
					{@const status = inviteStatus(inv)}
					<tr class="border-t border-border">
						<td class="px-4 py-3 text-card-foreground">{inv.email ?? '—'}</td>
						<td class="px-4 py-3 text-card-foreground">{inv.role}</td>
						<td class="px-4 py-3">
							<span
								class="rounded-full px-2 py-0.5 text-xs {status === 'Active'
									? 'bg-emerald-500/15 text-emerald-500'
									: status === 'Used'
										? 'bg-muted text-muted-foreground'
										: 'bg-destructive/15 text-destructive'}"
							>
								{status}
							</span>
						</td>
						<td class="px-4 py-3 text-muted-foreground">{fmt(inv.expiresAt)}</td>
						<td class="px-4 py-3 text-muted-foreground">{fmt(inv.createdAt)}</td>
						<td class="px-4 py-3 text-right">
							<button
								type="button"
								onclick={() => revoke(inv.id)}
								class="text-xs text-destructive hover:underline"
							>
								Revoke
							</button>
						</td>
					</tr>
				{/each}
				{#if data.invites.length === 0}
					<tr>
						<td colspan="6" class="px-4 py-6 text-center text-sm text-muted-foreground">
							No invites yet.
						</td>
					</tr>
				{/if}
			</tbody>
		</table>
	</div>
</div>
