import { useEffect, useMemo, useState } from 'react'
import { useNavigate } from 'react-router'
import {
  Alert,
  Box,
  Button,
  Checkbox,
  Chip,
  CircularProgress,
  Collapse,
  Divider,
  IconButton,
  LinearProgress,
  Switch,
  Tab,
  Tabs,
  TextField,
  Tooltip,
  Typography,
} from '@mui/material'
import { useQueryClient } from '@tanstack/react-query'
import { ChevronDown, ChevronUp, Clock, Edit2, Layers, Save, ShieldCheck, Users, X, Zap } from 'lucide-react'
import { useOfferWizardStore } from '../../stores/offerWizardStore'
import { PropertyMap } from '../shared'
import { NeedMatchCard } from './NeedMatchCard'
import { PropertyMarketSignalsTab } from './PropertyMarketSignalsTab'
import type { Property, PropertyUnit, UnitNeedMatch, UpdatePropertyInput } from '../../domain/property'
import { unitMatchService } from '../../services/unitMatchService'
import type { PropertyNeedMatch } from '../../domain/match'
import { usePropertyById } from '../../hooks/useProperties'
import { PropertyDetailSkeleton } from './PropertyDetailSkeleton'
import { matchService } from '../../services/matchService'
import { propertyService } from '../../services/propertyService'
import { useToastStore } from '../../stores/toastStore'
import {
  getAssetTypeColor,
  getAssetTypeLabel,
  getAvailabilityChipColor,
  getAvailabilityLabel,
  qualityColor,
} from './propertyHelpers'

interface PropertyDetailViewProps {
  propertyId: string
  onClose?: () => void
}

// ── Helpers ────────────────────────────────────────────────────────────────────

function Field({ label, value }: { label: string; value?: string | number | boolean | null }) {
  return (
    <Box sx={{ mb: 1.5 }}>
      <Typography variant="caption" color="text.secondary" sx={{ display: 'block', lineHeight: 1 }}>
        {label}
      </Typography>
      {value !== undefined && value !== null && value !== '' ? (
        <Typography variant="body2" sx={{ fontWeight: 500, mt: 0.25 }}>
          {typeof value === 'boolean' ? (value ? 'Ja' : 'Nein') : String(value)}
        </Typography>
      ) : (
        <Typography variant="body2" color="text.disabled" sx={{ mt: 0.25 }}>—</Typography>
      )}
    </Box>
  )
}

function FieldGrid({ children }: { children: React.ReactNode }) {
  return (
    <Box sx={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 0.5 }}>
      {children}
    </Box>
  )
}

function SectionTitle({ title }: { title: string }) {
  return (
    <Typography variant="subtitle2" sx={{ fontWeight: 600, mb: 1.5, mt: 0.5 }}>
      {title}
    </Typography>
  )
}

// ── Unit structure panel ──────────────────────────────────────────────────────

function floorLabel(u: PropertyUnit): string {
  if (u.floorLevel === 0) return 'EG'
  if (u.floorLevel < 0) return `UG${Math.abs(u.floorLevel)}`
  return `${u.floorLevel}.OG`
}

function MatchPill({ m }: { m: UnitNeedMatch }) {
  const bg = m.matchScore >= 85 ? '#fef3c7' : '#e0e7ff'
  const color = m.matchScore >= 85 ? '#92400e' : '#3730a3'
  return (
    <Tooltip title={`${m.requiredSqmMin}–${m.requiredSqmMax} m² · ${m.matchType === 'partial' ? `Teilfläche ~${m.suggestedSqm} m²` : m.matchType === 'bundle' ? 'Kombination' : 'Passt'}`}>
      <Box sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.5, px: 0.75, py: 0.125, borderRadius: 1, bgcolor: bg, cursor: 'default' }}>
        <Users size={10} color={color} />
        <Typography sx={{ fontSize: '0.63rem', fontWeight: 700, color, lineHeight: 1 }}>
          {m.tenantCompany ?? m.tenantName}
        </Typography>
        <Typography sx={{ fontSize: '0.63rem', color, lineHeight: 1 }}>{m.matchScore}%</Typography>
      </Box>
    </Tooltip>
  )
}

