/**
 * @fileoverview Utility module for integration.test.js
 * 
 * @module games.semaforo.__tests__.integration.test
 */

import { describe, test, expect, beforeEach } from "vitest";
import { validateSolution } from "../validation/validators";

/**
 * Testes de integração para o jogo Semáforo
 *
 * Estes testes verificam:
 * - Validação de cada fase
 * - Casos de sucesso e falha
 * - Histórico de comandos
 * - Mensagens de erro apropriadas
 */

describe("SemaforoGame - Validação de Fases", () => {
  let gameConfig;

  beforeEach(() => {
    gameConfig = {
      mensagens: {
        semComandos: "Você não executou nenhum comando!",
        sequenciaIncorreta: "A sequência de cores está incorreta.",
        faltaAguardar: "Você esqueceu de aguardar entre as mudanças.",
        pedestreErrado: "O semáforo de pedestres deve estar sincronizado.",
        semPiscar: "Você esqueceu de fazer a luz piscar.",
        semSom: "Você não configurou os sons corretamente.",
        erroGeral: "Algo deu errado. Verifique seu código.",
      },
    };
  });

  // ========================================================================
  // FASE 1: Sequência básica de cores
  // ========================================================================
  describe("Fase 1 - Sequência de Cores", () => {
    const configFase = {
      id: 1,
      expectedSequence: ["vermelho", "amarelo", "verde"],
    };

    test("deve aceitar sequência correta: vermelho → amarelo → verde", () => {
      const historico = [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "semaforo", cor: "amarelo" },
        { tipo: "semaforo", cor: "verde" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(true);
    });

    test("deve rejeitar sequência vazia", () => {
      const historico = [];
      const resultado = validateSolution(historico, configFase, gameConfig);

      expect(resultado.success).toBe(false);
      expect(resultado.reason).toBe(gameConfig.mensagens.semComandos);
    });

    test("deve rejeitar sequência incompleta", () => {
      const historico = [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "semaforo", cor: "amarelo" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(false);
      expect(resultado.reason).toBe(gameConfig.mensagens.sequenciaIncorreta);
    });

    test("deve rejeitar sequência em ordem errada", () => {
      const historico = [
        { tipo: "semaforo", cor: "verde" },
        { tipo: "semaforo", cor: "amarelo" },
        { tipo: "semaforo", cor: "vermelho" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(false);
      expect(resultado.reason).toBe(gameConfig.mensagens.sequenciaIncorreta);
    });

    test("deve rejeitar cor duplicada", () => {
      const historico = [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "semaforo", cor: "verde" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(false);
    });
  });

  // ========================================================================
  // FASE 2: Sequência com aguardar
  // ========================================================================
  describe("Fase 2 - Sequência com Aguardar", () => {
    const configFase = {
      id: 2,
      expectedCommands: [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "aguardar" },
        { tipo: "semaforo", cor: "amarelo" },
        { tipo: "aguardar" },
        { tipo: "semaforo", cor: "verde" },
      ],
    };

    test("deve aceitar sequência com aguardar entre mudanças", () => {
      const historico = [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "aguardar", seg: 2 },
        { tipo: "semaforo", cor: "amarelo" },
        { tipo: "aguardar", seg: 2 },
        { tipo: "semaforo", cor: "verde" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(true);
    });

    test("deve rejeitar sequência sem aguardar", () => {
      const historico = [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "semaforo", cor: "amarelo" },
        { tipo: "semaforo", cor: "verde" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(false);
      expect(resultado.reason).toBe(gameConfig.mensagens.faltaAguardar);
    });

    test("deve rejeitar ordem errada dos comandos", () => {
      const historico = [
        { tipo: "aguardar", seg: 2 },
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "semaforo", cor: "amarelo" },
        { tipo: "aguardar", seg: 2 },
        { tipo: "semaforo", cor: "verde" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(false);
    });
  });

  // ========================================================================
  // FASE 3: Carros e Pedestres
  // ========================================================================
  describe("Fase 3 - Semáforo de Pedestres", () => {
    const configFase = {
      id: 3,
      temPedestre: true,
      expectedCommands: [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "pedestre", cor: "verde" },
        { tipo: "aguardar", seg: 3 },
        { tipo: "pedestre", cor: "vermelho" },
        { tipo: "semaforo", cor: "verde" },
      ],
    };

    test("deve aceitar sincronização correta carros/pedestres", () => {
      const historico = [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "pedestre", cor: "verde" },
        { tipo: "aguardar", seg: 3 },
        { tipo: "pedestre", cor: "vermelho" },
        { tipo: "semaforo", cor: "verde" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(true);
    });

    test("deve rejeitar semáforo de pedestres não sincronizado", () => {
      const historico = [
        { tipo: "semaforo", cor: "verde" },
        { tipo: "pedestre", cor: "verde" },
        { tipo: "aguardar", seg: 3 },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(false);
      expect(resultado.reason).toBe(gameConfig.mensagens.pedestreErrado);
    });

    test("deve rejeitar falta de comandos de pedestre", () => {
      const historico = [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "aguardar", seg: 3 },
        { tipo: "semaforo", cor: "verde" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(false);
    });
  });

  // ========================================================================
  // FASE 4: Piscar Luz de Pedestre
  // ========================================================================
  describe("Fase 4 - Piscar Luz", () => {
    const configFase = {
      id: 4,
      temPedestre: true,
      expectedCommands: [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "pedestre", cor: "verde" },
        { tipo: "aguardar", seg: 3 },
        { tipo: "piscar", cor: "verde", seg: 5 },
        { tipo: "pedestre", cor: "vermelho" },
        { tipo: "semaforo", cor: "verde" },
      ],
    };

    test("deve aceitar sequência com piscar", () => {
      const historico = [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "pedestre", cor: "verde" },
        { tipo: "aguardar", seg: 3 },
        { tipo: "piscar", cor: "verde", seg: 5 },
        { tipo: "pedestre", cor: "vermelho" },
        { tipo: "semaforo", cor: "verde" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(true);
    });

    test("deve rejeitar sequência sem piscar", () => {
      const historico = [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "pedestre", cor: "verde" },
        { tipo: "aguardar", seg: 3 },
        { tipo: "pedestre", cor: "vermelho" },
        { tipo: "semaforo", cor: "verde" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(false);
      expect(resultado.reason).toBe(gameConfig.mensagens.semPiscar);
    });

    test("deve validar cor e duração do piscar", () => {
      const historico = [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "pedestre", cor: "verde" },
        { tipo: "aguardar", seg: 3 },
        { tipo: "piscar", cor: "verde", seg: 5 },
        { tipo: "pedestre", cor: "vermelho" },
        { tipo: "semaforo", cor: "verde" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(true);
    });
  });

  // ========================================================================
  // FASE 5: Controle de Sons
  // ========================================================================
  describe("Fase 5 - Controle de Sons", () => {
    const configFase = {
      id: 5,
      temPedestre: true,
      expectedCommands: [
        { tipo: "tocar", som: "barulho_cidade" },
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "tocar", som: "beep_semaforo" },
        { tipo: "pedestre", cor: "verde" },
        { tipo: "aguardar", seg: 3 },
        { tipo: "piscar", cor: "verde", seg: 5 },
        { tipo: "pedestre", cor: "vermelho" },
        { tipo: "parar", som: "beep_semaforo" },
        { tipo: "semaforo", cor: "verde" },
      ],
    };

    test("deve aceitar sequência completa com sons", () => {
      const historico = [
        { tipo: "tocar", som: "barulho_cidade" },
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "tocar", som: "beep_semaforo" },
        { tipo: "pedestre", cor: "verde" },
        { tipo: "aguardar", seg: 3 },
        { tipo: "piscar", cor: "verde", seg: 5 },
        { tipo: "pedestre", cor: "vermelho" },
        { tipo: "parar", som: "beep_semaforo" },
        { tipo: "semaforo", cor: "verde" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(true);
    });

    test("deve rejeitar sequência sem controle de sons", () => {
      const historico = [
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "pedestre", cor: "verde" },
        { tipo: "aguardar", seg: 3 },
        { tipo: "piscar", cor: "verde", seg: 5 },
        { tipo: "pedestre", cor: "vermelho" },
        { tipo: "semaforo", cor: "verde" },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(false);
      expect(resultado.reason).toBe(gameConfig.mensagens.semSom);
    });

    test("deve validar ordem correta dos sons", () => {
      const historico = [
        { tipo: "parar", som: "beep_semaforo" }, // Ordem errada
        { tipo: "semaforo", cor: "vermelho" },
        { tipo: "tocar", som: "barulho_cidade" },
        { tipo: "pedestre", cor: "verde" },
        { tipo: "aguardar", seg: 3 },
      ];

      const resultado = validateSolution(historico, configFase, gameConfig);
      expect(resultado.success).toBe(false);
    });
  });
});
