import { useEffect, useMemo } from 'react' import { Box, Button, CircularProgress, Typography } from '@mui/material' import { ArrowRight } from 'lucide-react' import { useProperties } from '../../hooks/useProperties' import { ResultType } from '../../domain/enums' import { useOfferWizardStore } from '../../stores/offerWizardStore' import { useLatentNeedById } from '../../hooks/useLatentNeeds' import { useCreateOfferDraft } from '../../hooks/useOffers' import { useToastStore } from '../../stores/toastStore' import { SelectablePropertyMatchCard } from './SelectablePropertyMatchCard' import { deterministicMatchScore, assetTypeLabel } from './latentNeedUtils' function buildReason(propertyAssetType: string, needAssetType: string, city: string, location: string): string { if (propertyAssetType === needAssetType) { const cityMatch = location.toLowerCase().includes(city.toLowerCase()) || city.toLowerCase().includes(location.toLowerCase()) if (cityMatch) return 'Nutzungstyp und Standort passen sehr gut' return 'Passender Nutzungstyp, alternative Lage' } return 'Alternatives Profil — Detailprüfung empfohlen' } export function OfferPropertySelectionStep() { const needId = useOfferWizardStore(s => s.selectedNeedId) const selectedIds = useOfferWizardStore(s => s.selectedPropertyIds) const toggle = useOfferWizardStore(s => s.toggleProperty) const setSelected = useOfferWizardStore(s => s.setSelectedProperties) const setOfferDraftId = useOfferWizardStore(s => s.setOfferDraftId) const setStep = useOfferWizardStore(s => s.setStep) const { data: need } = useLatentNeedById(needId) const { data: properties = [], isLoading } = useProperties({ resultType: ResultType.VERIFIED_PORTFOLIO }) const createDraft = useCreateOfferDraft() const showToast = useToastStore(s => s.showToast) const scored = useMemo(() => { if (!need) return [] return properties .map(p => ({ property: p, score: deterministicMatchScore(p.id, need.id), reason: buildReason(p.assetType, need.assetType, p.location.city, need.desiredLocation), })) .sort((a, b) => b.score - a.score) }, [properties, need]) // Pre-select top 2 if nothing selected useEffect(() => { if (scored.length > 0 && selectedIds.length === 0) { setSelected(scored.slice(0, 2).map(s => s.property.id)) } }, [scored, selectedIds.length, setSelected]) const handleNext = async () => { if (!need) return if (selectedIds.length === 0) { showToast('Bitte mindestens ein Objekt auswählen', 'warning') return } const res = await createDraft.mutateAsync({ needId: need.id, selectedPropertyIds: selectedIds, needTitle: need.title, location: need.desiredLocation, assetType: need.assetType, sizeRange: need.sizeRange, }) if (res.error || !res.data) { showToast(`Fehler: ${res.error}`, 'error') return } setOfferDraftId(res.data.id) setStep('select_fields') } if (!need) { return ( ) } return ( {/* Need summary header */} Bedarf {need.title} {assetTypeLabel(need.assetType)} · {need.desiredLocation} · {need.sizeRange.min}–{need.sizeRange.max} m² Wählen Sie passende Objekte aus Ihrem Portfolio {isLoading && } {scored.map(({ property, score, reason }) => ( toggle(property.id)} reason={reason} /> ))} {selectedIds.length} Objekt{selectedIds.length === 1 ? '' : 'e'} ausgewählt ) }