import type {
  UnifiedMatchResult,
  VerifiedPortfolioResult,
  ExternalMarketResult,
  FutureAvailabilityResult,
} from '../../domain/unifiedResult'
import type { ScoreFactor } from '../../domain/match'
import type {
  MatchCardViewModel,
  MatchCardAction,
  MatchCardReason,
} from '../../components/match-card/MatchCardViewModel'

const HARD_CRITERIA = new Set(['area', 'location', 'budget', 'timing'])

function buildReasons(positiveFactors: ScoreFactor[]): MatchCardReason[] {
  const reasons: MatchCardReason[] = []

  const hardFact = positiveFactors.find(f => HARD_CRITERIA.has(f.criterion))
  const softFact = positiveFactors.find(f => !HARD_CRITERIA.has(f.criterion))

  if (hardFact) {
    reasons.push({
      type: 'HARD_FACT',
      label: capitalize(hardFact.criterion),
      explanation: hardFact.explanation,
      score: hardFact.score,
    })
  }
  if (softFact) {
    reasons.push({
      type: 'SOFT_FACTOR',
      label: capitalize(softFact.criterion),
      explanation: softFact.explanation,
      score: softFact.score,
    })
  }

  return reasons
}

function capitalize(s: string): string {
  return s.charAt(0).toUpperCase() + s.slice(1)
}

export function buildMatchCardViewModel(
  result: UnifiedMatchResult,
  actions: MatchCardAction[],
): MatchCardViewModel {
  const { match, matchScore, resultType } = result

  const isFuture = resultType === 'FUTURE_AVAILABILITY'
  const property = !isFuture
    ? (result as VerifiedPortfolioResult | ExternalMarketResult).property
    : undefined
  const signal = isFuture
    ? (result as FutureAvailabilityResult).signal
    : undefined

  const city = property?.location?.city
  const district = property?.location?.district
  const locationLabel = city
    ? `${city}${district ? `, ${district}` : ''}`
    : signal?.locationHint ?? '–'

  const availabilityLabel =
    property?.availabilityDate ??
    (signal?.timeHorizonMonths ? `~${signal.timeHorizonMonths} Monate` : undefined)

  const sourceLabel =
    property?.sourceLabel ??
    property?.sourceMeta?.sourceLabel ??
    property?.sourceMeta?.sourceType

  const externalUrl = property?.sourceUrl ?? property?.sourceMeta?.sourceUrl

  const reasons = buildReasons(match.positiveFactors)

  const dataQualityScore =
    property?.dataQuality?.score ?? signal?.confidenceScore ?? 0.5

  return {
    id: result.matchId,
    title:
      property?.title ??
      signal?.companyName ??
      signal?.locationHint ??
      '–',
    resultType,
    assetType: property?.assetType,
    matchScore,
    confidenceScore: match.confidenceLevel,
    dataQualityScore,
    locationLabel,
    availabilityLabel,
    sourceLabel,
    externalUrl,
    reasons,
    tradeoffs: match.tradeoffs ?? [],
    risks: match.risks ?? [],
    missingData: match.missingData ?? [],
    actions,
    disclaimer: isFuture
      ? (signal?.disclaimer ?? 'Probabilistisches Signal – kein bestätigtes Objekt')
      : undefined,
    explainabilitySummary: match.explainabilitySummary,
    isReviewRequired: match.status === 'PENDING_REVIEW',
    isStaleData: false,
  }
}
