import { aggregateAcrossTeams, formatAggregationResult, loopGet, } from "../lib/loop-api.js"; // ─── Loop API V2: /property/residential/{dept} ───────────────── // Fields: id, refId, propertyAddress, status, propertyType, // dateCreated, price, bedrooms, offerCount, viewingCount, // publishedToPortals, publishedToWebsite, publishedToMatching // ──────────────────────────────────────────────────────────────── interface LoopPropertySummary { id: number; refId?: string; propertyAddress?: string; status?: string; propertyType?: string; dateCreated?: string; price?: number; bedrooms?: number; offerCount?: number; viewingCount?: number; publishedToPortals?: boolean; publishedToWebsite?: boolean; publishedToMatching?: boolean; [key: string]: unknown; } type Department = "sales" | "lettings" | "both"; export async function propertySearch(params: { accountId: string; department?: Department; searchTerm?: string; minPrice?: number; maxPrice?: number; minBedrooms?: number; maxBedrooms?: number; propertyStatuses?: string; propertyTypes?: string; teamName?: string; limit?: number; }): Promise { const { accountId, department = "both", searchTerm, minPrice, maxPrice, minBedrooms, maxBedrooms, propertyStatuses, propertyTypes, teamName, limit, } = params; const result = await aggregateAcrossTeams( accountId, "properties", "loop-property-search", async (apiKey, team) => { const depts: string[] = department === "both" ? ["sales", "lettings"] : [department]; const all: LoopPropertySummary[] = []; for (const dept of depts) { const qp: string[] = []; if (searchTerm) qp.push(`SearchTerm=${encodeURIComponent(searchTerm)}`); if (minPrice != null) qp.push(`MinPrice=${minPrice}`); if (maxPrice != null) qp.push(`MaxPrice=${maxPrice}`); if (minBedrooms != null) qp.push(`MinBedrooms=${minBedrooms}`); if (maxBedrooms != null) qp.push(`MaxBedrooms=${maxBedrooms}`); if (propertyStatuses) qp.push(`PropertyStatuses=${encodeURIComponent(propertyStatuses)}`); if (propertyTypes) qp.push(`PropertyTypes=${encodeURIComponent(propertyTypes)}`); const query = qp.length > 0 ? `?${qp.join("&")}` : ""; const path = `/property/residential/${dept}${query}`; const data = await loopGet(apiKey, path, "loop-property-search", team); if (Array.isArray(data)) all.push(...data); } return all; }, { teamName, limitPerTeam: limit ?? 50, limitTotal: limit ?? 200 } ); return formatAggregationResult( result, (p) => { const id = p.id != null ? ` [ID: ${p.id}]` : ""; const price = p.price ? ` — £${p.price.toLocaleString("en-GB")}` : ""; const beds = p.bedrooms ? ` ${p.bedrooms}bed` : ""; const status = p.status ? ` [${p.status}]` : ""; const propType = p.propertyType ? ` (${p.propertyType})` : ""; const offers = p.offerCount ? ` ${p.offerCount} offer${p.offerCount !== 1 ? "s" : ""}` : ""; return `- ${p.propertyAddress ?? "Unknown address"}${id}${price}${beds}${propType}${status}${offers}`; }, "properties" ); }