import { describe, it, expect } from 'vitest';
import {
  applyOpusUpdates,
  shouldRunDeepReasoning,
} from './stage4-deep-reasoning';
import type {
  DeepAnalysisResponse,
  TriageResponse,
} from '@/lib/types/analyzer';

const baseTriage: TriageResponse = {
  ticket_type: 'service_request',
  category: 'misc',
  entities: {
    client_name: 'Acme',
    site_name: null,
    devices: [],
    users: [],
    applications: [],
    vendors: [],
  },
  is_resolved: false,
  status_matches_reality: true,
  complexity_tier: 'medium',
  complexity_reasons: [],
  itglue_lookup_needed: false,
  itglue_search_hints: [],
};

const baseSonnet: DeepAnalysisResponse = {
  summary: 's',
  timeline: [],
  what_was_done: [],
  what_should_have_been_done: [],
  gaps: [],
  next_step: 'Original next step',
  next_step_rationale: 'because',
  post_resolution_analysis: null,
  confidence_score: 0.8,
  needs_human_review: false,
  human_review_reasons: [],
  ambiguities_for_opus: [],
  itglue_docs_referenced: [],
};

describe('shouldRunDeepReasoning', () => {
  it('triggers on complexity_tier=high', () => {
    expect(
      shouldRunDeepReasoning({
        triage: { ...baseTriage, complexity_tier: 'high' },
        sonnet: baseSonnet,
      })
    ).toBe(true);
  });

  it('triggers when ambiguities_for_opus is non-empty', () => {
    expect(
      shouldRunDeepReasoning({
        triage: baseTriage,
        sonnet: { ...baseSonnet, ambiguities_for_opus: ['why?'] },
      })
    ).toBe(true);
  });

  it('triggers on confidence_score < 0.5', () => {
    expect(
      shouldRunDeepReasoning({
        triage: baseTriage,
        sonnet: { ...baseSonnet, confidence_score: 0.4 },
      })
    ).toBe(true);
  });

  it('triggers on status_matches_reality=false', () => {
    expect(
      shouldRunDeepReasoning({
        triage: { ...baseTriage, status_matches_reality: false },
        sonnet: baseSonnet,
      })
    ).toBe(true);
  });

  it('does not trigger in the all-clear case', () => {
    expect(shouldRunDeepReasoning({ triage: baseTriage, sonnet: baseSonnet })).toBe(false);
  });
});

describe('applyOpusUpdates', () => {
  it('returns Sonnet untouched when updates is empty', () => {
    const out = applyOpusUpdates(baseSonnet, {});
    expect(out).toEqual(baseSonnet);
    expect(out).not.toBe(baseSonnet); // shallow copy
  });

  it('overrides only fields present in updates', () => {
    const out = applyOpusUpdates(baseSonnet, {
      next_step: 'Opus next step',
      confidence_score: 0.95,
    });
    expect(out.next_step).toBe('Opus next step');
    expect(out.confidence_score).toBe(0.95);
    // unchanged
    expect(out.next_step_rationale).toBe(baseSonnet.next_step_rationale);
    expect(out.summary).toBe(baseSonnet.summary);
  });

  it('replaces gaps array entirely when present in updates', () => {
    const out = applyOpusUpdates(baseSonnet, {
      gaps: [
        { description: 'new gap', severity: 'high', evidence_timestamps: [] },
      ],
    });
    expect(out.gaps).toHaveLength(1);
    expect(out.gaps[0].severity).toBe('high');
  });

  it('flips needs_human_review when present', () => {
    const out = applyOpusUpdates(baseSonnet, {
      needs_human_review: true,
      human_review_reasons: ['opus says so'],
    });
    expect(out.needs_human_review).toBe(true);
    expect(out.human_review_reasons).toEqual(['opus says so']);
  });

  it('explicitly null post_resolution_analysis is honored', () => {
    const sonnetWithRes: DeepAnalysisResponse = {
      ...baseSonnet,
      post_resolution_analysis: 'old',
    };
    const out = applyOpusUpdates(sonnetWithRes, { post_resolution_analysis: null });
    expect(out.post_resolution_analysis).toBeNull();
  });

  it('does not mutate the input', () => {
    const snapshot = JSON.parse(JSON.stringify(baseSonnet));
    applyOpusUpdates(baseSonnet, { next_step: 'mutated' });
    expect(baseSonnet).toEqual(snapshot);
  });
});
