<script lang="ts">
    import Icon from "$lib/components/atoms/icon.svelte";
    import MaxWidthWrapper from "$lib/components/molecules/max-width-wrapper.svelte";
    import * as AlertDialog from "$lib/components/ui/alert-dialog/index.js";
    import { Badge } from "$lib/components/ui/badge";
    import { Button, buttonVariants } from "$lib/components/ui/button";
    import * as Card from "$lib/components/ui/card";
    import * as Dialog from "$lib/components/ui/dialog";
    import { Input } from "$lib/components/ui/input";
    import { Label } from "$lib/components/ui/label";
    import * as Table from "$lib/components/ui/table";
    import { FRONTEND_URL, mainNavTree } from "$lib/core/constants";
    import { linkVM } from "$lib/domains/link/link.vm.svelte";
    import { breadcrumbs } from "$lib/global.stores";
    import Ban from "@lucide/svelte/icons/ban";
    import Copy from "@lucide/svelte/icons/copy";
    import LinkIcon from "@lucide/svelte/icons/link";
    import Plus from "@lucide/svelte/icons/plus";
    import RefreshCw from "@lucide/svelte/icons/refresh-cw";
    import Trash2 from "@lucide/svelte/icons/trash-2";
    import { onMount } from "svelte";
    import { toast } from "svelte-sonner";

    breadcrumbs.set([mainNavTree[0], mainNavTree[1]]);

    let selectedDeviceId = $state("");
    let selectedSupportedAppId = $state("");
    let expiresAt = $state("");

    onMount(async () => {
        await linkVM.fetchLinks();
        await linkVM.fetchDevicesForSelect();
        await linkVM.fetchSupportedAppsForSelect();
    });

    function resetForm() {
        selectedDeviceId = "";
        selectedSupportedAppId = "";
        expiresAt = "";
    }

    async function handleCreate(e: Event) {
        e.preventDefault();
        const success = await linkVM.createLink({
            linkedDeviceId: Number(selectedDeviceId),
            supportedAppId: Number(selectedSupportedAppId),
            expiresAt: expiresAt ? new Date(expiresAt) : null,
        });
        if (success) resetForm();
    }

    function buildPublicLink(token: string): string {
        const base = FRONTEND_URL.trim() || "/";
        const origin =
            typeof window !== "undefined"
                ? window.location.origin
                : "http://localhost";
        const url = new URL(base, origin);
        url.searchParams.set("token", token);
        return url.toString();
    }

    async function copyLink(token: string) {
        try {
            await navigator.clipboard.writeText(buildPublicLink(token));
            toast.success("Link copied to clipboard");
        } catch {
            toast.error("Failed to copy");
        }
    }

    function statusVariant(
        status: string,
    ): "default" | "secondary" | "destructive" | "outline" {
        switch (status) {
            case "active":
                return "default";
            case "inactive":
                return "secondary";
            case "revoked":
                return "destructive";
            case "expired":
                return "outline";
            default:
                return "secondary";
        }
    }

    function formatDate(date: Date | string | null): string {
        if (!date) return "—";
        return new Date(date).toLocaleString();
    }
</script>

