/**
 * Test script for voice intent classification
 *
 * Run with: node scripts/test-voice-intent.mjs
 */

// Import intent types (inline for testing)
const IntentType = {
  FEEDING: 'feeding',
  SLEEP: 'sleep',
  DIAPER: 'diaper',
  UNKNOWN: 'unknown',
};

const FeedingType = {
  BOTTLE: 'bottle',
  BREAST_LEFT: 'breast_left',
  BREAST_RIGHT: 'breast_right',
  BREAST_BOTH: 'breast_both',
  SOLID: 'solid',
};

const testCases = [
  // ===== FEEDING TESTS =====
  {
    name: 'Bottle feeding with amount in ml',
    input: 'Fed baby 120 ml',
    expectedIntent: IntentType.FEEDING,
    expectedSubtype: FeedingType.BOTTLE,
    expectedEntities: { amount: 120, unit: 'ml' },
  },
  {
    name: 'Bottle feeding with amount in oz',
    input: 'Gave him 4 oz',
    expectedIntent: IntentType.FEEDING,
    expectedSubtype: FeedingType.BOTTLE,
    expectedEntities: { amount: 4, unit: 'oz' },
  },
  {
    name: 'Bottle feeding simple',
    input: 'Bottle fed the baby',
    expectedIntent: IntentType.FEEDING,
    expectedSubtype: FeedingType.BOTTLE,
  },
  {
    name: 'Breastfeeding left side',
    input: 'Nursed on left breast for 15 minutes',
    expectedIntent: IntentType.FEEDING,
    expectedSubtype: FeedingType.BREAST_LEFT,
    expectedEntities: { side: 'left', duration: 15 },
  },
  {
    name: 'Breastfeeding right side',
    input: 'Fed from right side',
    expectedIntent: IntentType.FEEDING,
    expectedSubtype: FeedingType.BREAST_RIGHT,
    expectedEntities: { side: 'right' },
  },
  {
    name: 'Breastfeeding both sides',
    input: 'Breastfed on both sides for 20 minutes',
    expectedIntent: IntentType.FEEDING,
    expectedSubtype: FeedingType.BREAST_BOTH,
    expectedEntities: { side: 'both', duration: 20 },
  },
  {
    name: 'Solid food',
    input: 'Baby ate solid food',
    expectedIntent: IntentType.FEEDING,
    expectedSubtype: FeedingType.SOLID,
  },
  {
    name: 'Meal time',
    input: 'Had breakfast',
    expectedIntent: IntentType.FEEDING,
    expectedSubtype: FeedingType.SOLID,
  },

  // ===== SLEEP TESTS =====
  {
    name: 'Nap started',
    input: 'Baby fell asleep for a nap',
    expectedIntent: IntentType.SLEEP,
    expectedEntities: { type: 'nap' },
  },
  {
    name: 'Nap with duration',
    input: 'Napped for 45 minutes',
    expectedIntent: IntentType.SLEEP,
    expectedEntities: { duration: 45 },
  },
  {
    name: 'Bedtime',
    input: 'Put baby down for bedtime',
    expectedIntent: IntentType.SLEEP,
    expectedEntities: { type: 'night' },
  },
  {
    name: 'Night sleep',
    input: 'Baby is sleeping through the night',
    expectedIntent: IntentType.SLEEP,
    expectedEntities: { type: 'night' },
  },
  {
    name: 'Woke up',
    input: 'Baby woke up',
    expectedIntent: IntentType.SLEEP,
  },
  {
    name: 'Simple sleep',
    input: 'Baby is sleeping',
    expectedIntent: IntentType.SLEEP,
  },

  // ===== DIAPER TESTS =====
  {
    name: 'Wet diaper',
    input: 'Changed wet diaper',
    expectedIntent: IntentType.DIAPER,
    expectedEntities: { type: 'wet' },
  },
  {
    name: 'Dirty diaper',
    input: 'Dirty diaper change',
    expectedIntent: IntentType.DIAPER,
    expectedEntities: { type: 'dirty' },
  },
  {
    name: 'Poopy diaper',
    input: 'Baby had a poopy diaper',
    expectedIntent: IntentType.DIAPER,
    expectedEntities: { type: 'dirty' },
  },
  {
    name: 'Both wet and dirty',
    input: 'Changed a wet and dirty diaper',
    expectedIntent: IntentType.DIAPER,
    expectedEntities: { type: 'both' },
  },
  {
    name: 'Poop and pee',
    input: 'Diaper had both poop and pee',
    expectedIntent: IntentType.DIAPER,
    expectedEntities: { type: 'both' },
  },
  {
    name: 'Simple diaper change',
    input: 'Changed diaper',
    expectedIntent: IntentType.DIAPER,
  },
  {
    name: 'Bowel movement',
    input: 'Baby had a bowel movement',
    expectedIntent: IntentType.DIAPER,
    expectedEntities: { type: 'dirty' },
  },

  // ===== COMPLEX/EDGE CASES =====
  {
    name: 'Feeding with relative time',
    input: 'Fed baby 100ml 30 minutes ago',
    expectedIntent: IntentType.FEEDING,
    expectedEntities: { amount: 100 },
  },
  {
    name: 'Natural language feeding',
    input: 'The baby drank 5 ounces from the bottle',
    expectedIntent: IntentType.FEEDING,
    expectedEntities: { amount: 5, unit: 'oz' },
  },
  {
    name: 'Conversational sleep',
    input: 'She just fell asleep for her afternoon nap',
    expectedIntent: IntentType.SLEEP,
  },
  {
    name: 'Unclear command',
    input: 'Baby is crying',
    expectedIntent: IntentType.UNKNOWN,
  },
];

