/**
 * Composable for real-time vote formula computation.
 *
 * Re-exports and wraps the threshold utility functions for reactive use
 * in Vue components. Provides convenient methods for threshold calculations,
 * inertia factor, required ratio, and adoption checks.
 */
import { wotThreshold, smithThreshold, techcommThreshold } from '~/utils/threshold'

export interface FormulaParams {
  majority_pct: number
  base_exponent: number
  gradient_exponent: number
  constant_base: number
}

export function useVoteFormula() {
  /**
   * Compute the WoT threshold for a given set of parameters.
   */
  function computeThreshold(wotSize: number, totalVotes: number, params: FormulaParams): number {
    return wotThreshold(
      wotSize,
      totalVotes,
      params.majority_pct,
      params.base_exponent,
      params.gradient_exponent,
      params.constant_base,
    )
  }

  /**
   * Compute the inertia factor: 1 - (T/W)^G
   * Ranges from ~1 (low participation) to ~0 (full participation).
   */
  function computeInertiaFactor(
    totalVotes: number,
    wotSize: number,
    gradientExponent: number,
  ): number {
    if (wotSize <= 0 || totalVotes <= 0) return 1.0
    const participationRatio = totalVotes / wotSize
    return 1.0 - Math.pow(participationRatio, gradientExponent)
  }

  /**
   * Compute the required ratio of "pour" votes at a given participation level.
   * requiredRatio = M + (1 - M) * inertiaFactor
   */
  function computeRequiredRatio(
    totalVotes: number,
    wotSize: number,
    majorityPct: number,
    gradientExponent: number,
  ): number {
    const M = majorityPct / 100
    const inertia = computeInertiaFactor(totalVotes, wotSize, gradientExponent)
    return M + (1.0 - M) * inertia
  }

  /**
   * Check whether a vote is adopted given all criteria.
   * A vote is adopted when it passes the WoT threshold AND
   * any applicable Smith/TechComm criteria.
   */
  function isAdopted(
    votesFor: number,
    threshold: number,
    smithVotesFor?: number,
    smithThresholdVal?: number,
    techcommVotesFor?: number,
    techcommThresholdVal?: number,
  ): boolean {
    // Main WoT criterion
    if (votesFor < threshold) return false

    // Smith criterion (if applicable)
    if (smithThresholdVal !== undefined && smithThresholdVal > 0) {
      if ((smithVotesFor ?? 0) < smithThresholdVal) return false
    }

    // TechComm criterion (if applicable)
    if (techcommThresholdVal !== undefined && techcommThresholdVal > 0) {
      if ((techcommVotesFor ?? 0) < techcommThresholdVal) return false
    }

    return true
  }

  return {
    computeThreshold,
    computeInertiaFactor,
    computeRequiredRatio,
    isAdopted,
    smithThreshold,
    techcommThreshold,
  }
}
