import { describe, it, expect } from 'vitest'
import {
  NeedParsingResponseSchema,
  FollowUpQuestionsResponseSchema,
  TradeOffSummaryResponseSchema,
  CompareSummaryResponseSchema,
  DecisionBriefResponseSchema,
  DataQualitySummaryResponseSchema,
  MarketSignalClassificationResponseSchema,
  OfferEmailResponseSchema,
  ProbabilitySchema,
  validateAIResponse,
} from '../schemas'

// ── ProbabilitySchema ─────────────────────────────────────────────────────────

describe('ProbabilitySchema', () => {
  it('accepts 0', () => expect(ProbabilitySchema.safeParse(0).success).toBe(true))
  it('accepts 1', () => expect(ProbabilitySchema.safeParse(1).success).toBe(true))
  it('accepts 0.65', () => expect(ProbabilitySchema.safeParse(0.65).success).toBe(true))
  it('rejects -5', () => expect(ProbabilitySchema.safeParse(-5).success).toBe(false))
  it('rejects 1.5', () => expect(ProbabilitySchema.safeParse(1.5).success).toBe(false))
  it('rejects NaN', () => expect(ProbabilitySchema.safeParse(NaN).success).toBe(false))
})

// ── NeedParsingResponseSchema ─────────────────────────────────────────────────

describe('NeedParsingResponseSchema', () => {
  it('accepts a complete valid response', () => {
    const result = NeedParsingResponseSchema.safeParse({
      assetType: 'OFFICE',
      areaRange: { min: 200, max: 500 },
      preferredLocations: ['Zürich', 'Basel'],
      budgetRange: { maxPerSqm: 45, currency: 'CHF' },
      timing: { earliestMoveIn: '2025-01-01', flexibleTiming: false },
      mustHaveCriteria: ['Erdgeschoss'],
      missingFields: [],
      assumptions: ['Fläche geschätzt'],
    })
    expect(result.success).toBe(true)
  })

  it('accepts a minimal response (all fields optional)', () => {
    const result = NeedParsingResponseSchema.safeParse({})
    expect(result.success).toBe(true)
  })

  it('accepts null for nullable fields', () => {
    const result = NeedParsingResponseSchema.safeParse({ assetType: null, areaRange: null })
    expect(result.success).toBe(true)
  })

  it('rejects areaRange where max < min', () => {
    const result = NeedParsingResponseSchema.safeParse({
      areaRange: { min: 500, max: 200 },
    })
    expect(result.success).toBe(false)
  })

  it('rejects unknown assetType value', () => {
    const result = NeedParsingResponseSchema.safeParse({ assetType: 'WAREHOUSE' })
    expect(result.success).toBe(false)
  })

  it('rejects negative area values', () => {
    const result = NeedParsingResponseSchema.safeParse({ areaRange: { min: -10, max: 500 } })
    expect(result.success).toBe(false)
  })
})

// ── FollowUpQuestionsResponseSchema ───────────────────────────────────────────

describe('FollowUpQuestionsResponseSchema', () => {
  const validQuestion = {
    questionText: 'Welchen Nutzungstyp suchen Sie?',
    targetField: 'assetType',
    reason: 'Pflichtfeld fehlt',
    importance: 'required',
  }

  it('accepts valid question array', () => {
    const result = FollowUpQuestionsResponseSchema.safeParse([validQuestion])
    expect(result.success).toBe(true)
  })

  it('accepts empty array', () => {
    const result = FollowUpQuestionsResponseSchema.safeParse([])
    expect(result.success).toBe(true)
  })

  it('rejects array with more than 5 items', () => {
    const questions = Array(6).fill(validQuestion)
    const result = FollowUpQuestionsResponseSchema.safeParse(questions)
    expect(result.success).toBe(false)
  })

  it('rejects question with empty questionText', () => {
    const result = FollowUpQuestionsResponseSchema.safeParse([{ ...validQuestion, questionText: '' }])
    expect(result.success).toBe(false)
  })

  it('rejects unknown importance value', () => {
    const result = FollowUpQuestionsResponseSchema.safeParse([{ ...validQuestion, importance: 'critical' }])
    expect(result.success).toBe(false)
  })
})

// ── TradeOffSummaryResponseSchema ─────────────────────────────────────────────