// Simplified classification logic for testing
function classifyIntent(text) {
  const lowerText = text.toLowerCase();

  // Feeding patterns
  const feedingKeywords = ['fed', 'feed', 'bottle', 'breast', 'nurse', 'nursing', 'drank', 'ate', 'breakfast', 'lunch', 'dinner', 'solid', 'gave'];
  const hasFeedingKeyword = feedingKeywords.some(kw => lowerText.includes(kw));

  // Sleep patterns
  const sleepKeywords = ['sleep', 'nap', 'asleep', 'woke', 'bedtime'];
  const hasSleepKeyword = sleepKeywords.some(kw => lowerText.includes(kw));

  // Diaper patterns
  const diaperKeywords = ['diaper', 'nappy', 'wet', 'dirty', 'poop', 'pee', 'bowel', 'bm', 'soiled'];
  const hasDiaperKeyword = diaperKeywords.some(kw => lowerText.includes(kw));

  let intent = IntentType.UNKNOWN;
  let subtype = null;
  const entities = {};

  if (hasFeedingKeyword) {
    intent = IntentType.FEEDING;

    // Determine feeding subtype
    if (lowerText.includes('breast') || lowerText.includes('nurs')) {
      if (lowerText.includes('left')) {
        subtype = FeedingType.BREAST_LEFT;
        entities.side = 'left';
      } else if (lowerText.includes('right')) {
        subtype = FeedingType.BREAST_RIGHT;
        entities.side = 'right';
      } else if (lowerText.includes('both')) {
        subtype = FeedingType.BREAST_BOTH;
        entities.side = 'both';
      } else {
        subtype = FeedingType.BREAST_BOTH;
      }
    } else if (lowerText.includes('solid') || lowerText.includes('ate') ||
               lowerText.includes('breakfast') || lowerText.includes('lunch') || lowerText.includes('dinner')) {
      subtype = FeedingType.SOLID;
    } else if (lowerText.includes('from') && (lowerText.includes('left') || lowerText.includes('right'))) {
      // Handle "fed from right/left side" pattern
      if (lowerText.includes('left')) {
        subtype = FeedingType.BREAST_LEFT;
        entities.side = 'left';
      } else {
        subtype = FeedingType.BREAST_RIGHT;
        entities.side = 'right';
      }
    } else {
      subtype = FeedingType.BOTTLE;
    }

    // Extract amount
    const amountMatch = text.match(/(\d+(?:\.\d+)?)\s*(ml|oz|ounces?)/i);
    if (amountMatch) {
      entities.amount = parseFloat(amountMatch[1]);
      const unit = amountMatch[2].toLowerCase();
      if (unit.startsWith('oz') || unit.startsWith('ounce')) {
        entities.unit = 'oz';
      } else if (unit.startsWith('ml')) {
        entities.unit = 'ml';
      }
    }

    // Extract duration
    const durationMatch = text.match(/(\d+)\s*minutes?/i);
    if (durationMatch) {
      entities.duration = parseInt(durationMatch[1]);
    }
  } else if (hasSleepKeyword) {
    intent = IntentType.SLEEP;

    // Extract sleep type
    if (lowerText.includes('nap')) {
      entities.type = 'nap';
    } else if (lowerText.includes('night') || lowerText.includes('bedtime')) {
      entities.type = 'night';
    }

    // Extract duration
    const durationMatch = text.match(/(\d+)\s*minutes?/i);
    if (durationMatch) {
      entities.duration = parseInt(durationMatch[1]);
    }
  } else if (hasDiaperKeyword) {
    intent = IntentType.DIAPER;

    const hasWet = /\b(wet|pee)\b/i.test(lowerText);
    const hasDirty = /\b(dirty|poop|poopy|soiled|bowel|bm)\b/i.test(lowerText);

    if (hasWet && hasDirty) {
      entities.type = 'both';
    } else if (hasDirty) {
      entities.type = 'dirty';
    } else if (hasWet) {
      entities.type = 'wet';
    }
  }

  return { intent, subtype, entities };
}

