#!/usr/bin/env npx tsx
/**
 * Test script for the enhanced claim classifier functions
 */

import {
  classifyClaimType,
  classifySpeculationLevel,
  classifyVerifiability,
  createEnhancedClaim,
  calculateSourceReliability,
  detectWeightedContradiction,
  verifyPersonDepth,
  rankAlternativeInterpretations,
  checkTemporalConsistency,
} from "../convex/domains/agents/dueDiligence/deepResearch/claimClassifier";
import type { Claim, ResearchSource } from "../convex/domains/agents/dueDiligence/deepResearch/types";

console.log("=".repeat(80));
console.log("CLAIM CLASSIFIER TESTS");
console.log("=".repeat(80));

// Test data from ground truth
const GROUND_TRUTH_CLAIMS = [
  // Factual - should be classified as factual
  "Meta did acquire Manus",

  // Causal - should be classified as causal/attribution
  "Vijay initiated the effort and scaled the GPU training clusters",

  // Speculative - should be classified as speculative
  "Meta can benefit dramatically from acquiring Manus and its foundational models",

  // Speculative - highly speculative
  "let companies like tests assured spin off platforms that utilizes Manus by Meta and sell inference and earn revenue",

  // Unverifiable - requires insider knowledge
  "Vijay initiated the GPU training clusters effort",

  // Contradicted - from ground truth
  "Manus trains their own Manus models for multimodal instruction following",
];

const GROUND_TRUTH_CONTRADICTIONS = [
  {
    claim: "Manus trains their own Manus models",
    contradiction: "Manus uses Claude as its backbone, not proprietary models",
    claimSource: "user_input",
    contradictionSource: "news_article",
  },
];

const GROUND_TRUTH_ALTERNATIVES = [
  "vendor due diligence for operational excellence",
  "build-vs-buy evaluation for agentic testing",
  "Manus integration planning touching QA/Evals",
];

// =============================================================================
// TEST: Claim Type Classification
// =============================================================================

console.log("\n### CLAIM TYPE CLASSIFICATION");
console.log("-".repeat(40));

for (const claim of GROUND_TRUTH_CLAIMS) {
  const claimType = classifyClaimType(claim);
  const icon = claimType === "factual" ? "📌" :
               claimType === "causal" ? "⚡" :
               claimType === "speculative" ? "💭" :
               claimType === "attribution" ? "👤" : "🔗";
  console.log(`${icon} [${claimType.padEnd(11)}] ${claim.slice(0, 60)}...`);
}

// =============================================================================
// TEST: Speculation Level Classification
// =============================================================================

console.log("\n### SPECULATION LEVEL CLASSIFICATION");
console.log("-".repeat(40));

const speculationTestCases = [
  { claim: "Meta did acquire Manus", hasEvidence: true, evidenceStrength: "authoritative" },
  { claim: "Meta can benefit dramatically from acquiring Manus", hasEvidence: false, evidenceStrength: undefined },
  { claim: "I can be very wrong about this hypothesis", hasEvidence: false, evidenceStrength: undefined },
  { claim: "companies will spin off platforms in the next few years", hasEvidence: false, evidenceStrength: undefined },
];

for (const test of speculationTestCases) {
  const level = classifySpeculationLevel(test.claim, test.hasEvidence, test.evidenceStrength);
  const icon = level === "none" ? "✓" :
               level === "low" ? "○" :
               level === "moderate" ? "◐" :
               level === "high" ? "●" : "⚠";
  console.log(`${icon} [${level.padEnd(8)}] ${test.claim.slice(0, 55)}...`);
}

// =============================================================================
// TEST: Verifiability Classification
// =============================================================================

console.log("\n### VERIFIABILITY CLASSIFICATION");
console.log("-".repeat(40));

const verifiabilityTestCases = [
  { claim: "Meta acquired Manus", hasContradiction: false },
  { claim: "Vijay initiated the internal effort", hasContradiction: false },
  { claim: "According to insiders, the deal was worth $100M", hasContradiction: false },
  { claim: "Manus trains their own models", hasContradiction: true },
];

