import { describe, it, expect } from "vitest";
import { getUnlockedPhases, getUnlockedAtividades } from "../phaseUtils";

describe("getUnlockedPhases", () => {
  describe("sem progresso", () => {
    it("retorna [1] quando nenhuma fase foi concluída", () => {
      expect(getUnlockedPhases([], 5)).toEqual([1]);
    });

    it("retorna [1] quando completedPhases é null", () => {
      expect(getUnlockedPhases(null, 5)).toEqual([1]);
    });
  });

  describe("progresso parcial", () => {
    it("desbloqueia a fase seguinte à última concluída", () => {
      expect(getUnlockedPhases([1], 5)).toEqual([1, 2]);
    });

    it("desbloqueia corretamente após múltiplas fases completas", () => {
      expect(getUnlockedPhases([1, 2, 3], 5)).toEqual([1, 2, 3, 4]);
    });

    it("lida com completedPhases fora de ordem", () => {
      // Fase 2 completada antes da 1 (ex: debug mode)
      expect(getUnlockedPhases([2, 1], 5)).toEqual([1, 2, 3]);
    });
  });

  describe("limite total de fases", () => {
    it("não ultrapassa o total quando o jogo está completo", () => {
      expect(getUnlockedPhases([1, 2, 3, 4, 5], 5)).toEqual([1, 2, 3, 4, 5]);
    });

    it("não ultrapassa o total quando completedPhases tem a última fase", () => {
      expect(getUnlockedPhases([5], 5)).toEqual([1, 2, 3, 4, 5]);
    });

    it("retorna todas as fases quando totalPhases é 1 e ela foi concluída", () => {
      expect(getUnlockedPhases([1], 1)).toEqual([1]);
    });
  });
});

describe("getUnlockedAtividades", () => {
  const atividades = [{ id: "a" }, { id: "b" }, { id: "c" }, { id: "d" }];

  describe("sem progresso", () => {
    it("retorna só o ID da primeira atividade quando nada foi concluído", () => {
      expect(getUnlockedAtividades([], atividades)).toEqual(["a"]);
    });

    it("retorna array vazio quando a lista de atividades é vazia", () => {
      expect(getUnlockedAtividades([], [])).toEqual([]);
    });

    it("retorna array vazio quando completedIds é null e atividades é vazia", () => {
      expect(getUnlockedAtividades(null, [])).toEqual([]);
    });
  });

  describe("progresso parcial", () => {
    it("desbloqueia a próxima após uma atividade concluída", () => {
      const result = getUnlockedAtividades(["a"], atividades);
      expect(result).toContain("a");
      expect(result).toContain("b");
    });

    it("desbloqueia a próxima após múltiplas atividades concluídas", () => {
      const result = getUnlockedAtividades(["a", "b"], atividades);
      expect(result).toContain("c");
    });

    it("inclui todas as atividades completadas no resultado", () => {
      const result = getUnlockedAtividades(["a", "b"], atividades);
      expect(result).toContain("a");
      expect(result).toContain("b");
    });
  });

  describe("limite da lista", () => {
    it("não adiciona atividade além da última da lista", () => {
      const result = getUnlockedAtividades(["a", "b", "c", "d"], atividades);
      expect(result).not.toContain(undefined);
      expect(result.every((id) => atividades.some((a) => a.id === id))).toBe(true);
    });

    it("não duplica IDs quando todas as atividades estão completas", () => {
      const result = getUnlockedAtividades(["a", "b", "c", "d"], atividades);
      expect(result.length).toBe(new Set(result).size);
    });
  });

  describe("ID inválido em completedIds", () => {
    it("ignora IDs que não existem na lista de atividades", () => {
      // ID fantasma não deve causar crash; Math.max retorna -Infinity → findIndex retorna -1
      const result = getUnlockedAtividades(["fantasma"], atividades);
      // Resultado válido: não deve lançar
      expect(Array.isArray(result)).toBe(true);
    });
  });
});
