import { BriefcaseBusinessIcon, Building2Icon, HouseIcon, TreePalmIcon, type LucideIcon } from "lucide-react"
import { ROUTES } from "@/lib/dashboards/real-estate/nav"
import { formatCurrency, formatNumber } from "@/lib/format"
import { type Listing } from "@/lib/sample-data"
import { type StatusVariant } from "@/components/ui/status-badge"
/**
* The Real estate dashboard's words and the small rules every page reads the
* book by: what a listing's kind and status are called and the tone each
* status wears, the glyph that stands for a listing where a photograph would
* go, how an asking price is written, which listings are on the market, where
* a listing's page is, and how an agent's book is printed. One module the
* pages share, so a label or a rule is retuned in one place. Plain values
* with no rows behind them — the store's types above are erased — so a
* client island and a server file can both import it without the store
* coming along.
*/
export const KIND_LABELS: Record<Listing["kind"], string> = {
house: "House",
apartment: "Apartment",
villa: "Villa",
office: "Office",
}
/** A listing has no photograph: its kind's glyph, drawn in ink, stands for it. */
export const KIND_ICONS: Record<Listing["kind"], LucideIcon> = {
house: HouseIcon,
apartment: Building2Icon,
villa: TreePalmIcon,
office: BriefcaseBusinessIcon,
}
export const LISTING_STATUS_LABELS: Record<Listing["status"], string> = {
listed: "Listed",
under_offer: "Under offer",
sold: "Sold",
rented: "Rented",
}
export const LISTING_STATUS_MAP: Record<string, StatusVariant> = {
listed: "info",
under_offer: "warning",
sold: "success",
rented: "primary",
}
/** Whole dollars from minor units: an asking price is round by nature. */
export const money = (cents: number): string => formatCurrency(cents / 100, "USD", { maximumFractionDigits: 0 })
/** On the market: listed, or under offer. A listing that has sold or let is off it. */
export const isOpen = (row: Pick<Listing, "status">): boolean => row.status === "listed" || row.status === "under_offer"
/** `/real-estate/listings/lst_0012`: the listing page's route with the id in it. */
export const listingHref = (id: string): string => ROUTES.listing.replace("[id]", id)
/** The middle value, or the mean of the middle two; 0 for nothing. */
export function median(values: number[]): number {
if (values.length === 0) return 0
const sorted = [...values].sort((a, b) => a - b)
const middle = Math.floor(sorted.length / 2)
return sorted.length % 2 === 1 ? sorted[middle] : Math.round((sorted[middle - 1] + sorted[middle]) / 2)
}
/** What an agent's book comes to: their listings on the market, this year's closings, and every enquiry. */
export type AgentBook = {
active: number
soldThisYear: number
rentedThisYear: number
/** Every enquiry their whole book has drawn, open and closed listings alike. */
enquiries: number
}
/**
* An agent's book as a stat list, the way the Agents page and a listing's
* agent card both print it — one set of labels, so the two can be read
* against each other.
*/
export function agentBookItems(book: AgentBook, year: number): { label: string; value: string }[] {
return [
{ label: "On the market", value: formatNumber(book.active) },
{ label: `Sold in ${year}`, value: formatNumber(book.soldThisYear) },
{ label: `Let in ${year}`, value: formatNumber(book.rentedThisYear) },
{ label: "Enquiries on their book", value: formatNumber(book.enquiries) },
]
}