<script lang="ts">
    import { onMount } from 'svelte';
    import {
        listAdminUsers,
        deleteAdminUser,
        setUserAdmin,
        createAdminUser,
        type AdminUsersPage
    } from '$lib/api/admin';
    import { ApiError } from '$lib/api/client';
    import { session } from '$lib/session.svelte';

    let page: AdminUsersPage | null = $state(null);
    let search = $state('');
    let error: string | null = $state(null);
    let busyId: string | null = $state(null);

    // Create-user form (collapsed by default).
    let showCreate = $state(false);
    let newUsername = $state('');
    let newPassword = $state('');
    let newIsAdmin = $state(false);
    let createError: string | null = $state(null);
    let creating = $state(false);

    async function load() {
        error = null;
        try {
            page = await listAdminUsers({
                search: search.trim() || undefined,
                limit: 100
            });
        } catch (e) {
            error = e instanceof ApiError ? e.message : 'load failed';
        }
    }

    onMount(load);

    async function onDelete(id: string) {
        if (!confirm('Delete this user? This cannot be undone.')) return;
        busyId = id;
        try {
            await deleteAdminUser(id);
            await load();
        } catch (e) {
            error = e instanceof ApiError ? e.message : 'delete failed';
        } finally {
            busyId = null;
        }
    }

    async function onToggleAdmin(id: string, next: boolean) {
        busyId = id;
        try {
            await setUserAdmin(id, next);
            await load();
        } catch (e) {
            error = e instanceof ApiError ? e.message : 'update failed';
        } finally {
            busyId = null;
        }
    }

    async function onCreate(e: SubmitEvent) {
        e.preventDefault();
        createError = null;
        creating = true;
        try {
            await createAdminUser({
                username: newUsername.trim(),
                password: newPassword,
                is_admin: newIsAdmin
            });
            // Reset form + reload list so the new row is visible.
            newUsername = '';
            newPassword = '';
            newIsAdmin = false;
            showCreate = false;
            await load();
        } catch (e) {
            createError = e instanceof ApiError ? e.message : 'create failed';
        } finally {
            creating = false;
        }
    }
</script>

<h1>Users</h1>

<div class="toolbar">
    <button
        type="button"
        onclick={() => (showCreate = !showCreate)}
        data-testid="admin-users-toggle-create"
    >
        {showCreate ? 'Cancel' : 'Create user'}
    </button>
</div>

