'use strict';

/**
 * Promotion detector — checks if shadow models are ready for promotion.
 * Creates brain tasks and briefing items when models meet criteria.
 */

const PROMOTION_CRITERIA = {
  minEvals: 50,
  minAvgScore: 0.75,
  minWinRate: 0.6,
  validTrends: ['improving', 'stable'],
  minDaysSinceAlert: 7,
};

/**
 * Format a promotion alert as markdown.
 */
function formatPromotionAlert(candidate) {
  const winRate = candidate.total_evals > 0
    ? (candidate.win_count / candidate.total_evals * 100).toFixed(1)
    : '0.0';
  return [
    `## Model Promotion: ${candidate.model}`,
    '',
    `**Task type:** ${candidate.task_type}`,
    `**Evaluations:** ${candidate.total_evals}`,
    `**Average score:** ${(candidate.avg_score * 100).toFixed(1)}%`,
    `**Win rate:** ${winRate}%`,
    `**Strong wins:** ${candidate.strong_win_count}`,
    `**Avg latency:** ${Math.round(candidate.avg_latency_ms || 0)}ms`,
    `**Trend:** ${candidate.trend}`,
    `**Current rollout:** ${((candidate.rollout_pct || 0) * 100).toFixed(0)}%`,
    '',
    '### Recommendation',
    buildRecommendation(candidate),
    '',
    '### Actions',
    '- **Approve**: Set as default model for this task type, start gradual rollout',
    '- **Trial**: Start at 10% rollout for 7 days',
    '- **Reject**: Suppress alerts for 30 days',
  ].join('\n');
}

/**
 * Build a recommendation based on candidate stats.
 */
function buildRecommendation(candidate) {
  const winRate = candidate.total_evals > 0
    ? candidate.win_count / candidate.total_evals
    : 0;

  if (candidate.avg_score >= 0.9 && winRate >= 0.8 && candidate.trend === 'improving') {
    return 'Strong candidate for full promotion. High quality and improving trend.';
  }
  if (candidate.avg_score >= 0.8 && winRate >= 0.7) {
    return 'Good candidate. Consider a 30% trial rollout to validate at scale.';
  }
  return 'Meets minimum criteria. Recommend starting with a 10% trial.';
}

/**
 * Check for models eligible for promotion.
 * @param {Object} brain - Brain module
 * @returns {{ candidates: Array, alertsCreated: number }}
 */
function checkPromotions(brain) {
  const promotionCandidates = brain.getPromotionCandidates();
  let alertsCreated = 0;

  for (const candidate of promotionCandidates) {
    // Skip if already fully promoted
    if (candidate.rollout_pct >= 1.0) continue;

    // Skip if recently alerted
    if (candidate.last_promotion_alert) {
      const daysSince = (Date.now() - new Date(candidate.last_promotion_alert).getTime()) / 86400000;
      if (daysSince < PROMOTION_CRITERIA.minDaysSinceAlert) continue;
    }

    // Create brain task for user review
    try {
      brain.insertTask({
        title: `Model promotion: ${candidate.model} for ${candidate.task_type}`,
        description: formatPromotionAlert(candidate),
        priority: 'high',
        type: 'once',
        execution: 'manual',
        source: 'training-pipeline',
      });
    } catch (err) {
      console.error(`[promoter] Failed to create task for ${candidate.model}:`, err.message);
      continue;
    }

    // Add briefing item
    try {
      if (brain.insertBriefingItem) {
        brain.insertBriefingItem({
          title: `Shadow model ${candidate.model} ready for promotion (${candidate.task_type})`,
          category: 'training',
          urgency: 'medium',
          context: JSON.stringify({
            model: candidate.model,
            taskType: candidate.task_type,
            avgScore: candidate.avg_score,
            totalEvals: candidate.total_evals,
            trend: candidate.trend,
          }),
        });
      }
    } catch (err) {
      console.error(`[promoter] Failed to create briefing for ${candidate.model}:`, err.message);
    }

    // Update last_promotion_alert timestamp
    try {
      brain.upsertModelTaskScore(candidate.model, candidate.task_type, {
        provider: candidate.provider,
        totalEvals: candidate.total_evals,
        avgScore: candidate.avg_score,
        winCount: candidate.win_count,
        strongWinCount: candidate.strong_win_count,
        avgLatencyMs: candidate.avg_latency_ms,
        score7d: candidate.score_7d,
        score30d: candidate.score_30d,
        trend: candidate.trend,
        lastEvalAt: candidate.last_eval_at,
      });
      // Set last_promotion_alert directly
      brain.getDb().prepare('UPDATE model_task_scores SET last_promotion_alert = datetime("now") WHERE model = ? AND task_type = ?')
        .run(candidate.model, candidate.task_type);
    } catch {}

    alertsCreated++;
  }

  return { candidates: promotionCandidates, alertsCreated };
}

module.exports = {
  checkPromotions,
  formatPromotionAlert,
  buildRecommendation,
  PROMOTION_CRITERIA,
};
