import type { InventoryPropertySummary } from '@/lib/velocityPlatformClient'; import type { Unit } from '@/types'; function asRecord(value: unknown): Record { return value && typeof value === 'object' && !Array.isArray(value) ? value as Record : {}; } function asNumber(value: unknown): number | null { if (typeof value === 'number' && Number.isFinite(value)) { return value; } if (typeof value === 'string') { const cleaned = value.replace(/[^0-9.]/g, ''); const parsed = Number(cleaned); if (Number.isFinite(parsed) && parsed > 0) { return parsed; } } return null; } function pickFirstNumber(values: unknown[]): number | null { for (const value of values) { const parsed = asNumber(value); if (parsed !== null) { return parsed; } } return null; } function mapInventoryStatus(status: string): Unit['status'] { switch ((status ?? '').toLowerCase()) { case 'active': return 'available'; case 'under_review': return 'reserved'; case 'archived': return 'hold'; default: return 'hold'; } } function inferArea(unitMix: unknown[]): number { for (const item of unitMix) { const record = asRecord(item); const area = pickFirstNumber([ record.avg_area_sqm, record.avg_area, record.area_sqm, record.area, record.size_sqm, record.size, ]); if (area !== null) { return Math.round(area); } } return 0; } function inferPrice(priceBands: unknown[]): number { for (const item of priceBands) { const record = asRecord(item); const price = pickFirstNumber([ record.from, record.min, record.price, record.starting_price, record.amount, record.value, ]); if (price !== null) { return Math.round(price); } } return 0; } function inferType(propertyType: string, unitMix: unknown[]): Unit['type'] { const normalizedPropertyType = (propertyType ?? '').toLowerCase(); if (normalizedPropertyType.includes('penthouse')) return 'penthouse'; if (normalizedPropertyType.includes('studio')) return 'studio'; if (normalizedPropertyType.includes('1')) return '1br'; if (normalizedPropertyType.includes('2')) return '2br'; if (normalizedPropertyType.includes('3')) return '3br'; for (const item of unitMix) { const record = asRecord(item); const raw = String( record.type ?? record.unit_type ?? record.label ?? record.configuration ?? '' ).toLowerCase(); if (raw.includes('penthouse')) return 'penthouse'; if (raw.includes('studio')) return 'studio'; if (raw.includes('1')) return '1br'; if (raw.includes('2')) return '2br'; if (raw.includes('3')) return '3br'; } return '2br'; } function inferFloor(unitMix: unknown[]): number { for (const item of unitMix) { const record = asRecord(item); const floor = pickFirstNumber([record.floor, record.level, record.start_floor]); if (floor !== null) { return Math.round(floor); } } return 0; } export function mapInventoryPropertySummaryToUnit( property: InventoryPropertySummary, index: number, ): Unit { const location = asRecord(property.location); const unitMix = Array.isArray(property.unit_mix) ? property.unit_mix : []; const priceBands = Array.isArray(property.price_bands) ? property.price_bands : []; const district = typeof location.district === 'string' ? location.district : ''; const city = typeof location.city === 'string' ? location.city : ''; const view = [district, city].filter(Boolean).join(', ') || property.developer_name || 'Location pending'; return { id: property.property_id, unitNumber: property.project_name || `Property ${index + 1}`, type: inferType(property.property_type, unitMix), floor: inferFloor(unitMix), area: inferArea(unitMix), price: inferPrice(priceBands), status: mapInventoryStatus(property.status), view, lastUpdated: new Date(property.ingested_at ?? property.created_at ?? Date.now()), }; }