describe('TradeOffSummaryResponseSchema', () => {
  const valid = {
    headline: 'Hohe Mietkosten',
    items: [{ concern: 'Budget überschritten', severity: 'HIGH', mitigation: 'Verhandlung möglich' }],
    overallRisk: 'HIGH',
  }

  it('accepts valid trade-off summary', () => {
    expect(TradeOffSummaryResponseSchema.safeParse(valid).success).toBe(true)
  })

  it('rejects unknown severity value', () => {
    const bad = { ...valid, items: [{ concern: 'test', severity: 'CRITICAL' }] }
    expect(TradeOffSummaryResponseSchema.safeParse(bad).success).toBe(false)
  })

  it('rejects unknown overallRisk value', () => {
    const bad = { ...valid, overallRisk: 'EXTREME' }
    expect(TradeOffSummaryResponseSchema.safeParse(bad).success).toBe(false)
  })

  it('rejects more than 5 items', () => {
    const bad = { ...valid, items: Array(6).fill({ concern: 'x', severity: 'LOW' }) }
    expect(TradeOffSummaryResponseSchema.safeParse(bad).success).toBe(false)
  })

  it('rejects missing headline', () => {
    const { headline: _, ...bad } = valid
    expect(TradeOffSummaryResponseSchema.safeParse(bad).success).toBe(false)
  })
})

// ── CompareSummaryResponseSchema ──────────────────────────────────────────────

describe('CompareSummaryResponseSchema', () => {
  it('accepts valid compare summary', () => {
    const result = CompareSummaryResponseSchema.safeParse({
      overallAssessment: 'Objekt A ist am besten geeignet.',
      recommendation: 'Besichtigungstermin für Objekt A vereinbaren.',
      strongestOption: 'Objekt A',
    })
    expect(result.success).toBe(true)
  })

  it('accepts response with only overallAssessment (others optional)', () => {
    const result = CompareSummaryResponseSchema.safeParse({ overallAssessment: 'Gute Optionen.' })
    expect(result.success).toBe(true)
  })

  it('rejects empty overallAssessment', () => {
    const result = CompareSummaryResponseSchema.safeParse({ overallAssessment: '' })
    expect(result.success).toBe(false)
  })
})

// ── DecisionBriefResponseSchema ───────────────────────────────────────────────

describe('DecisionBriefResponseSchema', () => {
  const validSection = { title: 'Zusammenfassung', body: 'Überblick über die Situation.' }

  it('accepts valid decision brief', () => {
    const result = DecisionBriefResponseSchema.safeParse({
      summary: 'Executive Summary.',
      sections: [validSection, { title: 'Empfehlung', body: 'Objekt A priorisieren.' }],
    })
    expect(result.success).toBe(true)
  })

  it('rejects missing sections', () => {
    const result = DecisionBriefResponseSchema.safeParse({ summary: 'OK' })
    expect(result.success).toBe(false)
  })

  it('rejects empty sections array', () => {
    const result = DecisionBriefResponseSchema.safeParse({ summary: 'OK', sections: [] })
    expect(result.success).toBe(false)
  })

  it('rejects more than 6 sections', () => {
    const result = DecisionBriefResponseSchema.safeParse({
      summary: 'OK',
      sections: Array(7).fill(validSection),
    })
    expect(result.success).toBe(false)
  })

  it('rejects section with empty body', () => {
    const result = DecisionBriefResponseSchema.safeParse({
      summary: 'OK',
      sections: [{ title: 'Test', body: '' }],
    })
    expect(result.success).toBe(false)
  })
})

// ── DataQualitySummaryResponseSchema ──────────────────────────────────────────

describe('DataQualitySummaryResponseSchema', () => {
  it('accepts valid data quality summary', () => {
    const result = DataQualitySummaryResponseSchema.safeParse({
      overallAssessment: 'Gute Datenqualität.',
      missingCriticalFields: ['areaSqm'],
      recommendation: 'Fläche ergänzen.',
      confidence: 0.75,
    })
    expect(result.success).toBe(true)
  })

  it('rejects confidence > 1', () => {
    const result = DataQualitySummaryResponseSchema.safeParse({
      overallAssessment: 'Test',
      recommendation: 'Test',
      confidence: 1.5,
    })
    expect(result.success).toBe(false)
  })

  it('rejects confidence < 0', () => {
    const result = DataQualitySummaryResponseSchema.safeParse({
      overallAssessment: 'Test',
      recommendation: 'Test',
      confidence: -0.1,
    })
    expect(result.success).toBe(false)
  })
})

