<script setup lang="ts">
import OperationTimeline from "@/components/operations/OperationTimeline.vue";
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 { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import AppLayout from "@/layouts/AppLayout.vue";
import { Head, Link, router, useForm } from "@inertiajs/vue3";
import {
    DatabaseIcon,
    GitBranchIcon,
    ListChecksIcon,
    PencilIcon,
    PlusIcon,
    RocketIcon,
    ServerIcon,
    SettingsIcon,
} from "lucide-vue-next";
import { computed } from "vue";

const props = defineProps<{
    application: Record<string, any>;
    environment: Record<string, any>;
    deploymentRequirements: {
        registryRequired: boolean;
        registryCount: number;
        serverCount: number;
    };
    gatewayRoutePreviews: {
        attachment_id: number;
        caddyfile: string;
    }[];
}>();

const gatewayAttachments = computed(() =>
    props.environment.attachments.filter((attachment) => attachment.role === "gateway"),
);

const gatewayCutovers = computed(() =>
    props.environment.operations.filter((operation) => operation.kind === "gateway_cutover"),
);

const caddyfilePreviewFor = (attachmentId: number): string =>
    props.gatewayRoutePreviews.find((preview) => preview.attachment_id === attachmentId)?.caddyfile ??
    "# No route preview available";

const deployForm = useForm({
    target_commit: "",
});

const deployEnvironment = (): void => {
    deployForm.post(
        route("environment-deployments.store", {
            organisation: route().params.organisation,
            application: props.application.id,
            environment: props.environment.id,
        }),
        {
            preserveScroll: true,
        },
    );
};
</script>

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

    <AppLayout
        :breadcrumbs="[
            {
                title: 'Applications',
                href: route('applications.index', { organisation: $page.props.organisation.id }),
            },
            {
                title: application.name,
                href: route('applications.show', {
                    organisation: $page.props.organisation.id,
                    application: application.id,
                }),
            },
            { title: environment.name },
        ]"
    >
        <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>
                    <div class="flex items-center gap-2">
                        <h2 class="text-3xl font-bold tracking-tight">{{ environment.name }}</h2>
                        <Badge
                            :variant="environment.status === 'active' ? 'success' : 'secondary'"
                            >{{ environment.status.replace("-", " ") }}</Badge
                        >
                    </div>
                    <p class="mt-1 text-sm text-muted-foreground">
                        <GitBranchIcon class="mr-1 inline size-4" />{{ environment.branch }}
                    </p>
                    <p class="mt-1 text-sm text-muted-foreground">
                        Scheduler:
                        {{
                            environment.scheduler_enabled
                                ? `${environment.scheduler_mode} on ${
                                      environment.services?.find(
                                          (service) =>
                                              service.id === environment.scheduler_target_service_id,
                                      )?.name ?? "selected service"
                                  }`
                                : "disabled"
                        }}
                    </p>
                </div>
                <div class="flex flex-wrap gap-2">
                    <Button
                        :as="Link"
                        variant="secondary"
                        :href="
                            route('environments.edit', {
                                organisation: $page.props.organisation.id,
                                application: application.id,
                                environment: environment.id,
                            })
                        "
                    >
                        <PencilIcon class="size-4" />
                        Settings
                    </Button>
                    <Button
                        variant="secondary"
                        @click="
                            router.post(
                                route('environment-migrations.store', {
                                    organisation: $page.props.organisation.id,
                                    application: application.id,
                                    environment: environment.id,
                                }),
                            )
                        "
                    >
                        <ListChecksIcon class="size-4" />
                        Migrate
                    </Button>
                    <Button
                        :as="Link"
                        variant="secondary"
                        :href="
                            route('environment-attachments.create', {
                                organisation: $page.props.organisation.id,
                                application: application.id,
                                environment: environment.id,
                            })
                        "
                    >
                        <PlusIcon class="size-4" />
                        Attach
                    </Button>
                </div>
            </div>

            <Card>
                <CardHeader>
                    <CardTitle>Deploy Target</CardTitle>
                    <CardDescription>
                        Deploy the current {{ environment.branch }} branch head, or pin this
                        deployment to a specific commit SHA.
                    </CardDescription>
                </CardHeader>
                <CardContent>
                    <form class="flex flex-col gap-3 md:flex-row md:items-end" @submit.prevent="deployEnvironment">
                        <div class="grid flex-1 gap-2">
                            <Label for="target_commit">Commit SHA</Label>
                            <Input
                                id="target_commit"
                                v-model="deployForm.target_commit"
                                placeholder="Leave blank to resolve the branch head"
                                maxlength="40"
                            />
                            <InputError :message="deployForm.errors.target_commit" />
                        </div>
                        <Button
                            type="submit"
                            :disabled="deploymentRequirements.registryRequired || deployForm.processing"
                            :title="
                                deploymentRequirements.registryRequired
                                    ? 'Configure a registry before deploying to multiple servers.'
                                    : undefined
                            "
                        >
                            <RocketIcon class="size-4" />
                            Deploy
                        </Button>
                    </form>
                </CardContent>
            </Card>

            <Card v-if="deploymentRequirements.registryRequired" class="border-amber-200 bg-amber-50">
                <CardHeader>
                    <CardTitle>Registry Required</CardTitle>
                    <CardDescription>
                        This environment spans {{ deploymentRequirements.serverCount }} servers.
                        Configure a registry before deploying so every server can pull the same
                        artifact.
                    </CardDescription>
                </CardHeader>
                <CardContent>
                    <Button
                        :as="Link"
                        variant="secondary"
                        :href="
                            route('registries.create', {
                                organisation: $page.props.organisation.id,
                            })
                        "
                    >
                        Add registry
                    </Button>
                </CardContent>
            </Card>

            <div class="grid gap-4 lg:grid-cols-[2fr_1fr]">
                <div class="space-y-4">
                    <Card>
                        <CardHeader>
                            <CardTitle>Services</CardTitle>
                            <CardDescription
                                >{{ environment.services?.length ?? 0 }} runtime and managed
                                services</CardDescription
                            >
                        </CardHeader>
                        <CardContent class="grid gap-3">
                            <div
                                v-for="service in environment.services"
                                :key="service.id"
                                class="rounded-md border p-3"
                            >
                                <div class="flex flex-wrap items-start justify-between gap-3">
                                    <div>
                                        <div class="flex items-center gap-2">
                                            <ServerIcon class="size-4" />
                                            <h3 class="font-semibold">{{ service.name }}</h3>
                                            <Badge variant="outline">{{ service.type }}</Badge>
                                        </div>
                                        <p class="mt-1 text-sm text-muted-foreground">
                                            {{ service.replicas?.length ?? 0 }} replicas ·
                                            {{ service.slices?.length ?? 0 }} slices ·
                                            {{ service.status?.replace("-", " ") }}
                                        </p>
                                    </div>
                                    <Button
                                        :as="Link"
                                        size="sm"
                                        variant="secondary"
                                        :href="
                                            route('environment-services.show', {
                                                organisation: $page.props.organisation.id,
                                                application: environment.application_id,
                                                environment: environment.id,
                                                service: service.id,
                                            })
                                        "
                                    >
                                        <SettingsIcon class="size-4" />
                                        Open
                                    </Button>
                                </div>
                            </div>
                        </CardContent>
                    </Card>

                    <Card>
                        <CardHeader>
                            <CardTitle>Operations</CardTitle>
                        </CardHeader>
                        <CardContent>
                            <OperationTimeline :operations="environment.operations" />
                        </CardContent>
                    </Card>

                    <Card>
                        <CardHeader>
                            <div class="flex items-center justify-between gap-3">
                                <div>
                                    <CardTitle>Builds</CardTitle>
                                    <CardDescription>
                                        Recent artifacts planned or built for this environment.
                                    </CardDescription>
                                </div>
                                <Button
                                    :as="Link"
                                    size="sm"
                                    variant="secondary"
                                    :href="
                                        route('build-artifacts.index', {
                                            organisation: $page.props.organisation.id,
                                            application: application.id,
                                            environment: environment.id,
                                        })
                                    "
                                >
                                    View all
                                </Button>
                            </div>
                        </CardHeader>
                        <CardContent class="grid gap-2">
                            <div
                                v-for="artifact in environment.build_artifacts"
                                :key="artifact.id"
                                class="rounded-md border p-3 text-sm"
                            >
                                <div class="flex flex-wrap items-center gap-2">
                                    <Badge variant="outline">{{ artifact.status }}</Badge>
                                    <span class="font-medium">{{ artifact.commit_sha }}</span>
                                    <span class="text-muted-foreground">{{ artifact.image_tag }}</span>
                                </div>
                                <p class="mt-1 text-muted-foreground">
                                    {{ artifact.registry_ref ?? "No registry ref" }}
                                    <span v-if="artifact.image_digest">
                                        · {{ artifact.image_digest }}
                                    </span>
                                </p>
                            </div>
                            <div
                                v-if="environment.build_artifacts.length === 0"
                                class="rounded-md border border-dashed p-4 text-sm text-muted-foreground"
                            >
                                No builds recorded for this environment.
                            </div>
                        </CardContent>
                    </Card>
                </div>

                <div class="space-y-4">
                    <Card>
                        <CardHeader>
                            <CardTitle>Attachments</CardTitle>
                        </CardHeader>
                        <CardContent class="grid gap-2">
                            <div
                                v-for="attachment in environment.attachments"
                                :key="attachment.id"
                                class="rounded-md border p-3 text-sm"
                            >
                                <div class="flex items-center gap-2 font-medium">
                                    <DatabaseIcon class="size-4" />
                                    <Link
                                        :href="
                                            route('environment-attachments.edit', {
                                                organisation: $page.props.organisation.id,
                                                application: application.id,
                                                environment: environment.id,
                                                attachment: attachment.id,
                                            })
                                        "
                                        class="hover:underline"
                                    >
                                        {{ attachment.role.replace("_", " ") }}
                                    </Link>
                                </div>
                                <p class="mt-1 text-muted-foreground">
                                    {{ attachment.service?.name }} ·
                                    {{ attachment.service_slice?.name ?? "service level" }}
                                </p>
                                <div
                                    v-if="attachment.role === 'gateway'"
                                    class="mt-2 grid gap-1 text-xs text-muted-foreground"
                                >
                                    <div>
                                        Domain:
                                        {{ attachment.service_slice?.config?.domain ?? "not set" }}
                                    </div>
                                    <div>
                                        Path:
                                        {{ attachment.service_slice?.config?.path_prefix ?? "/" }}
                                        · TLS
                                        {{
                                            attachment.service_slice?.config?.tls_enabled === false
                                                ? "disabled"
                                                : "enabled"
                                        }}
                                    </div>
                                    <div>
                                        Certificate:
                                        {{
                                            attachment.service_slice?.config?.certificate_status ??
                                            "pending"
                                        }}
                                    </div>
                                </div>
                            </div>
                        </CardContent>
                    </Card>

                    <Card v-if="gatewayAttachments.length > 0">
                        <CardHeader>
                            <div class="flex flex-wrap items-start justify-between gap-3">
                                <div>
                                    <CardTitle>Gateway Cutover</CardTitle>
                                    <CardDescription>
                                        Route validation, reload, upstream health, and drain sequence.
                                    </CardDescription>
                                </div>
                                <Button
                                    :as="Link"
                                    size="xs"
                                    variant="secondary"
                                    :href="
                                        route('gateway.routes.index', {
                                            organisation: $page.props.organisation.id,
                                            application: application.id,
                                            environment: environment.id,
                                        })
                                    "
                                >
                                    Manage routes
                                </Button>
                            </div>
                        </CardHeader>
                        <CardContent class="grid gap-3">
                            <div
                                v-for="attachment in gatewayAttachments"
                                :key="attachment.id"
                                class="rounded-md border p-3 text-sm"
                            >
                                <div class="font-medium">
                                    {{ attachment.service_slice?.config?.domain ?? "Unassigned domain" }}
                                </div>
                                <div class="text-muted-foreground">
                                    Caddyfile: /home/keystone/gateway/Caddyfile
                                </div>
                                <pre class="mt-2 overflow-x-auto rounded-md bg-muted p-3 text-xs">{{
                                    caddyfilePreviewFor(attachment.id)
                                }}</pre>
                                <div class="mt-2 flex flex-wrap gap-2">
                                    <Badge variant="outline">Render route</Badge>
                                    <Badge variant="outline">Health check</Badge>
                                    <Badge variant="outline">Reload gateway</Badge>
                                    <Badge variant="outline">Drain old upstream</Badge>
                                </div>
                            </div>
                            <OperationTimeline :operations="gatewayCutovers" />
                        </CardContent>
                    </Card>
                    <Card v-else>
                        <CardHeader>
                            <div class="flex flex-wrap items-start justify-between gap-3">
                                <div>
                                    <CardTitle>Gateway Routes</CardTitle>
                                    <CardDescription>
                                        No gateway routes are configured for this environment.
                                    </CardDescription>
                                </div>
                                <Button
                                    :as="Link"
                                    size="xs"
                                    variant="secondary"
                                    :href="
                                        route('gateway.routes.index', {
                                            organisation: $page.props.organisation.id,
                                            application: application.id,
                                            environment: environment.id,
                                        })
                                    "
                                >
                                    Manage routes
                                </Button>
                            </div>
                        </CardHeader>
                    </Card>

                    <Card>
                        <CardHeader>
                            <CardTitle>Variables</CardTitle>
                        </CardHeader>
                        <CardContent class="flex flex-wrap gap-2">
                            <Badge
                                v-for="variable in environment.variables"
                                :key="variable.id"
                                :variant="variable.source === 'user' ? 'secondary' : 'outline'"
                            >
                                {{ variable.key }} · {{ variable.source.replace("_", " ") }}
                                <span v-if="!variable.overridable"> · locked</span>
                            </Badge>
                            <Button
                                :as="Link"
                                size="sm"
                                variant="secondary"
                                :href="
                                    route('environment-variables.index', {
                                        organisation: $page.props.organisation.id,
                                        application: application.id,
                                        environment: environment.id,
                                    })
                                "
                            >
                                <PlusIcon class="size-4" />
                                Manage
                            </Button>
                        </CardContent>
                    </Card>

                    <Card>
                        <CardHeader>
                            <CardTitle>Service policy</CardTitle>
                            <CardDescription>
                                Migration and scheduler-related defaults exposed by current
                                services.
                            </CardDescription>
                        </CardHeader>
                        <CardContent class="grid gap-2 text-sm">
                            <div
                                v-for="service in environment.services"
                                :key="service.id"
                                class="rounded-md border p-3"
                            >
                                <div class="font-medium">{{ service.name }}</div>
                                <div class="text-muted-foreground">
                                    Deploy policy: {{ service.deploy_policy ?? "default" }} ·
                                    Roles: {{ service.process_roles?.join(", ") || "none" }}
                                </div>
                                <div class="text-muted-foreground">
                                    Migration:
                                    {{
                                        service.config?.migration_mode ??
                                        service.config?.migration_timing ??
                                        "not configured"
                                    }}
                                </div>
                            </div>
                        </CardContent>
                    </Card>
                </div>
            </div>
        </div>
    </AppLayout>
</template>
