<script setup lang="ts">
import StatusIndicator from "@/components/StatusIndicator.vue";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import AppLayout from "@/layouts/AppLayout.vue";
import { type BreadcrumbItem } from "@/types";
import { Head, Link, usePage } from "@inertiajs/vue3";
import { GitBranchIcon, PlusIcon } from "lucide-vue-next";
import { computed } from "vue";

defineProps<{
    organisations: Record<string, any>[];
    recentApplications: Record<string, any>[];
    deployments: Record<string, any>[];
    unhealthyServices: Record<string, any>[];
}>();

const page = usePage();
const organisation = computed(() => page.props.organisation);

const breadcrumbs: BreadcrumbItem[] = [
    {
        title: "Dashboard",
        href: "/dashboard",
    },
];

const initials = (name: string): string =>
    name
        .split(" ")
        .map((part) => part[0])
        .filter(Boolean)
        .slice(0, 2)
        .join("")
        .toUpperCase();

const timeAgo = (value?: string | null): string => {
    if (!value) {
        return "never";
    }

    const date = new Date(value);
    const seconds = Math.round((Date.now() - date.getTime()) / 1000);
    const formatter = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
    const divisions: { amount: number; unit: Intl.RelativeTimeFormatUnit }[] = [
        { amount: 60, unit: "seconds" },
        { amount: 60, unit: "minutes" },
        { amount: 24, unit: "hours" },
        { amount: 7, unit: "days" },
        { amount: 4.34524, unit: "weeks" },
        { amount: 12, unit: "months" },
        { amount: Number.POSITIVE_INFINITY, unit: "years" },
    ];

    let duration = -seconds;
    for (const division of divisions) {
        if (Math.abs(duration) < division.amount) {
            return formatter.format(Math.round(duration), division.unit);
        }
        duration /= division.amount;
    }

    return "just now";
};

const deploymentTarget = (operation: Record<string, any>): Record<string, any> | null => {
    const service = operation.target;
    const environment = service?.environment;
    const application = environment?.application;

    if (!service || !environment || !application) {
        return null;
    }

    return {
        service,
        environment,
        application,
        href: route("environments.show", {
            organisation: application.organisation_id,
            application: application.id,
            environment: environment.id,
        }),
    };
};
</script>

