import type {
  AssetType, ResultType, AvailabilityStatus, AvailabilityType,
  FreshnessStatus, RiskLevel, SourceType, DataQualityLevel,
} from './enums'
import { AvailabilityStatus as AS } from './enums'
import type { PropertyUnit } from './unit'
import type { Lease } from './lease'

// Re-export unit types so all existing imports from 'property' continue to work
export type { PropertyUnit, UnitBundle, UnitNeedMatch } from './unit'

// ── Location / Address ────────────────────────────────────────────────────────

export interface Location {
  city: string
  district?: string
  canton?: string
  region?: string
  country: string
  coordinates?: { lat: number; lng: number }
}

export interface Address {
  street: string
  houseNumber: string
  postalCode: string
  city: string
  country: string
}

// ── Source Metadata ───────────────────────────────────────────────────────────

export interface SourceMeta {
  sourceType: SourceType | string
  sourceLabel?: string
  sourceUrl?: string
  sourceUpdatedAt?: string
  externalId?: string
}

// ── Data Quality ──────────────────────────────────────────────────────────────

export interface DataQuality {
  score: number
  qualityLevel?: DataQualityLevel
  missingCriticalFields: string[]
  missingOptionalFields: string[]
  lastVerifiedAt?: string
  freshness: FreshnessStatus
  warnings: string[]
}

// ── Hard Facts ────────────────────────────────────────────────────────────────

export interface PropertyHardFacts {
  floor?: number
  fitOut?: 'SHELL' | 'BASIC' | 'FULL' | 'PREMIUM'
  mieterausbaubeitragPerSqm?: number
  /** true = Vermieter übernimmt den Ausbau & preist ihn in die Miete ein (kein Aufschlag, kein MAB). */
  fitOutByLandlord?: boolean
  parking?: number
  publicTransportScore?: number
  usageType?: string
  ceilingHeightM?: number
  loadingDocksCount?: number
  powerSupplyKva?: number
  hasServerRoom?: boolean
  isBarrierFree?: boolean
  hasAirConditioning?: boolean
  hasStorefront?: boolean
}

// ── Soft Factors ──────────────────────────────────────────────────────────────

export interface SoftFactors {
  prestigeScore?: number
  visibilityScore?: number
  footfallScore?: number
  commuterAccessScore?: number
  talentAccessScore?: number
  esgScore?: number
  flexibilityScore?: number
  expansionPotentialScore?: number
  taxEnvironmentScore?: number
  // Legacy aliases kept for mock-data backward compatibility
  prestige?: number
  accessibility?: number
  talentAccess?: number
  esgRating?: string
  passerbyFrequency?: 'LOW' | 'MEDIUM' | 'HIGH' | 'VERY_HIGH'
  parkingSpots?: number
  publicTransportMinutes?: number
  infrastructureNotes?: string
}

// ── Property ──────────────────────────────────────────────────────────────────

export interface Property {
  id: string
  organizationId?: string
  title: string

  assetType: AssetType
  resultType: ResultType

  location: Location
  address: Address

  areaSqm: number
  areaSqmMin?: number
  areaSqmMax?: number

  rentPricePerSqm: number
  rentChfSqmYear?: number
  totalRentMonthly?: number
  ancillaryCosts?: number

  availabilityDate: string
  availabilityStatus: AvailabilityStatus
  availabilityType?: AvailabilityType

  sourceType: string
  sourceLabel?: string
  sourceUrl?: string
  sourceUpdatedAt?: string
  sourceMeta?: SourceMeta

  confidenceScore: number
  dataQuality: DataQuality

  softFactors?: SoftFactors
  hardFacts?: PropertyHardFacts

  // Legacy fields — kept for backward compat
  floorLevel?: number
  expansionPotentialSqm?: number

  contractDurationMonths?: number
  riskLevel?: RiskLevel
  description?: string
  images?: string[]
  floorPlanUrl?: string
  /** @deprecated Use unit.leases[].contractDocumentUrl instead */
  leaseContractUrl?: string
  /** @deprecated Use unit.leases[].contractDocumentName instead */
  leaseContractName?: string

  propertyNumber?: string
  units?: PropertyUnit[]
  mapImageUrl?: string

  /** @deprecated Use unit.leases instead */
  leaseTerm?: string
  /** @deprecated Use unit.leases[].startDate instead */
  leaseStartDate?: string
  /** @deprecated Use unit.leases[].endDate instead */
  leaseEndDate?: string
  /** @deprecated Use unit.leases[].breakoutOption instead */
  breakoutOption?: boolean
  /** @deprecated Use unit.leases[].breakoutOptionDate instead */
  breakoutOptionDate?: string
  /** @deprecated Use unit.leases[].tenant.companyName instead */
  currentTenant?: string
  importedFrom?: string
  importedAt?: string
  lastUpdatedAt?: string

  schattenmarktRelease?: { enabled: boolean; leadTimeMonths?: number; anonymous?: boolean }

  status?: 'ACTIVE' | 'INACTIVE' | 'DRAFT' | 'ARCHIVED'
  lastReviewedAt?: string
  createdAt: string
  updatedAt: string
}

export type CreatePropertyInput = Omit<Property, 'id' | 'createdAt' | 'updatedAt'>
export type UpdatePropertyInput = Partial<CreatePropertyInput>

/**
 * Returns the rentable units of a property.
 * For properties without explicit units, synthesises one unit from property-level data
 * so that all matching logic can operate uniformly at unit level.
 * Property-level lease fields are synthesised into a proper Lease object for backward compat.
 */
export function getEffectiveUnits(p: Property): PropertyUnit[] {
  if (p.units && p.units.length > 0) return p.units

  const syntheticLease: Lease | undefined = p.currentTenant
    ? {
        id: `${p.id}-lease`,
        unitId: p.id,
        tenant: { id: `${p.id}-tenant`, companyName: p.currentTenant },
        rentPerSqm: p.rentPricePerSqm,
        startDate: p.leaseStartDate ?? '',
        endDate: p.leaseEndDate ?? '',
        contractDurationYears: p.contractDurationMonths ? Math.round(p.contractDurationMonths / 12) : undefined,
        breakoutOption: p.breakoutOption,
        breakoutOptionDate: p.breakoutOptionDate,
        status: p.leaseEndDate && new Date(p.leaseEndDate) > new Date() ? 'ACTIVE' : 'EXPIRED',
        sourceSystem: p.importedFrom ?? 'MANUAL',
        contractDocumentUrl: p.leaseContractUrl,
        contractDocumentName: p.leaseContractName,
      }
    : undefined

  return [{
    id: p.id,
    propertyId: p.id,
    floorLevel: p.hardFacts?.floor ?? p.floorLevel ?? 0,
    unitLabel: undefined,
    areaSqm: p.areaSqm,
    available: p.availabilityStatus === AS.AVAILABLE_NOW || p.availabilityStatus === AS.AVAILABLE_SOON,
    rentPricePerSqm: p.rentPricePerSqm,
    leases: syntheticLease ? [syntheticLease] : [],
    schattenmarktRelease: p.schattenmarktRelease?.enabled
      ? { enabled: true, availableFrom: p.leaseEndDate }
      : undefined,
  }]
}