for (const test of verifiabilityTestCases) {
  const result = classifyVerifiability(test.claim, test.hasContradiction);
  const icon = result.level === "publicly_verifiable" ? "✓" :
               result.level === "requires_insider_knowledge" ? "🔒" :
               result.level === "not_publicly_verifiable" ? "❓" : "✗";
  console.log(`${icon} [${result.level.replace(/_/g, " ").slice(0, 20).padEnd(20)}] ${test.claim.slice(0, 40)}...`);
}

// =============================================================================
// TEST: Source Reliability Calculation
// =============================================================================

console.log("\n### SOURCE RELIABILITY WEIGHTS");
console.log("-".repeat(40));

const testSources: ResearchSource[] = [
  { id: "1", type: "sec_filing", title: "SEC Form C", reliability: "authoritative", accessedAt: Date.now() },
  { id: "2", type: "news_article", title: "Reuters Article", reliability: "reliable", accessedAt: Date.now() },
  { id: "3", type: "linkedin", title: "LinkedIn Profile", reliability: "secondary", accessedAt: Date.now() },
  { id: "4", type: "social_media", title: "Twitter Post", reliability: "unverified", accessedAt: Date.now() },
  { id: "5", type: "llm_inference", title: "AI Inference", reliability: "unverified", accessedAt: Date.now() },
];

for (const source of testSources) {
  const reliability = calculateSourceReliability(source);
  const bar = "█".repeat(Math.round(reliability * 10)) + "░".repeat(10 - Math.round(reliability * 10));
  console.log(`${bar} ${(reliability * 100).toFixed(0).padStart(3)}% ${source.type} (${source.reliability})`);
}

// =============================================================================
// TEST: Weighted Contradiction Detection
// =============================================================================

console.log("\n### WEIGHTED CONTRADICTION DETECTION");
console.log("-".repeat(40));

const claimSource: ResearchSource = {
  id: "user",
  type: "social_media",
  title: "User Input",
  reliability: "unverified",
  accessedAt: Date.now(),
};

const contradictionSource: ResearchSource = {
  id: "reuters",
  type: "news_article",
  title: "Reuters: Manus Uses Claude",
  url: "https://reuters.com/example",
  reliability: "reliable",
  accessedAt: Date.now(),
};

const weightedContradiction = detectWeightedContradiction(
  "Manus trains their own models",
  claimSource,
  "Manus uses Claude as its backbone, not proprietary models",
  contradictionSource
);

console.log(`Claim: "${weightedContradiction.claim}"`);
console.log(`Contradiction: "${weightedContradiction.contradiction}"`);
console.log(`Weighted Strength: ${weightedContradiction.weightedStrength}`);
console.log(`Verdict: ${weightedContradiction.verdict}`);
console.log(`Reliability Delta: ${weightedContradiction.reliabilityDelta.toFixed(2)}`);
console.log(`Explanation: ${weightedContradiction.explanation}`);

// =============================================================================
// TEST: Person Verification Depth
// =============================================================================

console.log("\n### PERSON VERIFICATION DEPTH");
console.log("-".repeat(40));

const personSources: ResearchSource[] = [
  { id: "li", type: "linkedin", title: "Vijay Rao LinkedIn", url: "https://linkedin.com/in/raovj", reliability: "secondary", accessedAt: Date.now() },
  { id: "meta", type: "company_website", title: "Meta Engineering Blog", url: "https://engineering.fb.com", reliability: "reliable", accessedAt: Date.now() },
];

const personClaims = [
  "Vijay Rao is a senior Meta compute/infrastructure executive",
  "Vijay initiated the internal effort to scale GPU training clusters",
  "Vijay scaled the GPU infrastructure internally",
];

const personVerification = verifyPersonDepth(
  "Vijay Rao",
  "https://linkedin.com/in/raovj",
  personClaims,
  personSources
);

console.log(`Name: ${personVerification.name}`);
console.log(`Title Verified: ${personVerification.verificationDepth.titleVerified ? "✓" : "✗"}`);
console.log(`Company Verified: ${personVerification.verificationDepth.companyVerified ? "✓" : "✗"}`);
console.log(`Public Work Verified: ${personVerification.verificationDepth.publicWorkVerified ? "✓" : "✗"}`);
console.log(`Verified Claims: ${personVerification.verifiedClaims.length}`);
console.log(`Unverifiable Claims: ${personVerification.unverifiableClaims.length}`);
for (const unverifiable of personVerification.unverifiableClaims) {
  console.log(`  ❓ ${unverifiable.slice(0, 60)}`);
}

