import { describe, it, expect } from 'vitest'
import { buildMatchCardViewModel } from '../matchCardAdapter'
import { buildFullMatch } from '../rankingEngine'
import { ResultType } from '../../../domain/enums'
import type { VerifiedPortfolioResult, FutureAvailabilityResult } from '../../../domain/unifiedResult'
import type { FutureSignal } from '../../../domain/futureSignal'
import { makeNeed, makeProperty } from './fixtures'

// ── buildMatchCardViewModel — verified portfolio ──────────────────────────────

describe('buildMatchCardViewModel — VERIFIED_PORTFOLIO', () => {
  const need = makeNeed()
  const property = makeProperty()
  const match = buildFullMatch(need, property)

  const result: VerifiedPortfolioResult = {
    matchId: 'vm-test-1',
    needId: need.id,
    matchScore: match.matchScore,
    resultType: 'VERIFIED_PORTFOLIO',
    property,
    match,
  }

  it('sets resultType correctly', () => {
    const vm = buildMatchCardViewModel(result, [])
    expect(vm.resultType).toBe('VERIFIED_PORTFOLIO')
  })

  it('uses property title as the card title', () => {
    const vm = buildMatchCardViewModel(result, [])
    expect(vm.title).toBe(property.title)
  })

  it('builds locationLabel from city (and district when present)', () => {
    const vm = buildMatchCardViewModel(result, [])
    expect(vm.locationLabel).toContain('Zürich')
  })

  it('propagates matchScore from the result', () => {
    const vm = buildMatchCardViewModel(result, [])
    expect(vm.matchScore).toBe(match.matchScore)
  })

  it('scoreBreakdown reflects hard and soft components from the engine', () => {
    const vm = buildMatchCardViewModel(result, [])
    expect(vm.scoreBreakdown!.hardMatchScore).toBe(match.scoreBreakdown.hardMatchScore)
    expect(vm.scoreBreakdown!.softFactorScore).toBe(match.scoreBreakdown.softFactorScore)
    expect(vm.scoreBreakdown!.totalScore).toBe(match.scoreBreakdown.totalScore)
  })

  it('does NOT set a disclaimer for verified portfolio results', () => {
    const vm = buildMatchCardViewModel(result, [])
    expect(vm.disclaimer).toBeUndefined()
  })

  it('returns reasons derived from top positive factors', () => {
    const vm = buildMatchCardViewModel(result, [])
    // A high-scoring match should have at least one reason
    expect(vm.reasons.length).toBeGreaterThan(0)
    vm.reasons.forEach(r => {
      expect(r.type).toMatch(/HARD_FACT|SOFT_FACTOR/)
      expect(r.score).toBeGreaterThanOrEqual(0)
    })
  })

  it('passes through supplied actions unchanged', () => {
    const actions = [{ id: 'shortlist', label: 'Shortlist', actionType: 'SAVE_SHORTLIST' as const, primary: true, onClick: () => {} }]
    const vm = buildMatchCardViewModel(result, actions)
    expect(vm.actions).toBe(actions)
  })
})

// ── buildMatchCardViewModel — future availability ─────────────────────────────

describe('buildMatchCardViewModel — FUTURE_AVAILABILITY', () => {
  const need = makeNeed()
  const futureProperty = makeProperty({ resultType: ResultType.FUTURE_AVAILABILITY })
  const match = buildFullMatch(need, futureProperty)

  const minimalSignal = {
    id: 'sig-1',
    probability: 0.72,
    locationHint: 'Zürich Oerlikon',
    isVerified: false,
    source: { type: 'AI_SIGNAL', credibility: 0.7 },
  } as unknown as FutureSignal

  const futureResult: FutureAvailabilityResult = {
    matchId: 'future-test-1',
    needId: need.id,
    matchScore: match.matchScore,
    resultType: 'FUTURE_AVAILABILITY',
    signal: minimalSignal,
    property: futureProperty,
    match,
  }

  it('sets resultType to FUTURE_AVAILABILITY', () => {
    const vm = buildMatchCardViewModel(futureResult, [])
    expect(vm.resultType).toBe('FUTURE_AVAILABILITY')
  })

  it('always includes a disclaimer for future signals', () => {
    const vm = buildMatchCardViewModel(futureResult, [])
    expect(vm.disclaimer).toBeTruthy()
    expect(typeof vm.disclaimer).toBe('string')
  })

  it('exposes signal probability in the view model', () => {
    const vm = buildMatchCardViewModel(futureResult, [])
    expect(vm.signalProbability).toBe(0.72)
  })

  it('classifies signal quality as HIGH when probability >= 0.70', () => {
    const vm = buildMatchCardViewModel(futureResult, [])
    expect(vm.signalQuality).toBe('HIGH')
  })
})
