'use strict';

const { complexityToModelTier } = require('./tier-selector');

const CRITICAL_KEYWORDS = [
  'production', 'deploy', 'security', 'auth', 'credential',
  'payment', 'database migration', 'delete', 'drop table', 'rm -rf'
];

const COMPLEX_KEYWORDS = [
  'architecture', 'refactor', 'debug', 'optimize', 'design',
  'trade-off', 'tradeoff', 'compare'
];

const SIMPLE_KEYWORDS = [
  'hello', 'hi', 'thanks', 'what is', 'define'
];

const TIER_MAP = {
  simple:   { quorumSize: 1 },
  moderate: { quorumSize: 2 },
  complex:  { quorumSize: 3 },
  critical: { quorumSize: 5 },
};

/**
 * Assess the complexity of a task to determine quorum size.
 * @param {Object} task
 * @param {string} task.content - The task text/prompt
 * @param {string} [task.type] - Task type hint: 'chat', 'coding', 'extraction', etc.
 * @param {Object} [task.metadata] - Additional context
 * @returns {{ tier: string, quorumSize: number, reasoning: string, signals: Object }}
 */
function assessComplexity(task) {
  const content = task.content || '';
  const type = task.type || null;
  const lower = content.toLowerCase();

  // Compute signals
  const signals = computeSignals(content, lower);

  // Determine tier
  let tier = determineTier(signals, lower);

  // Apply type hint overrides
  if (type === 'coding' && tier === 'simple') {
    tier = 'moderate';
  }

  const reasoning = buildReasoning(tier, signals, type);

  return {
    tier,
    modelTier: complexityToModelTier(tier),
    quorumSize: TIER_MAP[tier].quorumSize,
    reasoning,
    signals,
  };
}

function computeSignals(content, lower) {
  const charCount = content.length;
  const wordCount = content.split(/\s+/).filter(Boolean).length;
  const hasCode = /```/.test(content) || /^(    |\t)\S/m.test(content);
  const hasQuestion = content.includes('?');

  // Ambiguity: multiple questions, "or"/"either", vague language
  const questionCount = (content.match(/\?/g) || []).length;
  const hasDisjunction = /\b(or|either|maybe|possibly|might)\b/i.test(content);
  const isAmbiguous = questionCount > 1 || hasDisjunction;

  // Domain keywords
  const domainKeywords = [];
  for (const kw of CRITICAL_KEYWORDS) {
    if (lower.includes(kw)) domainKeywords.push(kw);
  }
  for (const kw of COMPLEX_KEYWORDS) {
    if (lower.includes(kw)) domainKeywords.push(kw);
  }
  for (const kw of SIMPLE_KEYWORDS) {
    if (lower.includes(kw)) domainKeywords.push(kw);
  }

  // Estimated steps: rough heuristic
  let estimatedSteps = 1;
  if (charCount > 200) estimatedSteps++;
  if (charCount > 500) estimatedSteps++;
  if (charCount > 1000) estimatedSteps++;
  if (hasCode) estimatedSteps++;
  if (questionCount > 1) estimatedSteps += questionCount - 1;

  return {
    charCount,
    wordCount,
    hasCode,
    hasQuestion,
    isAmbiguous,
    domainKeywords,
    estimatedSteps,
  };
}

function determineTier(signals, lower) {
  const { charCount, hasCode, hasQuestion, isAmbiguous, domainKeywords, estimatedSteps } = signals;

  // Critical: any critical keyword present
  const hasCritical = CRITICAL_KEYWORDS.some(kw => lower.includes(kw));
  if (hasCritical) return 'critical';

  // Complex: complex keywords, or long with code, or ambiguous with significant length
  const hasComplex = COMPLEX_KEYWORDS.some(kw => lower.includes(kw));
  if (hasComplex) return 'complex';
  if (charCount > 1000 && hasCode) return 'complex';
  if (charCount > 1000 && isAmbiguous) return 'complex';

  // Moderate: multi-step reasoning, code, how/why questions, medium length
  if (hasCode) return 'moderate';
  if (charCount >= 200) return 'moderate';
  if (/\b(how|why)\b/i.test(lower) && !SIMPLE_KEYWORDS.some(kw => lower.includes(kw))) return 'moderate';
  if (estimatedSteps >= 3) return 'moderate';

  // Check for coding-related terms that suggest moderate
  if (/\b(write|implement|create|build|function|class|module|api)\b/i.test(lower) && charCount > 30) return 'moderate';

  return 'simple';
}

function buildReasoning(tier, signals, type) {
  const parts = [];
  parts.push(`Tier: ${tier}`);

  if (signals.domainKeywords.length > 0) {
    parts.push(`matched keywords: ${signals.domainKeywords.join(', ')}`);
  }
  parts.push(`${signals.charCount} chars, ${signals.wordCount} words`);
  if (signals.hasCode) parts.push('contains code');
  if (signals.hasQuestion) parts.push('contains question');
  if (signals.isAmbiguous) parts.push('ambiguous/multi-part');
  if (type) parts.push(`type hint: ${type}`);

  return parts.join('; ');
}

module.exports = { assessComplexity };