function UnitStructurePanel({ p }: { p: Property }) {
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set())
  const [expandedUnit, setExpandedUnit] = useState<string | null>(null)

  const freeUnits = useMemo(() => (p.units ?? []).filter(u => u.available), [p.units])

  const unitMatches = useMemo(() =>
    Object.fromEntries(freeUnits.map(u => [u.id, unitMatchService.getMatchesForUnit(u, p)])),
    [freeUnits, p],
  )

  const selectedFreeUnits = freeUnits.filter(u => selectedIds.has(u.id))
  const bundle = selectedFreeUnits.length >= 2 ? unitMatchService.buildBundle(selectedFreeUnits) : null
  const bundleMatches = useMemo(() =>
    selectedFreeUnits.length >= 2 ? unitMatchService.getMatchesForBundle(selectedFreeUnits, p) : [],
    [selectedFreeUnits, p],
  )

  const toggleUnit = (id: string) => {
    setSelectedIds(prev => {
      const next = new Set(prev)
      next.has(id) ? next.delete(id) : next.add(id)
      return next
    })
  }

  if (!p.units || p.units.length === 0) return null

  return (
    <>
      <Divider sx={{ my: 2 }} />
      <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 1 }}>
        <Typography variant="body2" sx={{ fontWeight: 700, color: '#0f172a', fontSize: '0.8125rem' }}>
          Stockwerkstruktur
        </Typography>
        {freeUnits.length >= 2 && (
          <Typography variant="caption" sx={{ color: '#64748b', fontSize: '0.7rem' }}>
            Freie Einheiten auswählen zum Kombinieren
          </Typography>
        )}
      </Box>

      <Box sx={{ border: '1px solid #e2e8f0', borderRadius: 1.5, overflow: 'hidden', mb: 1.5 }}>
        {/* Header */}
        <Box sx={{ display: 'grid', gridTemplateColumns: '28px 72px 88px 1fr auto 80px', bgcolor: '#f8fafc', px: 1.5, py: 0.75, borderBottom: '1px solid #e2e8f0', alignItems: 'center' }}>
          {['', 'Stockwerk', 'Einheit', 'Mieter / Status', 'Matches', 'Fläche'].map(h => (
            <Typography key={h} variant="caption" sx={{ fontWeight: 600, color: '#64748b', fontSize: '0.63rem', textTransform: 'uppercase' }}>{h}</Typography>
          ))}
        </Box>

        {p.units!.map((u: PropertyUnit, i: number) => {
          const matches = u.available ? (unitMatches[u.id] ?? []) : []
          const topMatch = matches[0]
          const isExpanded = expandedUnit === u.id
          const isSelected = selectedIds.has(u.id)
          const isLastRow = i === p.units!.length - 1 && !isExpanded

          return (
            <Box key={u.id}>
              <Box
                sx={{
                  display: 'grid',
                  gridTemplateColumns: '28px 72px 88px 1fr auto 80px',
                  px: 1.5,
                  py: 0.875,
                  borderBottom: isLastRow ? 'none' : '1px solid #f1f5f9',
                  alignItems: 'center',
                  bgcolor: isSelected ? '#eff6ff' : 'transparent',
                  transition: 'background 0.15s',
                }}
              >
                {/* Checkbox — only for free units */}
                <Box>
                  {u.available && freeUnits.length >= 2 && (
                    <Checkbox
                      size="small"
                      checked={isSelected}
                      onChange={() => toggleUnit(u.id)}
                      sx={{ p: 0, color: '#94a3b8', '&.Mui-checked': { color: '#2563eb' } }}
                    />
                  )}
                </Box>

                {/* Floor */}
                <Typography variant="caption" sx={{ fontWeight: 600, color: '#0f172a' }}>
                  {floorLabel(u)}
                </Typography>

                {/* Unit label */}
                <Typography variant="caption" sx={{ color: '#374151' }}>{u.unitLabel ?? '–'}</Typography>

                {/* Status */}
                <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, flexWrap: 'wrap' }}>
                  {u.available ? (
                    <>
                      <Chip label="Frei" size="small" sx={{ height: 16, fontSize: '0.6rem', bgcolor: '#f0fdf4', color: '#166534', border: '1px solid #bbf7d0' }} />
                      {u.isFlexible && (
                        <Chip label="Teilfläche möglich" size="small" sx={{ height: 16, fontSize: '0.58rem', bgcolor: '#eff6ff', color: '#1d4ed8', border: '1px solid #bfdbfe' }} />
                      )}
                    </>
                  ) : (
                    <Typography variant="caption" sx={{ color: '#64748b' }} noWrap>{u.currentTenant ?? 'Vermietet'}</Typography>
                  )}
                </Box>

                {/* Top match pill + expand */}
                <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
                  {topMatch && <MatchPill m={topMatch} />}
                  {matches.length > 1 && (
                    <IconButton
                      size="small"
                      onClick={() => setExpandedUnit(isExpanded ? null : u.id)}
                      sx={{ p: 0.25, color: '#94a3b8' }}
                    >
                      {isExpanded ? <ChevronUp size={12} /> : <ChevronDown size={12} />}
                    </IconButton>
                  )}
                </Box>

                {/* Area */}
                <Box sx={{ textAlign: 'right' }}>
                  <Typography variant="caption" sx={{ color: '#374151', fontWeight: u.available ? 600 : 400 }}>
                    {(u.offeredSqm ?? u.areaSqm).toLocaleString('de-CH')} m²
                  </Typography>
                  {u.isFlexible && u.minLettableSqm && (
                    <Typography variant="caption" sx={{ color: '#94a3b8', fontSize: '0.6rem', display: 'block' }}>
                      ab {u.minLettableSqm} m²
                    </Typography>
                  )}
                </Box>
              </Box>

              {/* Expanded: show all matches for this unit */}
              <Collapse in={isExpanded}>
                <Box sx={{ px: 2, py: 1, bgcolor: '#f8fafc', borderBottom: i < p.units!.length - 1 ? '1px solid #e2e8f0' : 'none' }}>
                  <Typography variant="caption" sx={{ fontWeight: 600, color: '#64748b', fontSize: '0.65rem', textTransform: 'uppercase', display: 'block', mb: 0.75 }}>
                    Passende Suchanfragen für diese Einheit
                  </Typography>
                  <Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>
                    {matches.map(m => (
                      <Box key={m.needId} sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                        <MatchPill m={m} />
                        <Typography variant="caption" sx={{ color: '#64748b', fontSize: '0.68rem' }}>
                          {m.requiredSqmMin}–{m.requiredSqmMax} m²
                          {m.matchType === 'partial' && m.suggestedSqm && ` · Teilfläche ~${m.suggestedSqm} m² anbieten`}
                        </Typography>
                      </Box>
                    ))}
                    {matches.length === 0 && (
                      <Typography variant="caption" sx={{ color: '#94a3b8', fontSize: '0.7rem' }}>Keine passenden Suchanfragen</Typography>
                    )}
                  </Box>
                </Box>
              </Collapse>
            </Box>
          )
        })}
      </Box>

      {/* Bundle panel */}
      {bundle && (
        <Box
          sx={{
            border: '1px solid #bfdbfe',
            borderRadius: 1.5,
            bgcolor: '#eff6ff',
            p: 1.5,
            mb: 1.5,
          }}
        >
          <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1 }}>
            <Layers size={14} color="#1d4ed8" />
            <Typography variant="body2" sx={{ fontWeight: 700, color: '#1d4ed8', fontSize: '0.8125rem' }}>
              Kombination: {bundle.label}
            </Typography>
            <Chip
              label={`${bundle.combinedSqm.toLocaleString('de-CH')} m² gesamt`}
              size="small"
              sx={{ bgcolor: '#dbeafe', color: '#1e40af', border: '1px solid #93c5fd', height: 18, fontSize: '0.65rem', ml: 'auto' }}
            />
          </Box>
          <Typography variant="caption" sx={{ color: '#1e40af', fontSize: '0.72rem', display: 'block', mb: 1 }}>
            Diese Einheiten können gemeinsam oder separat vermietet werden.
            {selectedFreeUnits.some(u => u.isFlexible) && ' Flexible Teilflächen möglich — Restfläche bleibt nach Vertragsabschluss verfügbar.'}
          </Typography>
          {bundleMatches.length > 0 ? (
            <Box>
              <Typography variant="caption" sx={{ fontWeight: 600, color: '#64748b', fontSize: '0.63rem', textTransform: 'uppercase', display: 'block', mb: 0.5 }}>
                Passende Suchanfragen für Kombination
              </Typography>
              <Box sx={{ display: 'flex', gap: 0.75, flexWrap: 'wrap' }}>
                {bundleMatches.map(m => <MatchPill key={m.needId} m={m} />)}
              </Box>
            </Box>
          ) : (
            <Typography variant="caption" sx={{ color: '#94a3b8', fontSize: '0.7rem' }}>
              Keine direkt passenden Suchanfragen für diese Kombination
            </Typography>
          )}
        </Box>
      )}
    </>
  )
}

