import { memo, useCallback, useMemo, useState } from 'react'
import { Alert, Box, Button, Chip, Divider, TextField, Typography } from '@mui/material'
import { Building2, CheckCircle2, Copy, MapPin, Ruler } from 'lucide-react'
import type { MarktHinweis } from '../../domain/marktHinweis'
import type { Property } from '../../domain/property'
import { useProperties } from '../../hooks/useProperties'
import { ASSET_TYPE_LABELS } from '../../lib/constants'
import { areaFitPct } from '../market-leads'
import { OWN_VERWALTUNG_ID, QUELLE_LABELS, buildAnschreiben, formatDate } from './hinweisHelpers'
import { DS_ACCENT, DS_NEUTRAL, DS_SLATE } from '../../lib/ds'
/**
* Der Netzwerk-Bereich der Nora-Seite: menschlich erfasste Marktinformationen.
*
* Ausgezogen aus `MarketIntelligence.tsx`, die mit über 1100 Zeilen zwei
* eigenständige Funktionsbereiche in einer Datei führte — bei einem harten
* Limit von 300 Zeilen je Seite.
*/
// ── Netzwerk: HinweisPropertyCard ────────────────────────────────────────────
const HinweisPropertyCard = memo(function HinweisPropertyCard({
p,
hinweis,
}: {
p: Property
hinweis: MarktHinweis
}) {
const [open, setOpen] = useState(false)
const [copied, setCopied] = useState(false)
const companyName = hinweis.isAnonymized ? 'Interessent' : (hinweis.companyName ?? 'Interessent')
const areaEstimate = hinweis.areaSqmMax ?? hinweis.areaSqmMin
const [draft, setDraft] = useState(() =>
buildAnschreiben(companyName, hinweis.locationHint, p, areaEstimate)
)
const fit = areaEstimate != null ? areaFitPct(p.areaSqm, areaEstimate) : null
const handleCopy = useCallback(() => {
navigator.clipboard.writeText(draft)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}, [draft])
return (
{/* Property header */}
{p.title}
{p.location.city} · {p.areaSqm.toLocaleString('de-CH')} m² · CHF {p.rentPricePerSqm}/m²/J
{fit !== null && (
= 75 ? '#dcfce7' : fit >= 50 ? '#fef9c3' : '#fee2e2',
color: fit >= 75 ? '#16a34a' : fit >= 50 ? '#92400e' : '#dc2626',
}}
/>
)}
{/* Anschreiben toggle */}
{/* Anschreiben composer */}
{open && (
Anschreiben-Entwurf
: }
onClick={handleCopy}
sx={{ textTransform: 'none', fontSize: '0.72rem', color: copied ? '#16a34a' : '#152642' }}
>
{copied ? 'Kopiert!' : 'Kopieren'}
setDraft(e.target.value)}
sx={{
'& .MuiOutlinedInput-root': { fontSize: '0.8rem', bgcolor: 'white' },
'& textarea': { lineHeight: 1.6 },
}}
/>
Text bearbeitbar — dann kopieren und per E-Mail versenden
)}
)
})
// ── Netzwerk: HinweisDetail ──────────────────────────────────────────────────
function HinweisDetail({ hinweis }: { hinweis: MarktHinweis }) {
const { data: properties = [] } = useProperties()
const matchingProperties = useMemo(
() => properties.filter(p => p.assetType === hinweis.assetType).slice(0, 3),
[properties, hinweis.assetType],
)
const displayName = !hinweis.isAnonymized && hinweis.companyName ? hinweis.companyName : 'Anonym'
const areaStr = useMemo(() => {
if (hinweis.areaSqmMin != null && hinweis.areaSqmMax != null && hinweis.areaSqmMin !== hinweis.areaSqmMax) {
return `${hinweis.areaSqmMin}–${hinweis.areaSqmMax} m²`
}
if (hinweis.areaSqmMax != null) return `${hinweis.areaSqmMax} m²`
if (hinweis.areaSqmMin != null) return `${hinweis.areaSqmMin} m²`
return null
}, [hinweis.areaSqmMin, hinweis.areaSqmMax])
return (
{/* Header */}
{displayName}
{/* Badge row */}
{hinweis.direction === 'SUCHE'
?
:
}
{hinweis.visibility === 'INTERN'
?
: hinweis.verwaltungId === OWN_VERWALTUNG_ID
?
:
}
{/* Stat chips */}
} label={hinweis.locationHint} size="small" sx={{ bgcolor: DS_SLATE[100], color: DS_SLATE[600], fontSize: '0.75rem' }} />
{areaStr && } label={areaStr} size="small" sx={{ bgcolor: DS_SLATE[100], color: DS_SLATE[600], fontSize: '0.75rem' }} />}
{/* Quelle row */}
Quelle: {QUELLE_LABELS[hinweis.quelle] ?? hinweis.quelle}
{' · '}{hinweis.createdBy}
{' · '}{formatDate(hinweis.createdAt)}
{/* Body */}
{hinweis.note && (
Notiz
{hinweis.note}
)}
{hinweis.direction === 'SUCHE' ? (
Passende Objekte im Portfolio ({matchingProperties.length})
{matchingProperties.length === 0 ? (
Kein passendes Portfolioobjekt gefunden
) : (
matchingProperties.map(p => (
))
)}
) : (
Verfügbarkeitssignal — wird auf der Plattform für andere Verwaltungen sichtbar gemacht
)}
)
}
export { HinweisPropertyCard, HinweisDetail }