import React from "react";
import { TrendingUp, TrendingDown, Minus, Plus } from "lucide-react";
import { cn } from "@/lib/utils";
import { formatCurrencyAbbrev } from "@/lib/format-currency";
import { Button } from "./button";
// ─── BorrowCapacityItem ───────────────────────────────────────────────────────
/**
* Displays a single borrowing capacity result field.
* Shows a muted label, optional sub-label, and the formatted value below.
*
* Used inside scenario detail cards on the Borrowing Capacity page.
*/
export interface BorrowCapacityItemProps {
/** Label above the value (e.g. "Purchase Price") */
title?: string;
/** Optional secondary descriptor below the title */
subTitle?: string;
/** Pre-formatted value string to display (e.g. "$500,000") */
value?: string;
className?: string;
}
export function BorrowCapacityItem({
title,
subTitle,
value,
className,
}: BorrowCapacityItemProps) {
if (!title && !value) {
return
;
}
return (
{title && (
{title}
)}
{value && (
{value}
)}
{subTitle && (
{subTitle}
)}
);
}
// ─── StatisticItem ────────────────────────────────────────────────────────────
/**
* Shows a financial trend statistic over a lookback period.
* Displays a heading ("Last N months"), the absolute dollar change,
* and the percentage change with a direction icon.
*
* Trend colors: positive → primary, flat/negative → muted.
*
* Used in the statistics summary row of the Borrowing Capacity page.
*/
export interface StatisticItemProps {
/** Number of months to look back (default: 3) */
loopBackMonths?: number;
/** Absolute dollar amount of change */
amountChange?: number;
/** Percentage change — positive = up, negative = down, 0 = flat */
amountChangePercentage?: number;
className?: string;
}
export function StatisticItem({
loopBackMonths = 3,
amountChange = 0,
amountChangePercentage = 0,
className,
}: StatisticItemProps) {
const isPositive = amountChangePercentage > 0;
const isNegative = amountChangePercentage < 0;
const TrendIcon = isPositive ? TrendingUp : isNegative ? TrendingDown : Minus;
const trendClassName = isPositive ? "text-primary" : "text-muted-foreground";
const amountPrefix = isPositive ? "+" : isNegative ? "−" : "";
return (
Last {loopBackMonths} month{loopBackMonths !== 1 ? "s" : ""}
{amountPrefix}
{formatCurrencyAbbrev(Math.abs(amountChange), 2)}
{Math.abs(amountChangePercentage).toFixed(1)}%
);
}
// ─── LoanToValueRatio ─────────────────────────────────────────────────────────
/**
* Displays a Loan-to-Value Ratio (LVR) as a percentage with a color-coded
* risk indicator and an optional equity/debt breakdown bar.
*
* Risk tiers:
* ≤ 60% → green (safe)
* 61–80% → warning (moderate)
* > 80% → destructive (high)
*
* Used in the LVR settings panel of the Borrowing Capacity page.
*/
export interface LoanToValueRatioProps {
/** LVR as a whole number percentage (0–100) */
lvr: number;
/** Optional debt amount — shown below the bar when provided */
debtAmount?: number;
/** Optional equity amount — shown below the bar when provided */
equityAmount?: number;
className?: string;
}
// Thresholds match major Australian lender risk bands
const LVR_TIER_STYLES = {
safe: { text: "text-success", bar: "bg-success" },
moderate: { text: "text-warning", bar: "bg-warning" },
high: { text: "text-destructive", bar: "bg-destructive" },
} as const;
export function LoanToValueRatio({
lvr,
debtAmount,
equityAmount,
className,
}: LoanToValueRatioProps) {
const clamped = Math.min(100, Math.max(0, lvr));
const tier = clamped <= 60 ? "safe" : clamped <= 80 ? "moderate" : "high";
const { text: lvrTextColor, bar: lvrBarColor } = LVR_TIER_STYLES[tier];
return (
{clamped.toFixed(0)}%
LVR
{/* Debt-vs-equity bar */}
{(debtAmount !== undefined || equityAmount !== undefined) && (
{debtAmount !== undefined && (
Debt {formatCurrencyAbbrev(debtAmount, 1)}
)}
{equityAmount !== undefined && (
Equity {formatCurrencyAbbrev(equityAmount, 1)}
)}
)}
);
}
// ─── AddScenarioButton ────────────────────────────────────────────────────────
/**
* A dashed-border CTA button for adding a new borrowing scenario.
* Renders as a full-width with a label and Plus icon.
* Supports a disabled state that removes interactivity.
*
* Used on the Borrowing Capacity page to open the "add / compare scenario" flow.
*/
export interface AddScenarioButtonProps {
/** Button label (default: "Add New Scenario") */
title?: string;
/** Disables the button */
disabled?: boolean;
/** Click handler */
onClick?: () => void;
className?: string;
}
export function AddScenarioButton({
title = "Add New Scenario",
disabled = false,
onClick,
className,
}: AddScenarioButtonProps) {
return (
{title}
);
}