// ── Schattenmarkt release panel ───────────────────────────────────────────────

const MOCK_TODAY = new Date('2026-05-20')

function SchattenmarktReleasePanel({ p }: { p: Property }) {
  const [enabled, setEnabled] = useState(p.schattenmarktRelease?.enabled ?? false)
  const [leadTimeMonths, setLeadTimeMonths] = useState(p.schattenmarktRelease?.leadTimeMonths ?? 6)
  const [saving, setSaving] = useState(false)
  const queryClient = useQueryClient()
  const showToast = useToastStore(s => s.showToast)

  if (p.resultType !== 'VERIFIED_PORTFOLIO') return null
  if (!p.leaseEndDate && !p.breakoutOptionDate) return null

  const candidates: Date[] = []
  if (p.leaseEndDate) {
    const d = new Date(p.leaseEndDate); d.setMonth(d.getMonth() - leadTimeMonths); candidates.push(d)
  }
  if (p.breakoutOption && p.breakoutOptionDate) {
    const d = new Date(p.breakoutOptionDate); d.setMonth(d.getMonth() - leadTimeMonths); candidates.push(d)
  }
  const triggerDate = candidates.length ? candidates.reduce((a, b) => (a < b ? a : b)) : null
  const isActive = triggerDate ? MOCK_TODAY >= triggerDate : false

  const targetDate = (p.breakoutOption && p.breakoutOptionDate)
    ? new Date(p.breakoutOptionDate)
    : p.leaseEndDate ? new Date(p.leaseEndDate) : null
  const monthsUntil = targetDate
    ? Math.max(0, Math.round((targetDate.getTime() - MOCK_TODAY.getTime()) / (1000 * 60 * 60 * 24 * 30)))
    : null

  async function save(nextEnabled: boolean, nextLeadTime: number) {
    setSaving(true)
    try {
      await propertyService.update(p.id, { schattenmarktRelease: { enabled: nextEnabled, leadTimeMonths: nextLeadTime } })
      await queryClient.invalidateQueries({ queryKey: ['property', p.id] })
      await queryClient.invalidateQueries({ queryKey: ['properties'] })
      showToast(nextEnabled ? 'Schattenmarkt-Freigabe aktiviert.' : 'Schattenmarkt-Freigabe deaktiviert.', 'success')
    } catch {
      showToast('Fehler beim Speichern.', 'error')
    } finally {
      setSaving(false)
    }
  }

  function handleToggle(_: React.ChangeEvent<HTMLInputElement>, checked: boolean) {
    setEnabled(checked)
    save(checked, leadTimeMonths)
  }

  function handleLeadTime(months: number) {
    setLeadTimeMonths(months)
    if (enabled) save(enabled, months)
  }

  return (
    <>
      <Divider sx={{ my: 2 }} />
      <SectionTitle title="Schattenmarkt" />
      <Box
        sx={{
          border: '1px solid',
          borderColor: enabled ? '#8b5cf6' : '#e2e8f0',
          borderRadius: 1.5,
          p: 1.75,
          bgcolor: enabled ? '#faf5ff' : 'transparent',
          transition: 'background 0.2s, border-color 0.2s',
        }}
      >
        <Box sx={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' }}>
          <Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 1 }}>
            <Zap size={15} color={enabled ? '#7c3aed' : '#94a3b8'} style={{ marginTop: 2 }} />
            <Box>
              <Typography variant="body2" sx={{ fontWeight: 600, lineHeight: 1.3 }}>
                Für Schattenmarkt freigeben
              </Typography>
              <Typography variant="caption" color="text.secondary">
                Nachfragesuchende sehen dieses Objekt vor Vertragsende im Feed
              </Typography>
            </Box>
          </Box>
          <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, ml: 1, flexShrink: 0 }}>
            {saving && <CircularProgress size={12} sx={{ color: '#7c3aed' }} />}
            <Switch
              checked={enabled}
              onChange={handleToggle}
              size="small"
              sx={{
                '& .MuiSwitch-switchBase.Mui-checked': { color: '#7c3aed' },
                '& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': { bgcolor: '#8b5cf6' },
              }}
            />
          </Box>
        </Box>

        {enabled && (
          <Box sx={{ mt: 1.5 }}>
            <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1.25 }}>
              <Typography variant="caption" sx={{ color: '#374151', fontWeight: 500, minWidth: 72 }}>
                Lead Time
              </Typography>
              <Box sx={{ display: 'flex', gap: 0.5, flexWrap: 'wrap' }}>
                {[3, 4, 5, 6, 8, 12].map(m => (
                  <Chip
                    key={m}
                    label={`${m} M`}
                    size="small"
                    onClick={() => handleLeadTime(m)}
                    sx={{
                      height: 20, fontSize: '0.68rem', cursor: 'pointer',
                      bgcolor: leadTimeMonths === m ? '#7c3aed' : '#f1f5f9',
                      color: leadTimeMonths === m ? 'white' : '#374151',
                      '&:hover': { bgcolor: leadTimeMonths === m ? '#6d28d9' : '#e2e8f0' },
                    }}
                  />
                ))}
              </Box>
            </Box>

            <Box
              sx={{
                display: 'flex', alignItems: 'flex-start', gap: 0.75, p: 1,
                borderRadius: 1, border: '1px solid',
                bgcolor: isActive ? '#f0fdf4' : '#fff7ed',
                borderColor: isActive ? '#bbf7d0' : '#fed7aa',
              }}
            >
              {isActive
                ? <ShieldCheck size={13} color="#166534" style={{ marginTop: 1, flexShrink: 0 }} />
                : <Clock size={13} color="#92400e" style={{ marginTop: 1, flexShrink: 0 }} />
              }
              <Typography variant="caption" sx={{ color: isActive ? '#166534' : '#92400e', fontWeight: 500, lineHeight: 1.4 }}>
                {isActive
                  ? `Signal aktiv seit ${triggerDate?.toLocaleDateString('de-CH')} — Objekt im Nachfrage-Feed sichtbar`
                  : triggerDate
                    ? `Signal aktiv ab ${triggerDate.toLocaleDateString('de-CH')} — noch ${monthsUntil} Monate bis Vertragsende`
                    : 'Kein Vertragsende hinterlegt'
                }
              </Typography>
            </Box>
          </Box>
        )}

        {!enabled && (
          <Typography variant="caption" color="text.secondary" sx={{ display: 'block', mt: 1 }}>
            Wenn aktiviert, erscheint dieses Objekt {leadTimeMonths} Monate vor Vertragsende als
            verifiziertes Schattenmarkt-Signal im Nachfrage-Feed.
          </Typography>
        )}
      </Box>
    </>
  )
}

