import { describe, it, expect } from 'vitest'
import { futureSignalService } from '../futureSignalService'

describe('futureSignalService', () => {
  describe('getAll', () => {
    it('returns a ListResponse with signal data', async () => {
      const result = await futureSignalService.getAll()
      expect(Array.isArray(result.data)).toBe(true)
      expect(result.data.length).toBeGreaterThan(0)
      expect(result.meta!.total).toBe(result.data.length)
    })

    it('each signal has required fields', async () => {
      const { data } = await futureSignalService.getAll()
      for (const s of data) {
        expect(typeof s.id).toBe('string')
        if (s.propertyId !== undefined) expect(typeof s.propertyId).toBe('string')
        expect(typeof s.confidenceScore).toBe('number')
        expect(s.confidenceScore).toBeGreaterThanOrEqual(0)
        expect(s.confidenceScore).toBeLessThanOrEqual(1)
      }
    })
  })

  describe('getById', () => {
    it('returns a signal for an existing id', async () => {
      const { data: all } = await futureSignalService.getAll()
      const id = all[0].id
      const result = await futureSignalService.getById(id)
      expect(result.data?.id).toBe(id)
    })

    it('returns null for an unknown id', async () => {
      const result = await futureSignalService.getById('no-such-signal')
      expect(result.data).toBeNull()
    })
  })

  describe('getByProperty', () => {
    it('returns only signals for the given propertyId', async () => {
      const { data: all } = await futureSignalService.getAll()
      const withPropertyId = all.find(s => s.propertyId)
      if (!withPropertyId?.propertyId) return // no signals with propertyId in seed data
      const result = await futureSignalService.getByProperty(withPropertyId.propertyId)
      expect(result.data.every(s => s.propertyId === withPropertyId.propertyId)).toBe(true)
    })
  })

  describe('getSignalSummary', () => {
    it('returns totals and distribution', async () => {
      const summary = await futureSignalService.getSignalSummary()
      expect(typeof summary.total).toBe('number')
      expect(typeof summary.highConfidence).toBe('number')
      expect(typeof summary.restricted).toBe('number')
      expect(typeof summary.needsReview).toBe('number')
      expect(typeof summary.avgTimeHorizonMonths).toBe('number')
      expect(typeof summary.timeHorizonDistribution.short).toBe('number')
      expect(typeof summary.timeHorizonDistribution.medium).toBe('number')
      expect(typeof summary.timeHorizonDistribution.long).toBe('number')
    })

    it('highConfidence count matches signals with score >= 0.75', async () => {
      const { data: all } = await futureSignalService.getAll()
      const expected = all.filter(s => s.confidenceScore >= 0.75).length
      const summary = await futureSignalService.getSignalSummary()
      expect(summary.highConfidence).toBe(expected)
    })

    it('needsReview count matches unverified signals', async () => {
      const { data: all } = await futureSignalService.getAll()
      const expected = all.filter(s => !s.isVerified).length
      const summary = await futureSignalService.getSignalSummary()
      expect(summary.needsReview).toBe(expected)
    })

    it('distribution totals add up to total signal count', async () => {
      const summary = await futureSignalService.getSignalSummary()
      const { short, medium, long } = summary.timeHorizonDistribution
      expect(short + medium + long).toBe(summary.total)
    })
  })
})
