// ── Rentable Unit — primary entity for demand-side matching ──────────────────
//
// A Property is the building/address container (Liegenschaft).
// A PropertyUnit is what is actually rented: a specific floor, wing, or section (Mietobjekt).
// Floor level is an attribute of the unit — not a separate entity (matches Garaio REM / SAP RE-FX).
// Tenant and contract data live on Lease, not directly on the unit.

import type { Lease } from './lease'
import type { AvailabilityStatus } from './enums'
import { AvailabilityStatus as AS } from './enums'

export interface PropertyUnit {
  id: string
  propertyId?: string       // FK to parent Property (Liegenschaft)
  floorLevel: number        // 0=EG, 1=1.OG, -1=UG1
  unitLabel?: string        // e.g. "Nord", "West", "Einheit A"
  areaSqm: number
  available: boolean
  rentPricePerSqm?: number  // annual CHF/m²; falls back to property.rentPricePerSqm
  availableFrom?: string    // explicit availability date for a free unit (ISO); else derived from leases
  // Unit-level overrides — fall back to property.hardFacts.* when unset.
  // Relevant where units of one property are matched individually (pre-market, multi-unit).
  fitOut?: 'SHELL' | 'BASIC' | 'FULL' | 'PREMIUM'
  fitOutByLandlord?: boolean          // wer trägt den Ausbau (Default: Objekt-Wert)
  mieterausbaubeitragPerSqm?: number  // MAB der Einheit (Default: Objekt-Wert)
  parkingSpots?: number               // aus dem Objekt-Pool zugeteilte Parkplätze
  expectedRentPerSqm?: number         // erwarteter künftiger Preis (Pre-Market), ≠ heutige Sollmiete
  leases?: Lease[]          // Mietverträge — current, historical, future
  /** @deprecated Use leases[].tenant.companyName */
  currentTenant?: string
  /** @deprecated Use leases[].endDate */
  leaseEndDate?: string
  /** @deprecated Use leases[0].contractDurationYears */
  leaseTerm?: string
  floorPlanUrl?: string
  // Flexible letting (Teilfläche)
  isFlexible?: boolean
  minLettableSqm?: number
  offeredSqm?: number       // currently offered area (≤ areaSqm)
  // Unit-level pre-market release
  schattenmarktRelease?: {
    enabled: boolean
    availableFrom?: string  // ISO date
    anonymous?: boolean     // hide address/name in pre-market feed
  }
}

// Derives availability from the unit's lease list.
// Use this instead of reading property.availabilityStatus directly.
export function getUnitAvailability(unit: PropertyUnit): {
  status: AvailabilityStatus
  availableFrom?: string
  activeLease?: Lease
} {
  const active = unit.leases?.find(l => l.status === 'ACTIVE')
  if (!active) return { status: AS.AVAILABLE_NOW }
  const now = new Date()
  const monthsToEnd = (new Date(active.endDate).getTime() - now.getTime()) / (1000 * 60 * 60 * 24 * 30)
  if (monthsToEnd <= 12) {
    return { status: AS.AVAILABLE_SOON, availableFrom: active.endDate, activeLease: active }
  }
  return { status: AS.OCCUPIED, activeLease: active }
}

// A bundle groups multiple free units into a combined offer
export interface UnitBundle {
  unitIds: string[]
  combinedSqm: number
  label: string             // e.g. "1.OG + 2.OG"
}

// Result of unit-level need matching (used in supply-side detail views)
export interface UnitNeedMatch {
  needId: string
  tenantName: string
  tenantCompany?: string
  requiredSqmMin: number
  requiredSqmMax: number
  matchScore: number
  matchType: 'exact' | 'partial' | 'bundle'
  suggestedSqm?: number
}

// ── Display helpers ───────────────────────────────────────────────────────────

export function formatFloorLabel(level: number): string {
  if (level === 0) return 'EG'
  if (level < 0) return `UG${Math.abs(level)}`
  return `${level}.OG`
}

/** Returns the primary display title for a specific unit: "1.OG Nord · Zollstrasse 12" */
export function formatUnitTitle(
  unit: PropertyUnit,
  address: { street: string; houseNumber: string },
): string {
  const floor = formatFloorLabel(unit.floorLevel)
  const label = unit.unitLabel ? ` ${unit.unitLabel}` : ''
  return `${floor}${label} · ${address.street} ${address.houseNumber}`
}

/** Returns a compact floor-range string for multi-unit properties: "1.OG–3.OG" or "EG · 1.OG" */
export function formatMultiUnitFloors(units: PropertyUnit[]): string {
  const floors = [...new Set(units.map(u => u.floorLevel))].sort((a, b) => a - b)
  if (floors.length === 0) return ''
  if (floors.length === 1) return formatFloorLabel(floors[0])
  if (floors.length === 2) return `${formatFloorLabel(floors[0])} · ${formatFloorLabel(floors[1])}`
  return `${formatFloorLabel(floors[0])}–${formatFloorLabel(floors[floors.length - 1])}`
}