// ── Übersicht tab ─────────────────────────────────────────────────────────────

interface OverviewPanelProps {
  p: Property
  editing: boolean
  draft: UpdatePropertyInput
  onDraftChange: (d: UpdatePropertyInput) => void
}

function OverviewPanel({ p, editing, draft, onDraftChange }: OverviewPanelProps) {
  const rentLabel = p.rentPricePerSqm > 0 ? `CHF ${p.rentPricePerSqm.toLocaleString('de-CH')}` : undefined

  return (
    <Box>
      {/* Key metrics */}
      <Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 1.5, mb: 0.75 }}>
        {[
          { label: 'Fläche', value: `${p.areaSqm.toLocaleString('de-CH')} m²` },
          { label: 'CHF/m²/Jahr', value: rentLabel },
          { label: 'Verfügbar ab', value: p.availabilityDate ? new Date(p.availabilityDate).toLocaleDateString('de-CH') : undefined },
        ].map(({ label, value }) => (
          <Box key={label} sx={{ p: 1.5, border: '1px solid', borderColor: 'divider', borderRadius: 1 }}>
            <Typography variant="caption" color="text.secondary">{label}</Typography>
            <Typography variant="body1" sx={{ fontWeight: 700, mt: 0.25 }}>
              {value ?? <span style={{ color: '#94a3b8' }}>k.A.</span>}
            </Typography>
          </Box>
        ))}
      </Box>
      {p.propertyNumber && (
        <Typography variant="caption" sx={{ color: '#94a3b8', mb: 2, display: 'block' }}>
          Objekt-Nr. {p.propertyNumber}
        </Typography>
      )}

      {/* Description */}
      {editing ? (
        <Box sx={{ mb: 2 }}>
          <SectionTitle title="Beschreibung" />
          <TextField
            multiline
            rows={3}
            fullWidth
            size="small"
            value={draft.description ?? p.description ?? ''}
            onChange={e => onDraftChange({ ...draft, description: e.target.value })}
            placeholder="Beschreibung des Objekts…"
          />
        </Box>
      ) : p.description ? (
        <Box sx={{ mb: 2 }}>
          <SectionTitle title="Beschreibung" />
          <Typography variant="body2" sx={{ lineHeight: 1.6, color: 'text.secondary' }}>
            {p.description}
          </Typography>
        </Box>
      ) : null}

      {/* Lease & Tenant */}
      <SectionTitle title="Miet- & Mieterinformationen" />
      {editing ? (
        <Box sx={{ mb: 2 }}>
          <Box sx={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 1.5, mb: 1 }}>
            <TextField
              label="Aktueller Mieter"
              size="small"
              value={draft.currentTenant ?? p.currentTenant ?? ''}
              onChange={e => onDraftChange({ ...draft, currentTenant: e.target.value })}
            />
            <TextField
              label="Mietlaufzeit"
              size="small"
              value={draft.leaseTerm ?? p.leaseTerm ?? ''}
              onChange={e => onDraftChange({ ...draft, leaseTerm: e.target.value })}
              placeholder="z.B. 5 Jahre"
            />
            <TextField
              label="Mietbeginn"
              size="small"
              type="date"
              slotProps={{ inputLabel: { shrink: true } }}
              value={draft.leaseStartDate ?? p.leaseStartDate ?? ''}
              onChange={e => onDraftChange({ ...draft, leaseStartDate: e.target.value })}
            />
            <TextField
              label="Mietende"
              size="small"
              type="date"
              slotProps={{ inputLabel: { shrink: true } }}
              value={draft.leaseEndDate ?? p.leaseEndDate ?? ''}
              onChange={e => onDraftChange({ ...draft, leaseEndDate: e.target.value })}
            />
          </Box>
        </Box>
      ) : (
        <FieldGrid>
          <Field label="Aktueller Mieter" value={p.currentTenant} />
          <Field label="Mietlaufzeit" value={p.leaseTerm} />
          <Field label="Mietbeginn" value={p.leaseStartDate ? new Date(p.leaseStartDate).toLocaleDateString('de-CH') : undefined} />
          <Field label="Mietende" value={p.leaseEndDate ? new Date(p.leaseEndDate).toLocaleDateString('de-CH') : undefined} />
          <Field label="Breakoutoption" value={p.breakoutOption} />
          <Field label="Breakoutoption Zeitpunkt" value={p.breakoutOptionDate ? new Date(p.breakoutOptionDate).toLocaleDateString('de-CH') : undefined} />
          <Field label="Importiert aus" value={p.importedFrom} />
          <Field label="Zuletzt aktualisiert" value={p.lastUpdatedAt ? new Date(p.lastUpdatedAt).toLocaleDateString('de-CH') : undefined} />
        </FieldGrid>
      )}

      {/* Floor / unit structure */}
      <UnitStructurePanel p={p} />

      {/* Schattenmarkt release */}
      <SchattenmarktReleasePanel p={p} />

      <Divider sx={{ my: 2 }} />

      {/* Object details */}
      <SectionTitle title="Objekt & Lage" />
      <FieldGrid>
        {p.propertyNumber && <Field label="Objekt-Nr." value={p.propertyNumber} />}
        <Field label="Objekttyp" value={getAssetTypeLabel(p.assetType)} />
        <Field label="Etage" value={p.hardFacts?.floor ?? p.floorLevel} />
        <Field label="Ausbaustandard" value={p.hardFacts?.fitOut} />
        <Field label="Parkplätze" value={p.hardFacts?.parking ?? p.softFactors?.parkingSpots} />
        <Field label="ÖV (Min.)" value={p.softFactors?.publicTransportMinutes} />
        <Field label="Nebenkosten/m²" value={p.ancillaryCosts ? `CHF ${p.ancillaryCosts}` : undefined} />
      </FieldGrid>

      {/* Map */}
      {p.location.coordinates && (
        <Box sx={{ mb: 2.5, mt: 1.5, borderRadius: 1, overflow: 'hidden', border: '1px solid #e2e8f0' }}>
          <Box sx={{ px: 1.5, pt: 1.25, pb: 0.75 }}>
            <Typography variant="caption" sx={{ fontWeight: 600, color: '#64748b', textTransform: 'uppercase', letterSpacing: 0.5 }}>
              Standort
            </Typography>
            <Typography variant="caption" color="text.secondary" sx={{ display: 'block' }}>
              {p.address.street} {p.address.houseNumber}, {p.address.postalCode} {p.address.city}
            </Typography>
          </Box>
          <PropertyMap
            lat={p.location.coordinates.lat}
            lng={p.location.coordinates.lng}
            label={p.title}
            height={160}
          />
        </Box>
      )}

      <Divider sx={{ my: 1.5 }} />

      {/* Data quality */}
      <SectionTitle title="Datenqualität" />
      <Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 0.5 }}>
        <Typography variant="body2" color="text.secondary">Score</Typography>
        <Typography variant="body2" sx={{ fontWeight: 600 }}>{Math.round(p.dataQuality.score * 100)}%</Typography>
      </Box>
      <LinearProgress
        variant="determinate"
        value={p.dataQuality.score * 100}
        color={qualityColor(p.dataQuality.score)}
        sx={{ height: 8, borderRadius: 4, mb: 1 }}
      />
      {p.dataQuality.warnings.length > 0 && (
        <Box sx={{ mt: 1 }}>
          {p.dataQuality.warnings.map((w, i) => (
            <Typography key={i} variant="caption" sx={{ display: 'block', color: 'warning.main' }}>⚠ {w}</Typography>
          ))}
        </Box>
      )}
    </Box>
  )
}

