/**
 * Harmony Score Calculation
 *
 * Design intent:
 * - Influence adapts; people are not judged.
 * - Guidance replaces punishment.
 * - Fit emerges naturally.
 *
 * Philosophy:
 * - Score is private, decays over time, and is reversible.
 * - Never bans or removes beliefs.
 * - Shapes distribution width, not access.
 *
 * Inputs:
 * - Blocks received (pattern-based, not single incidents)
 * - Trusted reports (from high-harmony users)
 * - Category friction (posting to sensitive categories with low CIS)
 * - Posting cadence (erratic spikes vs steady participation)
 * - Rewrite prompts triggered (content rejected for tone)
 * - False reports made (reports that were dismissed)
 *
 * Effects:
 * - Shapes distribution width (reach)
 * - Adds gentle posting friction if low
 * - Limits Trending eligibility
 */

export interface HarmonyInputs {
  user_id: string;
  blocks_received_7d: number;
  blocks_received_30d: number;
  trusted_reports_against: number;
  total_reports_against: number;
  posts_rejected_7d: number; // rewrite prompts triggered
  posts_created_7d: number;
  false_reports_filed: number; // reports dismissed after review
  validated_reports_filed: number; // reports confirmed after review
  days_since_signup: number;
  current_harmony_score: number;
  current_tier: string;
}

export interface HarmonyAdjustment {
  new_score: number;
  delta: number;
  reason: string;
  new_tier: string;
}

/**
 * Calculate harmony score adjustment based on recent behavior
 */
export function calculateHarmonyAdjustment(inputs: HarmonyInputs): HarmonyAdjustment {
  let delta = 0;
  const reasons: string[] = [];

  // 1. Blocks received (pattern-based)
  // Single block = minor signal. Pattern of blocks = strong negative signal.
  if (inputs.blocks_received_7d >= 3) {
    delta -= 10;
    reasons.push('Multiple blocks received recently');
  } else if (inputs.blocks_received_30d >= 5) {
    delta -= 5;
    reasons.push('Pattern of blocks over time');
  }

  // 2. Trusted reports
  // Reports from high-harmony users are strong negative signals
  if (inputs.trusted_reports_against >= 2) {
    delta -= 8;
    reasons.push('Multiple reports from trusted users');
  } else if (inputs.trusted_reports_against === 1) {
    delta -= 3;
    reasons.push('Report from trusted user');
  }

  // 3. Content rejection rate (rewrite prompts)
  // High rejection rate indicates persistent tone issues
  const rejectionRate =
    inputs.posts_created_7d > 0 ? inputs.posts_rejected_7d / inputs.posts_created_7d : 0;

  if (rejectionRate > 0.3) {
    delta -= 6;
    reasons.push('High content rejection rate');
  } else if (rejectionRate > 0.1) {
    delta -= 2;
    reasons.push('Some content rejected for tone');
  }

  // 4. False reports filed
  // Filing false reports is harmful behavior
  if (inputs.false_reports_filed >= 3) {
    delta -= 7;
    reasons.push('Multiple false reports filed');
  } else if (inputs.false_reports_filed >= 1) {
    delta -= 3;
    reasons.push('False report filed');
  }

  // 5. Positive signals: Validated reports
  // Accurate reporting helps the community
  if (inputs.validated_reports_filed >= 3) {
    delta += 5;
    reasons.push('Helpful reporting behavior');
  } else if (inputs.validated_reports_filed >= 1) {
    delta += 2;
    reasons.push('Validated report filed');
  }

  // 6. Time-based trust growth
  // Steady participation without issues slowly builds trust
  if (inputs.days_since_signup > 90 && delta >= 0) {
    delta += 2;
    reasons.push('Sustained positive participation');
  } else if (inputs.days_since_signup > 30 && delta >= 0) {
    delta += 1;
    reasons.push('Consistent participation');
  }

  // 7. Natural decay toward equilibrium (50)
  // Scores gradually drift back toward 50 over time
  // This ensures old negative signals fade
  if (inputs.current_harmony_score < 45) {
    delta += 1;
    reasons.push('Natural recovery over time');
  } else if (inputs.current_harmony_score > 60) {
    delta -= 1;
    reasons.push('Natural equilibrium adjustment');
  }

  // 8. Calculate new score with bounds [0, 100]
  const new_score = Math.max(0, Math.min(100, inputs.current_harmony_score + delta));

  // 9. Determine tier based on new score
  let new_tier: string;
  if (new_score >= 75) {
    new_tier = 'established';
  } else if (new_score >= 50) {
    new_tier = 'trusted';
  } else if (new_score >= 25) {
    new_tier = 'new';
  } else {
    new_tier = 'restricted';
  }

  return {
    new_score,
    delta,
    reason: reasons.join('; ') || 'No significant changes',
    new_tier,
  };
}

/**
 * Get user-facing explanation of harmony score (without revealing the number)
 */
export function getHarmonyExplanation(tier: string, score: number): string {
  if (tier === 'restricted') {
    return 'Your posts currently have limited reach. This happens when content patterns trigger community concerns. Your reach will naturally restore over time with calm participation.';
  }

  if (tier === 'new') {
    return 'Your posts reach a modest audience while you build trust. Steady participation and helpful contributions will gradually expand your reach.';
  }

  if (tier === 'trusted') {
    return 'Your posts reach a good audience. You have shown consistent, calm participation.';
  }

  if (tier === 'established') {
    return 'Your posts reach a wide audience. You have built strong trust through sustained positive contributions.';
  }

  return 'Your reach is determined by your participation patterns and community response.';
}

/**
 * Determine reach multiplier for feed algorithms
 */
export function getReachMultiplier(tier: string, score: number): number {
  const baseMultiplier: Record<string, number> = {
    restricted: 0.2,
    new: 0.6,
    trusted: 1.0,
    established: 1.4,
  };

  // Fine-tune based on score within tier
  const tierBase = baseMultiplier[tier] || 1.0;
  const scoreAdjustment = (score - 50) / 200; // -0.25 to +0.25

  return Math.max(0.1, tierBase + scoreAdjustment);
}
