/**
 * Integration Test: Modal → Learning Pipeline
 *
 * Tests the full flow:
 * 1. Mock modal postMessage feedback
 * 2. Validate with shared Zod schemas
 * 3. Transform to FeedbackEvent
 * 4. Feed into learning pipeline
 * 5. Verify output
 */

import { parseModalMessage, modalResponseToFeedbackEvent } from "../../packages/shared/src/integration/modal-to-learning.js";
import type { ModalResponse } from "../../packages/shared/src/types/feedback.js";

// ─── Test Helpers ───

let passed = 0;
let failed = 0;

function assert(condition: boolean, message: string) {
  if (condition) {
    console.log(`  ✅ ${message}`);
    passed++;
  } else {
    console.error(`  ❌ ${message}`);
    failed++;
  }
}

// ─── Mock Data ───

const mockModalResponse: ModalResponse = {
  type: "factory_modal_response",
  modalType: "traffic-light",
  modalVersion: "1.0.0",
  pipelineId: "pipeline-123",
  itemId: "item-456",
  sessionId: "session-789",
  timestamp: new Date().toISOString(),
  responseTimeMs: 3500,
  feedback: {
    decision: {
      decision: "approved",
      reason: "Code looks clean, tests passing",
      tags: ["clean-code", "tests-passing"],
    },
    confidence: {
      confidencePercent: 85,
      zone: "confident",
      wouldDelegateToAI: false,
      needsExpertReview: false,
    },
  },
  meta: {
    timeToFirstInteractionMs: 1200,
    timeToDecisionMs: 3500,
    fieldsModified: ["decision", "confidence"],
    scrollDepth: 0.8,
    revisits: 0,
    totalInteractions: 5,
    viewportSize: { width: 1920, height: 1080 },
    deviceType: "desktop",
  },
};

// ─── Tests ───

console.log("\n🧪 Modal → Learning Integration Tests\n");

// Test 1: Valid modal message parsing
console.log("Test 1: Parse valid modal response");
{
  const result = parseModalMessage(mockModalResponse);
  assert(result.valid === true, "Should parse valid modal response");
  if (result.valid) {
    assert(result.response.modalType === "traffic-light", "Modal type should be traffic-light");
    assert(result.response.feedback.decision?.decision === "approved", "Decision should be approved");
  }
}

// Test 2: Invalid message (wrong type)
console.log("\nTest 2: Reject non-response messages");
{
  const result = parseModalMessage({ type: "factory_modal_ready", modalType: "test", version: "1.0.0" });
  assert(result.valid === false, "Should reject non-response messages");
}

// Test 3: Invalid message (bad schema)
console.log("\nTest 3: Reject schema-invalid messages");
{
  const result = parseModalMessage({
    type: "factory_modal_response",
    modalType: "test",
    // Missing required fields
  });
  assert(result.valid === false, "Should reject schema-invalid messages");
}

// Test 4: Null/undefined input
console.log("\nTest 4: Handle null/undefined input");
{
  assert(parseModalMessage(null).valid === false, "Should reject null");
  assert(parseModalMessage(undefined).valid === false, "Should reject undefined");
  assert(parseModalMessage("string").valid === false, "Should reject string");
}

// Test 5: Transform to FeedbackEvent
console.log("\nTest 5: Transform ModalResponse → FeedbackEvent");
{
  const feedbackEvent = modalResponseToFeedbackEvent(mockModalResponse, {
    workProductType: "mcp_server",
    workProductId: "ghl-mcp",
    workProductVersion: "abc123",
    workProductSummary: "Go High Level MCP server",
    pipelineStage: "review",
    mcpServerType: "go-high-level",
  });

  assert(typeof feedbackEvent.id === "string", "Should have UUID id");
  assert(feedbackEvent.modalType === "traffic-light", "Modal type preserved");
  assert(feedbackEvent.pipelineId === "pipeline-123", "Pipeline ID preserved");
  assert(feedbackEvent.workProduct.type === "mcp_server", "Work product type set");
  assert(feedbackEvent.pipelineStage === "review", "Pipeline stage set");
  assert(feedbackEvent.feedback.decision?.decision === "approved", "Feedback preserved");
  assert(feedbackEvent.meta.timeOfDay !== undefined, "Time of day enriched");
  assert(feedbackEvent.meta.dayOfWeek !== undefined, "Day of week enriched");
}

// Test 6: Scores validation in FeedbackEvent
console.log("\nTest 6: Scores feedback type");
{
  const responseWithScores: ModalResponse = {
    ...mockModalResponse,
    modalType: "report-card",
    feedback: {
      scores: [
        { dimension: "code_quality", score: 8, comment: "Clean" },
        { dimension: "test_coverage", score: 9 },
        { dimension: "documentation", score: 7 },
      ],
    },
  };

  const result = parseModalMessage(responseWithScores);
  assert(result.valid === true, "Should accept scores feedback");
  if (result.valid) {
    assert(result.response.feedback.scores?.length === 3, "Should have 3 scores");
  }
}

// Test 7: Batch decisions feedback type
console.log("\nTest 7: Batch decisions feedback type");
{
  const responseWithBatch: ModalResponse = {
    ...mockModalResponse,
    modalType: "tinder-swipe",
    feedback: {
      batchDecisions: [
        { itemId: "item-1", decision: "approve", timeMs: 1200, flippedForDetails: false },
        { itemId: "item-2", decision: "reject", timeMs: 3500, flippedForDetails: true },
        { itemId: "item-3", decision: "love", timeMs: 800, flippedForDetails: false },
      ],
    },
  };

  const result = parseModalMessage(responseWithBatch);
  assert(result.valid === true, "Should accept batch decisions");
  if (result.valid) {
    assert(result.response.feedback.batchDecisions?.length === 3, "Should have 3 batch decisions");
  }
}

// ─── Summary ───
console.log(`\n${"═".repeat(50)}`);
console.log(`Results: ${passed} passed, ${failed} failed out of ${passed + failed} assertions`);
console.log(`${"═".repeat(50)}\n`);

if (failed > 0) {
  process.exit(1);
}