// ── Matchability tab ──────────────────────────────────────────────────────────

function MatchabilityTabPanel({ propertyId }: { propertyId: string }) {
  const [matches, setMatches] = useState<PropertyNeedMatch[]>([])
  const [loading, setLoading] = useState(true)
  const navigate = useNavigate()
  const setSelectedProperties = useOfferWizardStore(s => s.setSelectedProperties)

  useEffect(() => {
    let cancelled = false
    setLoading(true)
    matchService.getNeedMatchesForProperty(propertyId, { minScore: 80 }).then(result => {
      if (!cancelled) { setMatches(result); setLoading(false) }
    })
    return () => { cancelled = true }
  }, [propertyId])

  function handleNeedCardClick() {
    setSelectedProperties([propertyId])
    navigate('/supply/anfragen', { state: { tab: 1 } })
  }

  if (loading) {
    return (
      <Box sx={{ p: 3, display: 'flex', justifyContent: 'center' }}>
        <CircularProgress size={24} />
      </Box>
    )
  }

  return (
    <Box sx={{ p: 2.5 }}>
      <Box sx={{ mb: 2 }}>
        <Typography variant="subtitle2" sx={{ fontWeight: 700, color: '#0f172a' }}>
          Matchability
        </Typography>
        <Typography variant="caption" color="text.secondary">
          Bedarfsprofile mit ≥ 80% Match-Score — Karte klicken um Angebot zu erstellen
        </Typography>
      </Box>
      {matches.length === 0 ? (
        <Alert severity="info" sx={{ fontSize: '0.8125rem' }}>
          Keine Bedarfsprofile mit ≥ 80% Match-Score für dieses Objekt gefunden.
        </Alert>
      ) : (
        matches.map(m => <NeedMatchCard key={m.matchId} match={m} onClick={handleNeedCardClick} />)
      )}
    </Box>
  )
}