<template>
    <Head title="Dashboard" />

    <AppLayout :breadcrumbs="breadcrumbs">
        <div class="mx-auto w-full max-w-7xl space-y-8 p-4">
            <div class="flex flex-wrap items-center justify-between gap-3">
                <div>
                    <h1 class="text-2xl font-bold tracking-tight">Overview</h1>
                    <p v-if="organisation" class="text-sm text-muted-foreground">
                        {{ organisation.name }}
                    </p>
                </div>
                <Button
                    v-if="organisation"
                    :as="Link"
                    :href="route('applications.create', { organisation: organisation.id })"
                >
                    <PlusIcon class="size-4" />
                    New application
                </Button>
            </div>

            <section class="space-y-3">
                <h2 class="text-sm font-medium text-muted-foreground">Recent applications</h2>

                <div class="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
                    <Link
                        v-for="application in recentApplications"
                        :key="application.id"
                        :href="
                            route('applications.show', {
                                organisation: application.organisation_id,
                                application: application.id,
                            })
                        "
                        class="block"
                    >
                        <Card class="h-full transition-colors hover:border-foreground/20">
                            <CardContent class="flex flex-col gap-4 p-5">
                                <div class="flex items-start gap-3">
                                    <div
                                        class="flex size-10 shrink-0 items-center justify-center rounded-lg bg-muted text-sm font-semibold"
                                    >
                                        {{ initials(application.name) }}
                                    </div>
                                    <div class="min-w-0 flex-1">
                                        <div class="truncate font-medium">
                                            {{ application.name }}
                                        </div>
                                        <div class="truncate text-sm text-muted-foreground">
                                            {{
                                                application.source_provider?.name ??
                                                "No source provider"
                                            }}
                                        </div>
                                    </div>
                                    <StatusIndicator
                                        v-if="application.environments?.[0]"
                                        :status="application.environments[0].status"
                                    />
                                </div>
                                <div class="flex items-center gap-2 text-xs text-muted-foreground">
                                    <GitBranchIcon class="size-3.5" />
                                    <span class="rounded bg-muted px-1.5 py-0.5 font-mono">
                                        {{ application.environments?.[0]?.branch ?? "—" }}
                                    </span>
                                    <span>·</span>
                                    <span
                                        >{{
                                            application.environments?.length ?? 0
                                        }}
                                        environments</span
                                    >
                                </div>
                            </CardContent>
                        </Card>
                    </Link>

                    <Card
                        v-if="recentApplications.length === 0"
                        class="col-span-full border-dashed"
                    >
                        <CardContent class="flex flex-col items-center gap-3 p-8 text-center">
                            <p class="text-sm text-muted-foreground">No applications yet.</p>
                            <Button
                                v-if="organisation"
                                :as="Link"
                                size="sm"
                                :href="
                                    route('applications.create', { organisation: organisation.id })
                                "
                            >
                                <PlusIcon class="size-4" />
                                Create your first application
                            </Button>
                        </CardContent>
                    </Card>
                </div>
            </section>

            <section class="grid gap-6 lg:grid-cols-3">
                <Card class="lg:col-span-2">
                    <CardHeader>
                        <CardTitle>Latest deployments</CardTitle>
                        <CardDescription
                            >Recent operations across your organisations.</CardDescription
                        >
                    </CardHeader>
                    <CardContent class="p-0">
                        <ul class="divide-y">
                            <li
                                v-for="operation in deployments"
                                :key="operation.id"
                                class="flex items-center gap-3 px-6 py-3 text-sm"
                            >
                                <StatusIndicator :status="operation.status" />
                                <span class="font-mono text-xs text-muted-foreground">
                                    {{ operation.hash?.slice(0, 8) }}
                                </span>
                                <component
                                    :is="deploymentTarget(operation) ? Link : 'span'"
                                    :href="deploymentTarget(operation)?.href"
                                    class="min-w-0 flex-1 truncate"
                                    :class="deploymentTarget(operation) ? 'hover:underline' : ''"
                                >
                                    <span class="font-medium">
                                        {{ deploymentTarget(operation)?.application?.name ?? "—" }}
                                    </span>
                                    <span class="text-muted-foreground">
                                        {{ operation.kind?.replaceAll("_", " ") }}
                                    </span>
                                </component>
                                <span class="shrink-0 text-xs text-muted-foreground">
                                    {{ timeAgo(operation.finished_at ?? operation.created_at) }}
                                </span>
                            </li>
                            <li
                                v-if="deployments.length === 0"
                                class="px-6 py-8 text-center text-sm text-muted-foreground"
                            >
                                No deployments recorded.
                            </li>
                        </ul>
                    </CardContent>
                </Card>

                <Card>
                    <CardHeader>
                        <CardTitle>Unhealthy services</CardTitle>
                        <CardDescription>Services that need attention.</CardDescription>
                    </CardHeader>
                    <CardContent class="grid gap-2">
                        <div
                            v-for="service in unhealthyServices"
                            :key="service.id"
                            class="flex items-center justify-between rounded-md border p-3 text-sm"
                        >
                            <span class="font-medium">{{ service.name }}</span>
                            <StatusIndicator :status="service.status" />
                        </div>
                        <div
                            v-if="unhealthyServices.length === 0"
                            class="rounded-md border border-dashed p-3 text-sm text-muted-foreground"
                        >
                            No unhealthy services.
                        </div>
                    </CardContent>
                </Card>
            </section>
        </div>
    </AppLayout>
</template>
