<script setup lang="ts">
import InputError from "@/components/InputError.vue";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import AppLayout from "@/layouts/AppLayout.vue";
import { Head, Link, router, useForm } from "@inertiajs/vue3";
import { CopyIcon, EyeIcon, EyeOffIcon, PlusIcon, Trash2Icon } from "lucide-vue-next";
import { ref } from "vue";

defineProps<{
    application: Record<string, any>;
    environment: Record<string, any>;
    variables: Record<string, any>[];
}>();

const importForm = useForm({
    contents: "",
    overridable: true,
});
const revealedVariableIds = ref<number[]>([]);
const copiedVariableId = ref<number | null>(null);

const isRevealed = (variable: Record<string, any>): boolean =>
    revealedVariableIds.value.includes(variable.id);

const toggleReveal = (variable: Record<string, any>): void => {
    revealedVariableIds.value = isRevealed(variable)
        ? revealedVariableIds.value.filter((id) => id !== variable.id)
        : [...revealedVariableIds.value, variable.id];
};

const copyValue = async (variable: Record<string, any>): Promise<void> => {
    await navigator.clipboard.writeText(variable.value ?? "");
    copiedVariableId.value = variable.id;

    window.setTimeout(() => {
        if (copiedVariableId.value === variable.id) {
            copiedVariableId.value = null;
        }
    }, 1500);
};

const importVariables = (): void => {
    importForm.post(
        route("environment-variables.import", {
            organisation: route().params.organisation,
            application: route().params.application,
            environment: route().params.environment,
        }),
        {
            preserveScroll: true,
            onSuccess: () => importForm.reset("contents"),
        },
    );
};

const destroyVariable = (variable: Record<string, any>): void => {
    if (!window.confirm(`Delete ${variable.key}?`)) {
        return;
    }

    router.delete(
        route("environment-variables.destroy", {
            organisation: route().params.organisation,
            application: route().params.application,
            environment: route().params.environment,
            variable: variable.id,
        }),
    );
};
</script>

<template>
    <Head :title="`${environment.name} Variables`" />

    <AppLayout
        :breadcrumbs="[
            {
                title: application.name,
                href: route('applications.show', {
                    organisation: $page.props.organisation.id,
                    application: application.id,
                }),
            },
            {
                title: environment.name,
                href: route('environments.show', {
                    organisation: $page.props.organisation.id,
                    application: application.id,
                    environment: environment.id,
                }),
            },
            { title: 'Variables' },
        ]"
    >
        <div class="flex h-full flex-1 flex-col gap-4 p-4">
            <div class="flex flex-wrap items-center justify-between gap-3">
                <div>
                    <h2 class="text-3xl font-bold tracking-tight">Environment Variables</h2>
                    <p class="mt-1 text-sm text-muted-foreground">
                        User values can be edited. Managed values show their source and lock state.
                    </p>
                </div>
                <Button
                    :as="Link"
                    :href="
                        route('environment-variables.create', {
                            organisation: $page.props.organisation.id,
                            application: application.id,
                            environment: environment.id,
                        })
                    "
                >
                    <PlusIcon class="size-4" />
                    Add variable
                </Button>
            </div>

            <Card>
                <CardHeader>
                    <CardTitle>Variables</CardTitle>
                    <CardDescription>{{ variables.length }} configured values</CardDescription>
                </CardHeader>
                <CardContent class="grid gap-2">
                    <div
                        v-for="variable in variables"
                        :key="variable.id"
                        class="flex flex-wrap items-center gap-3 rounded-md border p-3 text-sm"
                    >
                        <div class="min-w-0 flex-1">
                            <div class="flex flex-wrap items-center gap-2">
                                <Link
                                    :href="
                                        route('environment-variables.edit', {
                                            organisation: $page.props.organisation.id,
                                            application: application.id,
                                            environment: environment.id,
                                            variable: variable.id,
                                        })
                                    "
                                    class="font-medium hover:underline"
                                >
                                    {{ variable.key }}
                                </Link>
                                <Badge
                                    :variant="variable.source === 'user' ? 'secondary' : 'outline'"
                                >
                                    {{ variable.source.replace("_", " ") }}
                                </Badge>
                                <Badge v-if="!variable.overridable" variant="outline">locked</Badge>
                                <Badge variant="outline">secret</Badge>
                            </div>
                            <p class="mt-1 text-muted-foreground">
                                {{ variable.service_slice?.name ?? "No slice source" }}
                            </p>
                        </div>
                        <code class="max-w-full truncate rounded bg-muted px-2 py-1 text-xs">
                            {{ isRevealed(variable) ? variable.value : "••••••••" }}
                        </code>
                        <Button
                            size="iconxs"
                            variant="ghost"
                            :aria-label="
                                isRevealed(variable)
                                    ? `Hide ${variable.key}`
                                    : `Reveal ${variable.key}`
                            "
                            @click="toggleReveal(variable)"
                        >
                            <EyeOffIcon v-if="isRevealed(variable)" class="size-3" />
                            <EyeIcon v-else class="size-3" />
                        </Button>
                        <Button
                            size="iconxs"
                            variant="ghost"
                            :aria-label="`Copy ${variable.key}`"
                            @click="copyValue(variable)"
                        >
                            <CopyIcon class="size-3" />
                            <span class="sr-only">
                                {{ copiedVariableId === variable.id ? "Copied" : "Copy" }}
                            </span>
                        </Button>
                        <Button size="iconxs" variant="ghost" @click="destroyVariable(variable)">
                            <Trash2Icon class="size-3" />
                        </Button>
                    </div>
                    <div
                        v-if="variables.length === 0"
                        class="rounded-md border border-dashed p-4 text-sm text-muted-foreground"
                    >
                        No variables configured.
                    </div>
                </CardContent>
            </Card>

            <Card>
                <CardHeader>
                    <CardTitle>Bulk Import</CardTitle>
                    <CardDescription>Paste KEY=value lines from an .env file.</CardDescription>
                </CardHeader>
                <CardContent>
                    <form class="grid gap-3" @submit.prevent="importVariables">
                        <textarea
                            v-model="importForm.contents"
                            class="min-h-40 rounded-md border border-input bg-transparent p-3 font-mono text-sm"
                            placeholder="APP_ENV=production&#10;APP_DEBUG=false"
                            required
                        />
                        <InputError :message="importForm.errors.contents" />
                        <label class="flex items-center gap-2 text-sm">
                            <input
                                v-model="importForm.overridable"
                                type="checkbox"
                                class="size-4"
                            />
                            Imported values are overridable
                        </label>
                        <InputError :message="importForm.errors.overridable" />
                        <div>
                            <Button type="submit" :disabled="importForm.processing">
                                Import variables
                            </Button>
                        </div>
                    </form>
                </CardContent>
            </Card>
        </div>
    </AppLayout>
</template>
