"use client";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useEffect, useRef, useState } from "react";
import { Popover, PopoverContent, PopoverTrigger, } from "../../../../components/ui/popover";
import { useParheliaSettings } from "../../../hooks/useParheliaSettings";
import { formatAgentCost, reconcileAgentCostTotal } from "../agentCost";
export function AgentCostDisplay({ className = "", response, totalTokens, costLimit, }) {
    const [showCostPopover, setShowCostPopover] = useState(false);
    const costPopoverRef = useRef(null);
    const parheliaSettings = useParheliaSettings();
    const currency = parheliaSettings?.currency || "USD";
    const limit = costLimit != null ? Number(costLimit) : null;
    // Handle click outside for cost popover
    useEffect(() => {
        function handleClickOutside(event) {
            if (costPopoverRef.current &&
                !costPopoverRef.current.contains(event.target)) {
                setShowCostPopover(false);
            }
        }
        if (showCostPopover) {
            document.addEventListener("click", handleClickOutside);
            return () => {
                document.removeEventListener("click", handleClickOutside);
            };
        }
    }, [showCostPopover]);
    // Calculate estimated cost based on typical pricing (rough estimates)
    // Claude 3.5 Sonnet pricing: ~$3/MTok input, ~$15/MTok output
    const calculateEstimatedCost = (inputTokens, outputTokens, cachedTokens, cacheWriteTokens = 0) => {
        // Cached tokens are a subset of input tokens, not additional tokens
        const freshInputTokens = inputTokens - cachedTokens;
        const inputCost = (freshInputTokens / 1000000) * 3; // $3 per million tokens
        const outputCost = (outputTokens / 1000000) * 15; // $15 per million tokens
        const cachedCost = (cachedTokens / 1000000) * 0.3; // Cached tokens are typically much cheaper
        const cacheWriteCost = (cacheWriteTokens / 1000000) * 3.75; // Cache write tokens cost more
        return {
            inputCost,
            outputCost,
            cachedCost,
            cacheWriteCost,
            totalCost: inputCost + outputCost + cachedCost + cacheWriteCost,
        };
    };
    // Use actual cost data if available, otherwise calculate estimates
    const currentCost = response
        ? response.totalCost !== undefined
            ? {
                inputCost: response.inputCost ?? 0,
                outputCost: response.outputCost ?? 0,
                cachedCost: response.cachedCost ?? 0,
                cacheWriteCost: response.cacheWriteCost ?? 0,
                totalCost: response.totalCost,
            }
            : calculateEstimatedCost(response.numInputTokens, response.numOutputTokens, response.numCachedTokens, response.numCacheWriteTokens ?? 0)
        : null;
    const declaredTotalCost = totalTokens?.totalCost ?? currentCost?.totalCost ?? 0;
    const displayTotalCost = totalTokens
        ? reconcileAgentCostTotal(declaredTotalCost, totalTokens)
        : declaredTotalCost;
    // Dev-mode invariant: visible rows should sum to the displayed total within rounding tolerance.
    // Warn (don't throw) so a regression like "header 0.63 vs rows 0.12" surfaces in the console
    // before the user notices it in the UI.
    useEffect(() => {
        if (process.env.NODE_ENV === "production")
            return;
        if (!totalTokens)
            return;
        const rowsSum = (totalTokens.inputCost ?? 0) +
            (totalTokens.outputCost ?? 0) +
            (totalTokens.cachedCost ?? 0) +
            (totalTokens.cacheWriteCost ?? 0) +
            (totalTokens.inputAudioCost ?? 0) +
            (totalTokens.outputAudioCost ?? 0) +
            (totalTokens.outputImageCost ?? 0) +
            (totalTokens.imageCost ?? 0) +
            (totalTokens.markupCost ?? 0);
        const drift = Math.abs(rowsSum - (totalTokens.totalCost ?? 0));
        if (drift > 0.005) {
            console.warn("[AgentCostDisplay] Row-sum invariant broken: rows sum to %f but total is %f (drift %f). " +
                "Server emitted inconsistent cost fields — see CostSnapshot.Apply on the backend.", rowsSum, totalTokens.totalCost, drift);
        }
    }, [totalTokens]);
    const hasTokenData = response &&
        (response.numInputTokens > 0 ||
            response.numOutputTokens > 0 ||
            response.numCachedTokens > 0);
    const hasTotalData = totalTokens &&
        (totalTokens.input > 0 || totalTokens.output > 0 || totalTokens.cached > 0);
    const hasCostData = (response && response.totalCost && response.totalCost > 0) ||
        (totalTokens && totalTokens.totalCost && totalTokens.totalCost > 0);
    if (!hasTokenData && !hasTotalData && !hasCostData && !(limit && limit > 0)) {
        return null;
    }
    // Calculate percentage of limit used
    const percentUsed = limit && limit > 0 ? Math.min((displayTotalCost / limit) * 100, 100) : null;
    // Determine color based on usage
    const getColorClass = () => {
        if (!percentUsed)
            return "text-neutral-grey-50";
        if (percentUsed >= 100)
            return "text-feedback-red";
        if (percentUsed >= 80)
            return "text-component-shared";
        if (percentUsed >= 60)
            return "text-feedback-orange";
        return "text-neutral-grey-50";
    };
    return (_jsx("div", { className: `relative ${className}`, ref: costPopoverRef, "data-testid": "agent-cost-display", children: _jsxs(Popover, { open: showCostPopover, onOpenChange: setShowCostPopover, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("div", { className: `hover:text-neutral-grey-50 cursor-pointer text-right text-[10px] ${getColorClass()}`, "data-testid": "agent-cost-display-trigger", children: ["Total cost:", " ", _jsx("span", { className: "font-medium", children: formatAgentCost(displayTotalCost, currency) }), limit && limit > 0 && ` / ${formatAgentCost(limit, currency)}`] }) }), _jsx(PopoverContent, { className: "w-80 p-4", align: "end", side: "bottom", "data-testid": "agent-cost-display-popover", children: _jsxs("div", { className: "space-y-4", children: [_jsx("div", { className: "border-b pb-2", children: _jsxs("h4", { className: "flex items-center justify-between text-sm font-medium", children: [_jsx("div", { children: "Cost Breakdown" }), _jsxs("span", { className: "text-sm font-medium", children: [formatAgentCost(displayTotalCost, currency), limit && limit > 0 && (_jsxs("span", { className: "text-neutral-grey-50 ml-1 text-xs", children: ["/ ", formatAgentCost(limit, currency)] }))] })] }) }), limit && limit > 0 && (_jsxs("div", { className: "bg-neutral-grey-5 rounded-md p-3", children: [_jsxs("div", { className: "mb-2 flex items-center justify-between text-xs", children: [_jsx("span", { className: "text-neutral-grey-100 font-medium", children: "Cost Limit Usage" }), _jsxs("span", { className: `font-medium ${getColorClass()}`, children: [percentUsed?.toFixed(1), "%"] })] }), _jsx("div", { className: "bg-neutral-grey-10 h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: `h-full transition-all ${percentUsed && percentUsed >= 100
                                                ? "bg-feedback-red"
                                                : percentUsed && percentUsed >= 80
                                                    ? "bg-component-shared"
                                                    : percentUsed && percentUsed >= 60
                                                        ? "bg-feedback-orange"
                                                        : "bg-highlight-100"}`, style: { width: `${Math.min(percentUsed || 0, 100)}%` } }) }), percentUsed != null && percentUsed >= 90 && (_jsx("p", { className: "text-neutral-grey-50 mt-2 text-xs", children: percentUsed >= 100
                                            ? "Cost limit reached. Execution will stop on next API call."
                                            : "Approaching cost limit. Consider extending if needed." }))] })), _jsx("div", { className: "space-y-3", children: (hasTotalData || hasTokenData) && (_jsx(_Fragment, { children: _jsx("div", { className: "space-y-2", children: hasTotalData ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Input tokens:" }), _jsxs("span", { className: "text-xs", children: [totalTokens.input.toLocaleString(), " (", totalTokens.inputCost.toFixed(2), " ", currency, ")"] })] }), (totalTokens.inputAudio ?? 0) > 0 && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Input audio tokens:" }), _jsxs("span", { className: "text-xs", children: [(totalTokens.inputAudio ?? 0).toLocaleString(), " (", (totalTokens.inputAudioCost ?? 0).toFixed(2), " ", currency, ")"] })] })), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Output tokens:" }), _jsxs("span", { className: "text-xs", children: [totalTokens.output.toLocaleString(), " (", totalTokens.outputCost.toFixed(2), " ", currency, ")"] })] }), (totalTokens.reasoning ?? 0) > 0 && (_jsxs("div", { className: "flex items-center justify-between pl-3", "data-testid": "reasoning-tokens-row", title: "Reasoning tokens are a subset of output tokens \u2014 already counted in the Output cost above.", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs italic", children: "\u21B3 of which reasoning:" }), _jsx("span", { className: "text-neutral-grey-50 text-xs italic", children: (totalTokens.reasoning ?? 0).toLocaleString() })] })), (totalTokens.outputImage ?? 0) > 0 && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Output image tokens:" }), _jsxs("span", { className: "text-xs", children: [(totalTokens.outputImage ?? 0).toLocaleString(), " ", "(", (totalTokens.outputImageCost ?? 0).toFixed(2), " ", currency, ")"] })] })), (totalTokens.outputAudio ?? 0) > 0 && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Output audio tokens:" }), _jsxs("span", { className: "text-xs", children: [(totalTokens.outputAudio ?? 0).toLocaleString(), " ", "(", (totalTokens.outputAudioCost ?? 0).toFixed(2), " ", currency, ")"] })] })), totalTokens.cached > 0 && (_jsxs("div", { className: "flex items-center justify-between", "data-testid": "cached-tokens-row", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Cached tokens:" }), _jsxs("span", { className: "text-xs", "data-testid": "cached-tokens-value", children: [totalTokens.cached.toLocaleString(), " (", totalTokens.cachedCost.toFixed(2), " ", currency, ")"] })] })), totalTokens.cacheWrite > 0 && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Cache write tokens:" }), _jsxs("span", { className: "text-xs", children: [totalTokens.cacheWrite.toLocaleString(), " (", (totalTokens.cacheWriteCost ?? 0).toFixed(2), " ", currency, ")"] })] })), totalTokens.imageCost > 0 && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Image generation:" }), _jsxs("span", { className: "text-xs", children: [totalTokens.imageCost.toFixed(2), " ", currency] })] })), (totalTokens.markupCost ?? 0) > 0 && (_jsxs("div", { className: "mt-1 flex items-center justify-between border-t border-dashed pt-2", "data-testid": "provider-markup-row", title: "Billed by the provider (e.g. OpenRouter) on top of upstream model cost.", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Provider markup:" }), _jsxs("span", { className: "text-xs", children: [(totalTokens.markupCost ?? 0).toFixed(2), " ", currency] })] }))] })) : (_jsx(_Fragment, { children: response && currentCost && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Input tokens:" }), _jsxs("span", { className: "text-xs", children: [response.numInputTokens.toLocaleString(), "(", currentCost.inputCost.toFixed(2), " ", currency, ")"] })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Output tokens:" }), _jsxs("span", { className: "text-xs", children: [response.numOutputTokens.toLocaleString(), "(", currentCost.outputCost.toFixed(2), " ", currency, ")"] })] }), response.numCachedTokens > 0 && (_jsxs("div", { className: "flex items-center justify-between", "data-testid": "cached-tokens-row", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Cached tokens:" }), _jsxs("span", { className: "text-xs", "data-testid": "cached-tokens-value", children: [response.numCachedTokens.toLocaleString(), "(", currentCost.cachedCost.toFixed(2), " ", currency, ")"] })] })), response.numCacheWriteTokens &&
                                                        response.numCacheWriteTokens > 0 && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-neutral-grey-50 text-xs", children: "Cache write tokens:" }), _jsxs("span", { className: "text-xs", children: [response.numCacheWriteTokens.toLocaleString(), "(", currentCost.cacheWriteCost.toFixed(2), " ", currency, ")"] })] })), _jsx("div", { className: "text-neutral-grey-50 mt-2 text-xs", children: "* Estimated costs based on typical Claude 3.5 pricing" })] })) })) }) })) })] }) })] }) }));
}
//# sourceMappingURL=AgentCostDisplay.js.map