import { Box, Chip, Divider, LinearProgress, Paper, Typography } from '@mui/material' import { CheckCircle, TrendingDown, TrendingUp } from 'lucide-react' import { useProperties } from '../../hooks/useProperties' import { useNeeds } from '../../hooks/useNeeds' import { getCityIntelligence, getMarketRent } from '../../lib/locationIntelligence' import type { Property } from '../../domain/property' import { generateSellingArguments, generateWeaknesses } from './negotiationInsightsUtils' // ── Main component ──────────────────────────────────────────────────────────── interface Props { property: Property } export function NegotiationInsightsPanel({ property }: Props) { const { data: allProperties = [] } = useProperties() const { data: needs = [] } = useNeeds() const intel = getCityIntelligence(property.location.city) const marketRent = getMarketRent(property.location.city, property.assetType) const priceDiff = marketRent ? ((property.rentPricePerSqm - marketRent) / marketRent) * 100 : null // Comparable properties for price positioning const comparables = allProperties .filter(p => p.id !== property.id && p.assetType === property.assetType && p.location.city === property.location.city) const avgComparableRent = comparables.length > 0 ? comparables.reduce((s, p) => s + p.rentPricePerSqm, 0) / comparables.length : null // Active needs matching this property type/location const matchingNeeds = needs.filter(n => n.assetType === property.assetType && (n.preferredLocations?.some(loc => loc.toLowerCase().includes(property.location.city.toLowerCase())) ?? false) ) const sellingArgs = generateSellingArguments(property) const weaknesses = generateWeaknesses(property) const strongArgs = sellingArgs.filter(a => a.strength === 'strong') const mediumArgs = sellingArgs.filter(a => a.strength === 'medium') return ( {/* ── Price positioning ── */} Preispositionierung Ihr Preis CHF {property.rentPricePerSqm}/m² {marketRent && ( Marktmedian {property.location.city} CHF {marketRent}/m² )} {avgComparableRent && ( Vergleichsangebote Ø CHF {Math.round(avgComparableRent)}/m² )} {priceDiff !== null && ( 0 ? '#fff8f0' : '#f0fdf4', borderRadius: 1.5 }}> {priceDiff > 0 ? : } 15 ? '#92400e' : priceDiff > 0 ? '#d97706' : '#1a7a4a', fontWeight: 500 }}> {priceDiff > 15 ? `Ihr Preis liegt ${Math.round(priceDiff)}% über dem Marktmedian — starke USPs nötig zur Rechtfertigung.` : priceDiff > 5 ? `Leicht über Marktmedian (+${Math.round(priceDiff)}%) — gut durch Qualität begründbar.` : priceDiff > -5 ? 'Im Marktdurchschnitt — gute Ausgangsposition.' : `${Math.round(Math.abs(priceDiff))}% unter Marktmedian — Preiserhöhung oder schnelle Vermietung möglich.`} )} {/* Price bar vs market */} {marketRent && ( Marktbereich {property.location.city} CHF {Math.round(marketRent * 0.7)}–{Math.round(marketRent * 1.4)}/m² )} {/* ── Active demand ── */} Aktive Nachfrage Unternehmen, die aktuell in {property.location.city} suchen {matchingNeeds.length > 0 ? ( <> {matchingNeeds.length} aktive Suchprofile für diesen Typ & Standort {matchingNeeds.slice(0, 4).map(n => ( {n.companyName} {n.requiredArea?.min ?? 0}–{n.requiredArea?.max ?? 0} m² {n.budgetRange?.maxPerSqm ? ` · max. CHF ${n.budgetRange.maxPerSqm}/m²` : ''} ))} {matchingNeeds.length > 4 && ( + {matchingNeeds.length - 4} weitere Suchprofile )} ) : ( Keine aktiven Suchprofile für diesen Typ und Standort. )} {intel && ( Ø Vermietungsdauer vergleichbarer Objekte in {property.location.city}:{' '} {intel.avgDaysOnMarket} Tage )} {/* ── Selling arguments ── */} {sellingArgs.length > 0 && ( Verkaufsargumente für das Gespräch Stärken dieses Objekts — maßgeschneidert auf typische Mieterwünsche {strongArgs.length > 0 && ( Starke Argumente {strongArgs.map((arg, i) => ( {arg.title} {arg.detail} ))} )} {mediumArgs.length > 0 && ( Weitere Vorteile {mediumArgs.map((arg, i) => ( {arg.title} {arg.detail} ))} )} )} {/* ── Proactive weakness handling ── */} {weaknesses.length > 0 && ( Schwächen proaktiv adressieren Potenzielle Einwände kennen und entkräften — bevor der Interessent fragt {weaknesses.map((w, i) => ( ⚠ {w.issue} → {w.mitigation} {i < weaknesses.length - 1 && } ))} )} {/* ── Tenant fit ── */} {intel && intel.dominantIndustryClusters.length > 0 && ( Welche Mieter passen? Dominant präsente Branchen in {property.location.city} — hohes Match-Potenzial {intel.dominantIndustryClusters.map(c => ( ))} Nachfragestärke: {' '} {{ LOW: 'Gering', MEDIUM: 'Mittel', HIGH: 'Hoch', VERY_HIGH: 'Sehr hoch' }[intel.demandStrength]} )} ) }