function runTests() {
  console.log('🎤 Testing Voice Intent Classification\n');
  console.log('='.repeat(60));

  let passed = 0;
  let failed = 0;
  const failures = [];

  for (const testCase of testCases) {
    const result = classifyIntent(testCase.input);
    let testPassed = true;
    const errors = [];

    // Check intent
    if (result.intent !== testCase.expectedIntent) {
      testPassed = false;
      errors.push(`Intent: expected ${testCase.expectedIntent}, got ${result.intent}`);
    }

    // Check subtype if specified
    if (testCase.expectedSubtype && result.subtype !== testCase.expectedSubtype) {
      testPassed = false;
      errors.push(`Subtype: expected ${testCase.expectedSubtype}, got ${result.subtype}`);
    }

    // Check entities if specified
    if (testCase.expectedEntities) {
      for (const [key, value] of Object.entries(testCase.expectedEntities)) {
        if (result.entities[key] !== value) {
          testPassed = false;
          errors.push(`Entity ${key}: expected ${value}, got ${result.entities[key]}`);
        }
      }
    }

    if (testPassed) {
      passed++;
      console.log(`✅ PASS: ${testCase.name}`);
    } else {
      failed++;
      console.log(`❌ FAIL: ${testCase.name}`);
      failures.push({ testCase, errors });
    }
  }

  console.log('='.repeat(60));
  console.log(`\n📊 Results: ${passed} passed, ${failed} failed out of ${testCases.length} tests`);

  if (failures.length > 0) {
    console.log('\n❌ Failed tests:');
    for (const { testCase, errors } of failures) {
      console.log(`\n  ${testCase.name}:`);
      console.log(`    Input: "${testCase.input}"`);
      for (const error of errors) {
        console.log(`    - ${error}`);
      }
    }
  }

  if (failed === 0) {
    console.log('🎉 All tests passed!\n');
  } else {
    console.log(`\n⚠️  ${failed} test(s) failed.\n`);
    process.exit(1);
  }
}

runTests();
