/**
 * Tests for sos-insights aggregation heuristic.
 */
import { describe, expect, it } from "vitest";

type Session = {
  breathingCount: number;
  gamesPlayed: unknown;
  messages: unknown;
  wasOvercome: boolean;
};

// Replicate the helpedBy logic for unit-test coverage
function aggregate(sessions: Session[]) {
  const helpedBy = { breathing: 0, game: 0, talk: 0, other: 0 };
  let overcome = 0;
  for (const s of sessions) {
    if (s.wasOvercome) overcome++;
    let counted = false;
    if (s.breathingCount > 0) {
      helpedBy.breathing++;
      counted = true;
    }
    if (Array.isArray(s.gamesPlayed) && s.gamesPlayed.length > 0) {
      helpedBy.game++;
      counted = true;
    }
    if (Array.isArray(s.messages) && s.messages.length > 4) {
      helpedBy.talk++;
      counted = true;
    }
    if (!counted) helpedBy.other++;
  }
  return { helpedBy, overcome, sessionsCount: sessions.length };
}

describe("sos-insights aggregation", () => {
  it("returns all-zero state when no sessions", () => {
    const r = aggregate([]);
    expect(r.sessionsCount).toBe(0);
    expect(r.overcome).toBe(0);
    expect(r.helpedBy).toEqual({ breathing: 0, game: 0, talk: 0, other: 0 });
  });

  it("counts breathing+game+talk independently per session", () => {
    const r = aggregate([
      {
        breathingCount: 2,
        gamesPlayed: [{ game: "tetris" }],
        messages: [1, 2, 3, 4, 5, 6],
        wasOvercome: true,
      },
    ]);
    expect(r.helpedBy.breathing).toBe(1);
    expect(r.helpedBy.game).toBe(1);
    expect(r.helpedBy.talk).toBe(1);
    expect(r.helpedBy.other).toBe(0);
    expect(r.overcome).toBe(1);
  });

  it("counts session as 'other' if nothing was used", () => {
    const r = aggregate([
      {
        breathingCount: 0,
        gamesPlayed: [],
        messages: [{ role: "user", content: "hi" }, { role: "assistant", content: "hi" }],
        wasOvercome: false,
      },
    ]);
    expect(r.helpedBy.other).toBe(1);
    expect(r.overcome).toBe(0);
  });

  it("handles mixed sessions correctly", () => {
    const r = aggregate([
      {
        breathingCount: 1,
        gamesPlayed: [],
        messages: [],
        wasOvercome: true,
      },
      {
        breathingCount: 0,
        gamesPlayed: [{ game: "snake" }],
        messages: [],
        wasOvercome: false,
      },
      {
        breathingCount: 0,
        gamesPlayed: [],
        messages: new Array(10).fill({ role: "user", content: "..." }),
        wasOvercome: true,
      },
    ]);
    expect(r.sessionsCount).toBe(3);
    expect(r.overcome).toBe(2);
    expect(r.helpedBy.breathing).toBe(1);
    expect(r.helpedBy.game).toBe(1);
    expect(r.helpedBy.talk).toBe(1);
  });

  it("handles malformed gamesPlayed (non-array) gracefully", () => {
    const r = aggregate([
      {
        breathingCount: 0,
        gamesPlayed: null,
        messages: null,
        wasOvercome: false,
      },
    ]);
    expect(r.helpedBy.other).toBe(1);
  });
});

describe("sos-insights overcome rate", () => {
  it("returns 0 rate when 0 sessions (avoid divide-by-zero)", () => {
    const sessionsCount = 0;
    const overcome = 0;
    const rate = sessionsCount > 0 ? overcome / sessionsCount : 0;
    expect(rate).toBe(0);
  });

  it("rounds to 2 decimals", () => {
    const rate = Math.round((4 / 5) * 100) / 100;
    expect(rate).toBe(0.8);
  });
});
