import { memo } from 'react' import { Box, Button, Typography } from '@mui/material' import { Ruler } from 'lucide-react' import { useNavigate } from 'react-router' import type { Property } from '../../domain/property' import type { VerifiedPortfolioResult } from '../../domain/unifiedResult' import type { Match } from '../../domain/match' import { MatchStrength, ResultType } from '../../domain/enums' import { useInquiryStore } from '../../stores/inquiryStore' import { usePipelineStore } from '../../stores/pipelineStore' import { useCompareStore } from '../../stores/compareStore' import { DS_ACCENT, DS_BRAND, DS_SLATE } from '../../lib/ds' interface Props { property: Property score: number needId: string } function buildSyntheticResult(property: Property, needId: string, score: number, matchId: string): VerifiedPortfolioResult { const strength = score >= 85 ? MatchStrength.STRONG : score >= 70 ? MatchStrength.MODERATE : MatchStrength.WEAK const syntheticMatch = { id: matchId, needId, propertyId: property.id, matchScore: score, matchStrength: strength, scoreBreakdown: { hardMatchScore: score, softFactorScore: score, confidenceModifier: 0, dataQualityModifier: 0, totalScore: score }, confidenceLevel: score / 100, } as unknown as Match return { matchId, needId, matchScore: score, resultType: ResultType.VERIFIED_PORTFOLIO, property, match: syntheticMatch, } } export const PropertyMatchRow = memo(function PropertyMatchRow({ property, score, needId }: Props) { const navigate = useNavigate() const openInquiryDialog = useInquiryStore(s => s.openInquiryDialog) const openSavedDialog = usePipelineStore(s => s.openSavedDialog) const { addToCompare, removeFromCompare, isInCompare, isFull } = useCompareStore() const scoreColor = score >= 85 ? '#16a34a' : score >= 70 ? '#d97706' : '#dc2626' const scoreBg = score >= 85 ? '#dcfce7' : score >= 70 ? '#fef3c7' : '#fee2e2' // Match IDs in the store use double-underscore format: m__propId__prop__needId const matchId = `m__${property.id}__prop__${needId}` const inCompare = isInCompare(matchId) function handleInquire() { openInquiryDialog({ propertyTitle: property.title, location: property.location.city, matchScore: score, matchId, propertyId: property.id, areaLabel: property.areaSqm ? `${property.areaSqm} m²` : undefined, rentLabel: property.rentPricePerSqm ? `CHF ${property.rentPricePerSqm}/m²/Jahr` : undefined, }) } function handleShortlist() { openSavedDialog({ resultId: matchId, resultType: 'VERIFIED_PORTFOLIO', title: property.title, matchScore: score, location: property.location.city, propertyId: property.id, propertyAddress: `${property.title}, ${property.location.city}`, areaLabel: property.areaSqm ? `${property.areaSqm} m²` : undefined, rentLabel: property.rentPricePerSqm ? `CHF ${property.rentPricePerSqm}/m²/Jahr` : undefined, }) } function handleCompare() { if (inCompare) { removeFromCompare(matchId) } else if (!isFull()) { addToCompare(buildSyntheticResult(property, needId, score, matchId)) } } function handleDetails() { navigate(`/demand/results/${matchId}`) } function handleUnit() { navigate(`/demand/property/${property.id}`) } return ( {property.images?.[0] ? ( ) : ( )} {property.title} {property.location.city} · {property.areaSqm} m² {score}% Anfrage Merken {inCompare ? 'Im Vergleich' : 'Vergleichen'} Details → Zur Einheit → ) }) function ActionButton({ children, onClick, primary, disabled }: { children: React.ReactNode onClick: () => void primary?: boolean disabled?: boolean }) { return ( ) }