// ── MarketSignalClassificationResponseSchema ──────────────────────────────────

describe('MarketSignalClassificationResponseSchema', () => {
  const valid = {
    signalType: 'VACANCY',
    probability: 0.75,
    timeHorizonMonths: 6,
    areaSqmEstimate: 1200,
    credibility: 'HIGH',
    reasoning: 'Kündigung bekannt.',
  }

  it('accepts valid market signal', () => {
    expect(MarketSignalClassificationResponseSchema.safeParse(valid).success).toBe(true)
  })

  it('accepts null for nullable optional fields', () => {
    const result = MarketSignalClassificationResponseSchema.safeParse({
      ...valid,
      timeHorizonMonths: null,
      areaSqmEstimate: null,
    })
    expect(result.success).toBe(true)
  })

  it('rejects probability -5', () => {
    expect(MarketSignalClassificationResponseSchema.safeParse({ ...valid, probability: -5 }).success).toBe(false)
  })

  it('rejects probability 1.5', () => {
    expect(MarketSignalClassificationResponseSchema.safeParse({ ...valid, probability: 1.5 }).success).toBe(false)
  })

  it('rejects unknown signalType', () => {
    expect(MarketSignalClassificationResponseSchema.safeParse({ ...valid, signalType: 'FIRE_SALE' }).success).toBe(false)
  })

  it('rejects unknown credibility value', () => {
    expect(MarketSignalClassificationResponseSchema.safeParse({ ...valid, credibility: 'VERY_HIGH' }).success).toBe(false)
  })

  it('rejects missing reasoning', () => {
    const { reasoning: _, ...bad } = valid
    expect(MarketSignalClassificationResponseSchema.safeParse(bad).success).toBe(false)
  })

  it('rejects non-integer timeHorizonMonths', () => {
    expect(MarketSignalClassificationResponseSchema.safeParse({ ...valid, timeHorizonMonths: 2.5 }).success).toBe(false)
  })
})

// ── OfferEmailResponseSchema ──────────────────────────────────────────────────

describe('OfferEmailResponseSchema', () => {
  it('accepts valid offer email', () => {
    const result = OfferEmailResponseSchema.safeParse({
      subject: 'Angebot Büroflächen',
      body: 'Sehr geehrte Damen und Herren, wir bieten folgende Objekte an.',
    })
    expect(result.success).toBe(true)
  })

  it('rejects empty subject', () => {
    const result = OfferEmailResponseSchema.safeParse({ subject: '', body: 'Valid body text here.' })
    expect(result.success).toBe(false)
  })

  it('rejects body shorter than 50 characters', () => {
    const result = OfferEmailResponseSchema.safeParse({ subject: 'Angebot', body: 'Kurz.' })
    expect(result.success).toBe(false)
  })
})

// ── validateAIResponse helper ─────────────────────────────────────────────────

describe('validateAIResponse helper', () => {
  it('returns parsed data when schema passes', () => {
    const result = validateAIResponse(
      OfferEmailResponseSchema,
      { subject: 'Angebot Büroflächen', body: 'This body is definitely long enough to pass the fifty character minimum threshold.' },
      'test',
    )
    expect(result).not.toBeNull()
    expect(result?.subject).toBe('Angebot Büroflächen')
  })

  it('returns null when schema fails (does not throw)', () => {
    const result = validateAIResponse(
      OfferEmailResponseSchema,
      { subject: '', body: 'x' },
      'test',
    )
    expect(result).toBeNull()
  })

  it('returns null for completely wrong shape (does not throw)', () => {
    const result = validateAIResponse(
      MarketSignalClassificationResponseSchema,
      { probability: -999, signalType: 'INVALID' },
      'test',
    )
    expect(result).toBeNull()
  })

  it('returns null for null input (does not throw)', () => {
    const result = validateAIResponse(OfferEmailResponseSchema, null, 'test')
    expect(result).toBeNull()
  })
})