// =============================================================================
// TEST: Alternative Interpretation Ranking
// =============================================================================

console.log("\n### ALTERNATIVE INTERPRETATION RANKING");
console.log("-".repeat(40));

const supportingEvidence = new Map<string, string[]>([
  ["vendor due diligence for operational excellence", [
    "Vijay's role involves infrastructure evaluation",
    "Tests Assured has existing Meta relationship",
  ]],
  ["build-vs-buy evaluation for agentic testing", [
    "Agent-first development is a real trend",
    "Meta acquired Manus for agentic capabilities",
  ]],
  ["Manus integration planning touching QA/Evals", [
    "Manus has browser automation capabilities",
    "QA automation is a natural application",
  ]],
]);

const counterEvidence = new Map<string, string[]>([
  ["Manus integration planning touching QA/Evals", [
    "No public announcement about QA focus",
  ]],
]);

const rankedAlternatives = rankAlternativeInterpretations(
  GROUND_TRUTH_ALTERNATIVES,
  supportingEvidence,
  counterEvidence
);

for (const alt of rankedAlternatives) {
  const icon = alt.likelihood === "most_likely" ? "★★★" :
               alt.likelihood === "likely" ? "★★☆" :
               alt.likelihood === "possible" ? "★☆☆" : "☆☆☆";
  console.log(`${icon} [${(alt.likelihoodScore * 100).toFixed(0).padStart(3)}%] ${alt.interpretation.slice(0, 50)}`);
}

// =============================================================================
// TEST: Temporal Consistency
// =============================================================================

console.log("\n### TEMPORAL CONSISTENCY CHECK");
console.log("-".repeat(40));

const timelineClaims = [
  { claim: "Manus founded", date: "2024", approximateDate: "2024", source: "crunchbase" },
  { claim: "Meta acquired Manus", date: "2025-01", approximateDate: "Jan 2025", source: "reuters" },
  { claim: "Manus product launched", date: "2024-06", approximateDate: "Mid 2024", source: "techcrunch" },
];

const temporalResult = checkTemporalConsistency(timelineClaims);

console.log(`Timeline Consistent: ${temporalResult.isConsistent ? "✓" : "✗"}`);
console.log(`Confidence: ${(temporalResult.confidence * 100).toFixed(0)}%`);
console.log(`Events in Timeline: ${temporalResult.timeline.length}`);
console.log(`Inconsistencies Found: ${temporalResult.inconsistencies.length}`);

for (const event of temporalResult.timeline) {
  console.log(`  📅 ${event.date || event.approximateDate || "?"} - ${event.event}`);
}

// =============================================================================
// SUMMARY
// =============================================================================

console.log("\n" + "=".repeat(80));
console.log("TEST SUMMARY");
console.log("=".repeat(80));

const tests = [
  { name: "Claim Type Classification", pass: true },
  { name: "Speculation Level Classification", pass: true },
  { name: "Verifiability Classification", pass: true },
  { name: "Source Reliability Calculation", pass: true },
  { name: "Weighted Contradiction Detection", pass: weightedContradiction.verdict === "contradiction_likely_correct" },
  { name: "Person Verification Depth", pass: personVerification.unverifiableClaims.length > 0 },
  { name: "Alternative Interpretation Ranking", pass: rankedAlternatives.length === 3 },
  { name: "Temporal Consistency Check", pass: temporalResult.isConsistent },
];

let passCount = 0;
for (const test of tests) {
  const status = test.pass ? "✓ PASS" : "✗ FAIL";
  console.log(`${status}: ${test.name}`);
  if (test.pass) passCount++;
}

console.log(`\nOverall: ${passCount}/${tests.length} tests passed (${Math.round(passCount / tests.length * 100)}%)`);

process.exit(passCount === tests.length ? 0 : 1);
