'use strict';
const { randomUUID: uuidv4 } = require('node:crypto');
const brain = require('../brain');

// Graduation thresholds from spec
const GRADUATION = {
  '1_to_2': { memories_required: 50 },
  '2_to_3': { approval_rate: 0.90, min_actions: 20 },
  '3_to_4': { approval_rate: 0.95, min_actions: 50 },
};

function getDomainConfidence(domain) {
  const db = brain.getDb();
  let row = db.prepare('SELECT * FROM domain_confidence WHERE domain = ?').get(domain);
  if (!row) {
    const id = uuidv4();
    db.prepare('INSERT INTO domain_confidence (id, domain) VALUES (?, ?)').run(id, domain);
    row = db.prepare('SELECT * FROM domain_confidence WHERE domain = ?').get(domain);
  }
  return row;
}

function checkGraduation(domain) {
  const dc = getDomainConfidence(domain);
  const currentTier = dc.current_tier;
  let newTier = currentTier;

  if (currentTier === 1) {
    // Tier 1 -> 2: enough memories in domain
    const memCount = brain.countMemories({ source: domain });
    if (memCount > 50) newTier = 2;
  } else if (currentTier === 2) {
    const rate = dc.total_actions > 0 ? dc.approved_actions / dc.total_actions : 0;
    if (rate > 0.90 && dc.total_actions > 20) newTier = 3;
  } else if (currentTier === 3) {
    const rate = dc.total_actions > 0 ? dc.approved_actions / dc.total_actions : 0;
    if (rate > 0.95 && dc.total_actions > 50) newTier = 4;
  }

  if (newTier !== currentTier) {
    brain.getDb().prepare(
      "UPDATE domain_confidence SET current_tier = ?, last_promotion = datetime('now'), updated_at = datetime('now') WHERE domain = ?"
    ).run(newTier, domain);
    return { promoted: true, from: currentTier, to: newTier };
  }
  return { promoted: false, tier: currentTier };
}

function recordAction(domain, approved) {
  const dc = getDomainConfidence(domain);
  const updates = {
    total_actions: dc.total_actions + 1,
    approved_actions: approved ? dc.approved_actions + 1 : dc.approved_actions,
    rejected_actions: approved ? dc.rejected_actions : dc.rejected_actions + 1,
  };

  // Check demotion: 3 rejections in a row
  if (!approved) {
    const recentActions = brain.getDb().prepare(
      "SELECT status FROM agent_actions WHERE domain = ? ORDER BY created_at DESC LIMIT 3"
    ).all(domain);
    const allRejected = recentActions.length === 3 && recentActions.every(a => a.status === 'rejected');
    if (allRejected && dc.current_tier > 1) {
      updates.current_tier = dc.current_tier - 1;
      updates.last_demotion = new Date().toISOString();
    }
  }

  const keys = Object.keys(updates);
  const sets = keys.map(k => `${k} = ?`).join(', ');
  const vals = keys.map(k => updates[k]);
  brain.getDb().prepare(`UPDATE domain_confidence SET ${sets}, updated_at = datetime('now') WHERE domain = ?`)
    .run(...vals, domain);

  // Check graduation after recording
  return checkGraduation(domain);
}

function canActAutonomously(domain, isHighRisk) {
  const dc = getDomainConfidence(domain);
  const tier = dc.current_tier;

  if (tier <= 2) return false; // Always queue
  if (tier === 3) return !isHighRisk; // Act on low-risk only
  if (tier === 4) return true; // Full autonomy
  return false;
}

function listDomainConfidences() {
  return brain.getDb().prepare('SELECT * FROM domain_confidence ORDER BY domain').all();
}

module.exports = { getDomainConfidence, checkGraduation, recordAction, canActAutonomously, listDomainConfidences };
