import { VariantCalculations } from "@/types/salary";
import { calculateNetSalary } from "../netSalary";
import { NetSalarySeekOptions } from "./types";

export class NetSalaryGoalSeek {
    seek(
        netSalary: number,
        { tolerancePercentage = 0.0001, ...options }: NetSalarySeekOptions
    ): [number, VariantCalculations] {
        const MAX_INT = 2 ** 31 - 1;

        let lowestGrossSalary = netSalary,
            highestGrossSalary = MAX_INT;

        while (lowestGrossSalary <= highestGrossSalary) {
            const grossSalary =
                lowestGrossSalary +
                (highestGrossSalary - lowestGrossSalary) / 2;

            const [approximateNetSalary, variantCalculations] =
                calculateNetSalary({
                    grossSalary,
                    ...options,
                });

            const errorPercentage =
                (Math.abs(approximateNetSalary - netSalary) / netSalary) * 100;

            if (errorPercentage <= tolerancePercentage)
                return [grossSalary, variantCalculations];
            else if (approximateNetSalary < netSalary)
                lowestGrossSalary = grossSalary + tolerancePercentage;
            else highestGrossSalary = grossSalary - tolerancePercentage;
        }

        return [-1, {} as VariantCalculations];
    }
}
