"use client";
import type { ValuationResponse } from "@/types/api";
import { deltaClass, fmtCurrency, fmtLarge, fmtPct } from "@/lib/format";
type Props = { data: ValuationResponse };
function pctVsCurrent(implied?: number | null, current?: number | null): number | null {
if (implied == null || current == null || current === 0) return null;
return (implied - current) / current;
}
function SummaryChip({
label,
price,
current,
accent = false,
}: {
label: string;
price?: number | null;
current?: number | null;
accent?: boolean;
}) {
const pct = pctVsCurrent(price, current);
return (
{label}
{price != null ? fmtCurrency(price) : "—"}
{pct != null && (
{fmtPct(pct, 1, true)}
)}
);
}
function MultipleRow({
label,
multiple,
price,
current,
}: {
label: string;
multiple?: number | null;
price?: number | null;
current?: number | null;
}) {
const pct = pctVsCurrent(price, current);
return (
{label}
{multiple != null ? `${multiple.toFixed(1)}×` : "—"}
{price != null ? fmtCurrency(price) : "—"}
{pct != null ? fmtPct(pct, 1, true) : "—"}
);
}
export function ValuationCard({ data }: Props) {
const { dcf, ev_ebitda, ev_revenue, price_to_book, current_price } = data;
const dcfPrice = dcf.available && !dcf.error ? dcf.intrinsic_value_per_share : null;
const hasMultiples = ev_ebitda.available || ev_revenue.available || price_to_book.available;
return (
{/* Summary strip */}
Market Price
{current_price != null ? fmtCurrency(current_price) : "—"}
{/* DCF detail */}
Discounted Cash Flow
WACC {(dcf.wacc * 100).toFixed(1)}% · Terminal {(dcf.terminal_growth * 100).toFixed(1)}%
{!dcf.available && (
Insufficient free cash flow history for DCF.
)}
{dcf.available && dcf.error && (
{dcf.error}
)}
{dcf.available && !dcf.error && (
Base FCF (TTM)
{dcf.base_fcf != null ? fmtLarge(dcf.base_fcf) : "—"}
Historical growth
{dcf.growth_rate_used != null ? fmtPct(dcf.growth_rate_used) : "—"}
Enterprise Value
{dcf.enterprise_value != null ? fmtLarge(dcf.enterprise_value) : "—"}
Net Debt
{dcf.net_debt != null ? fmtLarge(dcf.net_debt) : "—"}
Equity Value
{dcf.equity_value != null ? fmtLarge(dcf.equity_value) : "—"}
Intrinsic Value
{dcf.intrinsic_value_per_share != null ? fmtCurrency(dcf.intrinsic_value_per_share) : "—"}
{data.shares_outstanding != null && (
{fmtLarge(data.shares_outstanding)} shares
)}
)}
{/* Multiples */}
{hasMultiples && (
Multiples — at current market multiple
{ev_ebitda.available && (
)}
{ev_revenue.available && (
)}
{price_to_book.available && (
)}
)}
);
}