<MaxWidthWrapper cls="space-y-4">
    <Card.Root>
        <Card.Header>
            <div
                class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between"
            >
                <div class="flex items-center gap-2">
                    <Icon icon={LinkIcon} cls="h-5 w-5 text-primary" />
                    <Card.Title>Links</Card.Title>
                    <span class="text-muted-foreground text-xs">
                        {linkVM.links.length} total
                    </span>
                </div>
                <div class="flex items-center gap-2">
                    <Button
                        variant="outline"
                        size="sm"
                        onclick={() => void linkVM.fetchLinks()}
                        disabled={linkVM.loading}
                    >
                        <Icon
                            icon={RefreshCw}
                            cls={`h-4 w-4 mr-2 ${linkVM.loading ? "animate-spin" : ""}`}
                        />
                        Refresh
                    </Button>
                    <Button
                        size="sm"
                        onclick={() => {
                            linkVM.showCreateDialog = true;
                            linkVM.fetchDevicesForSelect();
                            linkVM.fetchSupportedAppsForSelect();
                        }}
                    >
                        <Icon icon={Plus} cls="h-4 w-4 mr-2" />
                        Generate Link
                    </Button>
                </div>
            </div>
        </Card.Header>

        <Card.Content>
            {#if !linkVM.loading && linkVM.links.length === 0}
                <div class="py-10 text-center text-sm text-muted-foreground">
                    No links generated yet.
                </div>
            {:else}
                <!-- Mobile cards -->
                <div class="space-y-3 md:hidden">
                    {#each linkVM.links as link (link.id)}
                        <div class="rounded-lg border bg-background p-3">
                            <div class="flex items-start justify-between gap-3">
                                <div class="min-w-0">
                                    <div class="flex items-center gap-2">
                                        <code
                                            class="truncate text-sm font-medium"
                                        >
                                            {link.token}
                                        </code>
                                        <button
                                            class="text-muted-foreground hover:text-foreground shrink-0"
                                            onclick={() => copyLink(link.token)}
                                        >
                                            <Copy class="h-3.5 w-3.5" />
                                        </button>
                                    </div>
                                </div>
                                <Badge variant={statusVariant(link.status)}>
                                    {link.status}
                                </Badge>
                            </div>
                            <div
                                class="mt-3 grid grid-cols-2 gap-x-3 gap-y-2 text-xs"
                            >
                                <div>
                                    <p class="text-muted-foreground">Device</p>
                                    <p>
                                        {linkVM.getDeviceName(
                                            link.linkedDeviceId,
                                        )}
                                    </p>
                                </div>
                                <div>
                                    <p class="text-muted-foreground">App</p>
                                    <p>
                                        {link.supportedApp?.title ||
                                            linkVM.getSupportedAppName(
                                                link.supportedAppId,
                                            )}
                                    </p>
                                </div>
                                <div>
                                    <p class="text-muted-foreground">Expires</p>
                                    <p>{formatDate(link.expiresAt)}</p>
                                </div>
                                <div>
                                    <p class="text-muted-foreground">
                                        Last Accessed
                                    </p>
                                    <p>{formatDate(link.lastAccessedAt)}</p>
                                </div>
                                <div>
                                    <p class="text-muted-foreground">Created</p>
                                    <p>{formatDate(link.createdAt)}</p>
                                </div>
                            </div>
                            <div class="mt-3 flex justify-end gap-2">
                                {#if link.status === "active"}
                                    <Button
                                        variant="outline"
                                        size="sm"
                                        onclick={() =>
                                            linkVM.revokeLink(link.id)}
                                        disabled={linkVM.revokingId === link.id}
                                    >
                                        <Icon icon={Ban} cls="h-4 w-4" />
                                    </Button>
                                {/if}
                                <AlertDialog.Root>
                                    <AlertDialog.Trigger
                                        class={buttonVariants({
                                            variant: "destructive",
                                            size: "sm",
                                        })}
                                        disabled={linkVM.deletingId === link.id}
                                    >
                                        <Icon icon={Trash2} cls="h-4 w-4" />
                                    </AlertDialog.Trigger>
                                    <AlertDialog.Content>
                                        <AlertDialog.Header>
                                            <AlertDialog.Title>
                                                Delete link?
                                            </AlertDialog.Title>
                                            <AlertDialog.Description>
                                                This will permanently remove
                                                this link. Anyone with this
                                                token will no longer be able to
                                                access the service.
                                            </AlertDialog.Description>
                                        </AlertDialog.Header>
                                        <AlertDialog.Footer>
                                            <AlertDialog.Cancel>
                                                Cancel
                                            </AlertDialog.Cancel>
                                            <AlertDialog.Action
                                                onclick={() =>
                                                    linkVM.deleteLink(link.id)}
                                            >
                                                Delete
                                            </AlertDialog.Action>
                                        </AlertDialog.Footer>
                                    </AlertDialog.Content>
                                </AlertDialog.Root>
                            </div>
                        </div>
                    {/each}
                </div>

                <!-- Desktop table -->
                <div class="hidden md:block">
                    <Table.Root>
                        <Table.Header>
                            <Table.Row>
                                <Table.Head>Token</Table.Head>
                                <Table.Head>Status</Table.Head>
                                <Table.Head>Device</Table.Head>
                                <Table.Head>Leased App</Table.Head>
                                <Table.Head>Expires</Table.Head>
                                <Table.Head>Last Accessed</Table.Head>
                                <Table.Head>Created</Table.Head>
                                <Table.Head>Actions</Table.Head>
                            </Table.Row>
                        </Table.Header>
                        <Table.Body>
                            {#each linkVM.links as link (link.id)}
                                <Table.Row>
                                    <Table.Cell>
                                        <div class="flex items-center gap-1.5">
                                            <code class="text-sm">
                                                {link.token}
                                            </code>
                                            <button
                                                class="text-muted-foreground hover:text-foreground"
                                                onclick={() =>
                                                    copyLink(link.token)}
                                            >
                                                <Copy class="h-3.5 w-3.5" />
                                            </button>
                                        </div>
                                    </Table.Cell>
                                    <Table.Cell>
                                        <Badge
                                            variant={statusVariant(link.status)}
                                        >
                                            {link.status}
                                        </Badge>
                                    </Table.Cell>
                                    <Table.Cell>
                                        {linkVM.getDeviceName(
                                            link.linkedDeviceId,
                                        )}
                                    </Table.Cell>
                                    <Table.Cell>
                                        <div class="space-y-0.5">
                                            <p class="text-sm font-medium">
                                                {link.supportedApp?.title ||
                                                    linkVM.getSupportedAppName(
                                                        link.supportedAppId,
                                                    )}
                                            </p>
                                        </div>
                                    </Table.Cell>
                                    <Table.Cell class="text-xs">
                                        {formatDate(link.expiresAt)}
                                    </Table.Cell>
                                    <Table.Cell class="text-xs">
                                        {formatDate(link.lastAccessedAt)}
                                    </Table.Cell>
                                    <Table.Cell class="text-xs">
                                        {formatDate(link.createdAt)}
                                    </Table.Cell>
                                    <Table.Cell>
                                        <div class="flex items-center gap-1">
                                            {#if link.status === "active"}
                                                <Button
                                                    variant="outline"
                                                    size="sm"
                                                    onclick={() =>
                                                        linkVM.revokeLink(
                                                            link.id,
                                                        )}
                                                    disabled={linkVM.revokingId ===
                                                        link.id}
                                                >
                                                    <Icon
                                                        icon={Ban}
                                                        cls="h-4 w-4 mr-1"
                                                    />
                                                    Revoke
                                                </Button>
                                            {/if}
                                            <AlertDialog.Root>
                                                <AlertDialog.Trigger
                                                    class={buttonVariants({
                                                        variant: "destructive",
                                                        size: "sm",
                                                    })}
                                                    disabled={linkVM.deletingId ===
                                                        link.id}
                                                >
                                                    <Icon
                                                        icon={Trash2}
                                                        cls="h-4 w-4"
                                                    />
                                                    Delete
                                                </AlertDialog.Trigger>
                                                <AlertDialog.Content>
                                                    <AlertDialog.Header>
                                                        <AlertDialog.Title>
                                                            Delete link?
                                                        </AlertDialog.Title>
                                                        <AlertDialog.Description
                                                        >
                                                            This will
                                                            permanently remove
                                                            this link. Anyone
                                                            with this token will
                                                            no longer be able to
                                                            access the service.
                                                        </AlertDialog.Description>
                                                    </AlertDialog.Header>
                                                    <AlertDialog.Footer>
                                                        <AlertDialog.Cancel>
                                                            Cancel
                                                        </AlertDialog.Cancel>
                                                        <AlertDialog.Action
                                                            onclick={() =>
                                                                linkVM.deleteLink(
                                                                    link.id,
                                                                )}
                                                        >
                                                            Delete
                                                        </AlertDialog.Action>
                                                    </AlertDialog.Footer>
                                                </AlertDialog.Content>
                                            </AlertDialog.Root>
                                        </div>
                                    </Table.Cell>
                                </Table.Row>
                            {/each}
                        </Table.Body>
                    </Table.Root>
                </div>
            {/if}
        </Card.Content>
    </Card.Root>
</MaxWidthWrapper>

<!-- Create Link Dialog -->
<Dialog.Root bind:open={linkVM.showCreateDialog}>
    <Dialog.Content class="sm:max-w-[425px]">
        <Dialog.Header>
            <Dialog.Title>Generate Link</Dialog.Title>
            <Dialog.Description>
                Create a new access link. The token is auto-generated.
            </Dialog.Description>
        </Dialog.Header>
        <form onsubmit={handleCreate} class="space-y-4">
            <div class="space-y-2">
                <Label for="device">Assigned Device</Label>
                <select
                    id="device"
                    bind:value={selectedDeviceId}
                    required
                    class="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1"
                >
                    <option value="" disabled>Select a device</option>
                    {#each linkVM.availableDevices as device}
                        <option value={String(device.id)}>
                            {device.title} — {device.host}{device.inUse
                                ? " (in use)"
                                : ""}
                        </option>
                    {/each}
                </select>
                <p class="text-muted-foreground text-xs">
                    Links now target one specific device.
                </p>
            </div>
            <div class="space-y-2">
                <Label for="supportedApp">Supported App</Label>
                <select
                    id="supportedApp"
                    bind:value={selectedSupportedAppId}
                    required
                    class="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1"
                >
                    <option value="" disabled>Select a supported app</option>
                    {#each linkVM.availableSupportedApps as app}
                        <option value={String(app.id)}>
                            {app.title}
                        </option>
                    {/each}
                </select>
                <p class="text-muted-foreground text-xs">
                    Supported apps are managed from the dedicated catalogue
                    page.
                </p>
            </div>
            <div class="space-y-2">
                <Label for="expiresAt">Expires At</Label>
                <Input
                    id="expiresAt"
                    type="datetime-local"
                    bind:value={expiresAt}
                />
                <p class="text-muted-foreground text-xs">
                    Optional. Leave empty for no expiry.
                </p>
            </div>
            <Dialog.Footer>
                <Button
                    variant="outline"
                    type="button"
                    onclick={() => (linkVM.showCreateDialog = false)}
                >
                    Cancel
                </Button>
                <Button type="submit" disabled={linkVM.creating}>
                    {linkVM.creating ? "Generating..." : "Generate"}
                </Button>
            </Dialog.Footer>
        </form>
    </Dialog.Content>
</Dialog.Root>