// ── Main component ────────────────────────────────────────────────────────────

const TABS = ['Übersicht', 'Matchability', 'Marktsignale'] as const

export function PropertyDetailView({ propertyId, onClose }: PropertyDetailViewProps) {
  const [tab, setTab] = useState(0)
  const [editing, setEditing] = useState(false)
  const [draft, setDraft] = useState<UpdatePropertyInput>({})
  const [saving, setSaving] = useState(false)
  const queryClient = useQueryClient()
  const { data: property, isLoading } = usePropertyById(propertyId)
  const showToast = useToastStore(s => s.showToast)

  function startEdit() {
    setDraft({})
    setEditing(true)
  }

  async function saveEdit() {
    if (!property) return
    setSaving(true)
    try {
      await propertyService.update(property.id, draft)
      await queryClient.invalidateQueries({ queryKey: ['property', propertyId] })
      setEditing(false)
      setDraft({})
      showToast('Objekt gespeichert.', 'success')
    } catch {
      showToast('Fehler beim Speichern.', 'error')
    } finally {
      setSaving(false)
    }
  }

  if (isLoading) return <PropertyDetailSkeleton />
  if (!property) {
    return (
      <Box sx={{ p: 3 }}>
        <Alert severity="error">Objekt nicht gefunden.</Alert>
      </Box>
    )
  }

  const isLowQuality = property.dataQuality.score < 0.6
  const hasCriticalGaps = property.dataQuality.missingCriticalFields.length > 0

  return (
    <Box sx={{ height: '100%', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      {/* Header */}
      <Box sx={{ p: 2.5, borderBottom: '1px solid #e2e8f0', flexShrink: 0 }}>
        <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', mb: 1 }}>
          <Box sx={{ display: 'flex', gap: 0.75, flexWrap: 'wrap' }}>
            <Chip
              label={getAssetTypeLabel(property.assetType)}
              size="small"
              sx={{ bgcolor: getAssetTypeColor(property.assetType), color: 'white', fontSize: '0.68rem' }}
            />
            <Chip
              label={getAvailabilityLabel(property.availabilityStatus)}
              size="small"
              color={getAvailabilityChipColor(property.availabilityStatus)}
              variant="outlined"
            />
          </Box>
          <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5, ml: 1 }}>
            {tab === 0 && !editing && (
              <IconButton size="small" onClick={startEdit} title="Bearbeiten">
                <Edit2 size={15} />
              </IconButton>
            )}
            {tab === 0 && editing && (
              <>
                <Button
                  size="small"
                  variant="contained"
                  startIcon={saving ? <CircularProgress size={12} sx={{ color: 'white' }} /> : <Save size={13} />}
                  onClick={saveEdit}
                  disabled={saving}
                  sx={{ textTransform: 'none', fontSize: '0.75rem', bgcolor: '#1e3a5f', '&:hover': { bgcolor: '#16304d' } }}
                >
                  Speichern
                </Button>
                <Button
                  size="small"
                  onClick={() => { setEditing(false); setDraft({}) }}
                  sx={{ textTransform: 'none', fontSize: '0.75rem' }}
                >
                  Abbrechen
                </Button>
              </>
            )}
            {onClose && (
              <IconButton size="small" onClick={onClose}>
                <X size={16} />
              </IconButton>
            )}
          </Box>
        </Box>

        <Typography variant="h6" sx={{ fontWeight: 600, lineHeight: 1.3, mb: 0.25 }}>
          {property.title}
        </Typography>
        <Typography variant="caption" color="text.secondary">
          {property.address.street} {property.address.houseNumber}, {property.address.postalCode} {property.address.city}
        </Typography>

        {isLowQuality && (
          <Alert severity="warning" sx={{ mt: 1, py: 0.25, fontSize: '0.75rem' }}>
            Niedrige Datenqualität ({Math.round(property.dataQuality.score * 100)}%) — Angaben können unvollständig sein.
          </Alert>
        )}
        {hasCriticalGaps && !isLowQuality && (
          <Alert severity="warning" sx={{ mt: 1, py: 0.25, fontSize: '0.75rem' }}>
            Kritische Felder fehlen: {property.dataQuality.missingCriticalFields.slice(0, 3).join(', ')}
          </Alert>
        )}
      </Box>

      {/* Photo */}
      {property.images?.[0] && (
        <Box sx={{ flexShrink: 0, height: 160, overflow: 'hidden' }}>
          <img
            src={property.images[0]}
            alt={property.title}
            style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
          />
        </Box>
      )}

      {/* Tabs */}
      <Tabs
        value={tab}
        onChange={(_, v) => setTab(v)}
        sx={{
          borderBottom: '1px solid #e2e8f0',
          flexShrink: 0,
          '& .MuiTab-root': { textTransform: 'none', fontSize: '0.8rem', minWidth: 'auto', px: 2 },
        }}
      >
        {TABS.map(label => (
          <Tab key={label} label={label} />
        ))}
      </Tabs>

      {/* Tab content */}
      <Box sx={{ flex: 1, overflowY: 'auto', p: tab === 0 ? 2.5 : 0 }}>
        {tab === 0 && (
          <OverviewPanel
            p={property}
            editing={editing}
            draft={draft}
            onDraftChange={setDraft}
          />
        )}
        {tab === 1 && <MatchabilityTabPanel propertyId={propertyId} />}
        {tab === 2 && <PropertyMarketSignalsTab propertyId={propertyId} />}
      </Box>
    </Box>
  )
}