{#if showCreate}
    <form class="create-form" onsubmit={onCreate} data-testid="admin-users-create-form">
        <label class="field">
            <span>Username</span>
            <input
                type="text"
                bind:value={newUsername}
                minlength="3"
                maxlength="32"
                required
                autocomplete="off"
                data-testid="admin-users-create-username"
            />
        </label>
        <label class="field">
            <span>Password</span>
            <input
                type="password"
                bind:value={newPassword}
                minlength="8"
                required
                autocomplete="new-password"
                data-testid="admin-users-create-password"
            />
        </label>
        <label class="field-inline">
            <input
                type="checkbox"
                bind:checked={newIsAdmin}
                data-testid="admin-users-create-is-admin"
            />
            <span>Make admin</span>
        </label>
        <button
            type="submit"
            class="primary"
            disabled={creating}
            data-testid="admin-users-create-submit"
        >
            {creating ? 'Creating…' : 'Create'}
        </button>
        {#if createError}
            <p class="error" role="alert" data-testid="admin-users-create-error">
                {createError}
            </p>
        {/if}
    </form>
{/if}

<form
    onsubmit={(e) => {
        e.preventDefault();
        load();
    }}
>
    <input
        type="search"
        placeholder="search by username"
        bind:value={search}
        data-testid="admin-users-search"
    />
    <button type="submit">Search</button>
</form>

{#if error}
    <p class="error" role="alert">{error}</p>
{/if}

{#if page}
    <p class="total">{page.page.total ?? page.items.length} users</p>
    <table>
        <thead>
            <tr>
                <th>Username</th>
                <th>Admin</th>
                <th>Created</th>
                <th class="actions">Actions</th>
            </tr>
        </thead>
        <tbody>
            {#each page.items as u (u.id)}
                {@const isSelf = session.user?.id === u.id}
                <tr>
                    <td>{u.username}{#if isSelf}<span class="self"> (you)</span>{/if}</td>
                    <td>
                        <input
                            type="checkbox"
                            checked={u.is_admin}
                            disabled={busyId === u.id || isSelf}
                            onchange={(e) => onToggleAdmin(u.id, e.currentTarget.checked)}
                            aria-label="admin"
                        />
                    </td>
                    <td>{new Date(u.created_at).toLocaleDateString()}</td>
                    <td class="actions">
                        <button
                            type="button"
                            class="danger"
                            disabled={busyId === u.id || isSelf}
                            onclick={() => onDelete(u.id)}
                        >
                            Delete
                        </button>
                    </td>
                </tr>
            {/each}
        </tbody>
    </table>
{:else}
    <p>Loading…</p>
{/if}

<style>
    h1 {
        margin: 0 0 var(--space-4) 0;
    }
    form {
        display: flex;
        gap: var(--space-2);
        margin-bottom: var(--space-3);
    }
    input[type='search'] {
        flex: 1;
        padding: var(--space-2) var(--space-3);
        border: 1px solid var(--border);
        border-radius: var(--radius-md);
        background: var(--surface);
        color: var(--text);
    }
    button {
        padding: var(--space-2) var(--space-3);
        border-radius: var(--radius-md);
        border: 1px solid var(--border);
        background: var(--surface);
        color: var(--text);
        cursor: pointer;
    }
    button.danger {
        color: var(--danger, #dc2626);
        border-color: var(--danger, #dc2626);
    }
    button:disabled {
        opacity: 0.5;
        cursor: not-allowed;
    }
    .total {
        color: var(--text-muted);
        font-size: var(--font-sm);
        margin: 0 0 var(--space-2) 0;
    }
    table {
        width: 100%;
        border-collapse: collapse;
    }
    th,
    td {
        padding: var(--space-2);
        text-align: left;
        border-bottom: 1px solid var(--border);
    }
    .actions {
        text-align: right;
    }
    .self {
        color: var(--text-muted);
        font-size: var(--font-sm);
    }
    .error {
        color: var(--danger, #dc2626);
        padding: var(--space-2) var(--space-3);
        border: 1px solid var(--danger, #dc2626);
        border-radius: var(--radius-md);
        margin-bottom: var(--space-3);
    }
    .toolbar {
        display: flex;
        justify-content: flex-end;
        margin-bottom: var(--space-2);
    }
    .create-form {
        display: grid;
        grid-template-columns: 1fr 1fr auto auto;
        gap: var(--space-3);
        align-items: end;
        padding: var(--space-3);
        border: 1px solid var(--border);
        border-radius: var(--radius-md);
        background: var(--surface-elevated);
        margin-bottom: var(--space-3);
    }
    @media (max-width: 600px) {
        .create-form {
            grid-template-columns: 1fr;
        }
    }
    .create-form .field {
        display: flex;
        flex-direction: column;
        gap: var(--space-1);
        font-size: var(--font-sm);
    }
    .create-form .field input {
        padding: var(--space-2) var(--space-3);
        border: 1px solid var(--border);
        border-radius: var(--radius-md);
        background: var(--surface);
        color: var(--text);
    }
    .create-form .field-inline {
        display: inline-flex;
        align-items: center;
        gap: var(--space-2);
        font-size: var(--font-sm);
    }
    .create-form .primary {
        background: var(--primary);
        color: var(--primary-contrast);
        border-color: var(--primary);
    }
    .create-form .primary:hover:not(:disabled) {
        background: var(--primary-hover);
        border-color: var(--primary-hover);
    }
    .create-form .error {
        grid-column: 1 / -1;
        margin: 0;
    }
</style>
