"use client"

import { useEffect, useState } from "react"
import { useRouter } from "next/navigation"
import { toast } from "sonner"
import { InvoiceStatus, parseApiError } from "@garage/api"
import { confirm } from "@/shared/components/confirm-dialog"
import { badgeVariants } from "@/shared/components/ui/badge"
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from "@/shared/components/ui/select"
import { cn } from "@/shared/lib/utils"
import { formatEnum } from "@/shared/utils/formatters"
import { useAuthApi } from "@/shared/useApi"

type InvoiceStatusValue = (typeof InvoiceStatus)[number]

type InvoiceStatusBadgeProps = {
    invoice: {
        status?: string | null
        id: number | string
    }
}

const STATUS_TRIGGER_CLASS_NAMES: Record<InvoiceStatusValue, string> = {
    draft: "border-slate-200 bg-slate-100 text-slate-700 dark:border-slate-800 dark:bg-slate-900/70 dark:text-slate-200",
    open: "border-blue-200 bg-blue-100 text-blue-700 dark:border-blue-900 dark:bg-blue-950/70 dark:text-blue-200",
    over_due: "border-red-200 bg-red-100 text-red-700 dark:border-red-900 dark:bg-red-950/70 dark:text-red-200",
    paid: "border-emerald-200 bg-emerald-100 text-emerald-700 dark:border-emerald-900 dark:bg-emerald-950/70 dark:text-emerald-200",
    partially_paid: "border-amber-200 bg-amber-100 text-amber-700 dark:border-amber-900 dark:bg-amber-950/70 dark:text-amber-200",
    un_paid: "border-orange-200 bg-orange-100 text-orange-700 dark:border-orange-900 dark:bg-orange-950/70 dark:text-orange-200",
}

function isInvoiceStatus(value?: string | null): value is InvoiceStatusValue {
    return !!value && InvoiceStatus.includes(value as InvoiceStatusValue)
}

export default function InvoiceStatusBadge({ invoice }: InvoiceStatusBadgeProps) {
    const api = useAuthApi()
    const router = useRouter()
    const [isUpdating, setIsUpdating] = useState(false)
    const [status, setStatus] = useState<InvoiceStatusValue | undefined>(
        isInvoiceStatus(invoice.status) ? invoice.status : undefined,
    )

    useEffect(() => {
        setStatus(isInvoiceStatus(invoice.status) ? invoice.status : undefined)
    }, [invoice.status])

    const handleStatusChange = async (nextStatus: string) => {
        if (!isInvoiceStatus(nextStatus) || nextStatus === status || isUpdating) {
            return
        }

        const currentStatus = status
        const confirmed = await confirm({
            title: "Change Invoice Status",
            description: currentStatus
                ? `Change invoice status from ${formatEnum(currentStatus)} to ${formatEnum(nextStatus)}?`
                : `Change invoice status to ${formatEnum(nextStatus)}?`,
            confirmLabel: "Update",
        })

        if (!confirmed) {
            return
        }

        setIsUpdating(true)

        const loadingToast = toast.loading(`Updating invoice status to ${formatEnum(nextStatus)}...`)
        try {
            await api.invoices.update(String(invoice.id), { status: nextStatus })
            toast.success("Invoice status updated successfully.", { id: loadingToast })
            router.refresh()
        } catch (e) {
            toast.error(parseApiError(e, "Failed to update invoice status."), { id: loadingToast })
        } finally {
            setIsUpdating(false)
        }
    }

    return (
        <Select value={status} onValueChange={handleStatusChange} disabled={isUpdating}>
            <SelectTrigger
                size="sm"
                aria-label="Invoice status"
                className={cn(
                    badgeVariants({ variant: "outline" }),
                    "h-8 gap-1.5 rounded-full px-3 py-1 text-xs font-medium shadow-none focus-visible:ring-2 [&_svg]:size-3.5",
                    status
                        ? STATUS_TRIGGER_CLASS_NAMES[status]
                        : "border-border bg-muted/50 text-muted-foreground",
                )}
            >
                <SelectValue placeholder="Set status">
                    {formatEnum(status ?? null)}
                </SelectValue>
            </SelectTrigger>
            <SelectContent>
                {InvoiceStatus.map((value) => (
                    <SelectItem key={value} value={value}>
                        {formatEnum(value)}
                    </SelectItem>
                ))}
            </SelectContent>
        </Select>
    )
}
