<script setup lang="ts">
import { computed } from "vue";

const props = withDefaults(
    defineProps<{
        status?: string | null;
        label?: string;
        size?: "sm" | "md";
    }>(),
    {
        status: "unknown",
        size: "sm",
    },
);

type Tone = "positive" | "negative" | "pending" | "neutral";

const tones: Record<string, Tone> = {
    active: "positive",
    running: "positive",
    succeeded: "positive",
    success: "positive",
    completed: "positive",
    ready: "positive",
    verified: "positive",
    enabled: "positive",
    healthy: "positive",
    stopped: "negative",
    failed: "negative",
    error: "negative",
    errored: "negative",
    unhealthy: "negative",
    cancelled: "negative",
    installing: "pending",
    pending: "pending",
    "in-progress": "pending",
    building: "pending",
    planning: "pending",
    deploying: "pending",
    provisioning: "pending",
    queued: "pending",
};

const normalised = computed(() => (props.status ?? "unknown").toString().toLowerCase().trim());

const tone = computed<Tone>(() => tones[normalised.value] ?? "neutral");

const label = computed(
    () =>
        props.label ??
        (props.status ?? "unknown").toString().replaceAll("-", " ").replaceAll("_", " "),
);

const dotClasses = computed(() => {
    switch (tone.value) {
        case "positive":
            return "bg-green-500";
        case "negative":
            return "bg-red-500";
        case "pending":
            return "bg-amber-500 animate-pulse";
        default:
            return "bg-zinc-400 dark:bg-zinc-500";
    }
});

const textClasses = computed(() => {
    switch (tone.value) {
        case "positive":
            return "text-green-700 dark:text-green-400";
        case "negative":
            return "text-red-700 dark:text-red-400";
        case "pending":
            return "text-amber-700 dark:text-amber-400";
        default:
            return "text-muted-foreground";
    }
});
</script>

<template>
    <span class="inline-flex items-center gap-1.5">
        <span
            class="inline-block rounded-full"
            :class="[dotClasses, size === 'md' ? 'size-2' : 'size-1.5']"
        />
        <span class="capitalize" :class="[textClasses, size === 'md' ? 'text-sm' : 'text-xs']">{{
            label
        }}</span>
    </span>
</template>
