# typed: strict
# frozen_string_literal: true

module Stats
  class PolynomialEquation < Equation
    extend T::Sig

    sig do
      params(x: Stats::Axis, y: Stats::Axis, coefficients: T::Array[Float]).void
    end
    def initialize(x, y, coefficients)
      super(x, y)
      @coefficients = T.let(coefficients, T::Array[Float])
    end

    # Public method to get coefficients
    sig(:final) { override.returns(T::Array[Float]) }
    def coefficients
      @coefficients
    end

    # Evaluate the polynomial equation for a given x value
    sig(:final) { override.params(x_value: Float).returns(Float) }
    def evaluate_normalized(x_value)
      result = @coefficients.last
      return 0.0 if result.nil?

      # Use Horner's method for efficient polynomial evaluation
      (@coefficients[0...-1] || []).reverse_each do |coeff|
        result = result * x_value + coeff
      end
      result
    end

    protected

    sig { override.returns(String) }
    def format_equation
      "y = #{polynomial_equation(@coefficients)}"
    end

    private

    # Convert array of coefficients into polynomial equation string
    sig { params(coefficients: T::Array[Float]).returns(String) }
    def polynomial_equation(coefficients)
      terms =
        coefficients.each_with_index.map do |coeff, power|
          next if coeff.zero?

          term = Stats::Helpers.format_number(coeff)
          case power
          when 0
            term
          when 1
            "#{term}x"
          else
            "#{term}x#{power.to_s.tr("0123456789", "⁰¹²³⁴⁵⁶⁷⁸⁹")}"
          end
        end

      terms.compact.reverse.join(" + ").gsub("+ -", "- ")
    end
  end
end
