import { formatIDR } from '@/lib/formatters';
import type { FinancingCalculation, FinancingProduct } from '@/types/financing';

/**
 * Safely convert a value to a number with a default fallback
 */
export const toNumber = (value: unknown, defaultValue: number = 0): number => {
    const num = Number(value);
    return Number.isNaN(num) ? defaultValue : num;
};

/**
 * Calculate financing details based on product and requested amount
 */
export function calculateFinancing(
    productId: number | string,
    amount: number | string,
    products: FinancingProduct[],
): FinancingCalculation | null {
    const pId = Number(productId) || 0;
    const rawAmount = Number(amount) || 0;

    if (!pId || !rawAmount || rawAmount <= 0) {
        return null;
    }

    const product = products.find((p) => p.id === pId);

    if (!product) return null;

    // Safely extract all product fields as numbers
    const marginRate = toNumber(product.margin_rate, 0);
    const installmentCount = toNumber(product.installment_count, 1);
    const administrationFee = toNumber(product.administration_fee, 0);
    const provisionFee = toNumber(product.provision_fee, 0);
    const notaryFee = toNumber(product.notary_fee, 0);
    const surveyFee = toNumber(product.survey_fee, 0);
    const minimumAmount = toNumber(product.minimum_amount, 0);
    const maximumAmount = toNumber(product.maximum_amount, Infinity);

    // Validate amount range
    if (rawAmount < minimumAmount || rawAmount > maximumAmount) {
        return {
            valid: false,
            principal: rawAmount,
            margin: 0,
            total: 0,
            daily: 0,
            adminFee: 0,
            provisiFee: 0,
            notaryFee: 0,
            surveyFee: 0,
            totalFees: 0,
            totalDisbursement: 0,
            installmentCount: 0,
            marginRate: 0,
            error: `Jumlah harus antara ${formatIDR(minimumAmount)} dan ${formatIDR(maximumAmount)}`,
        };
    }

    const principal = rawAmount;
    const margin = principal * (marginRate / 100);
    const total = principal + margin;

    // Prevent division by zero
    const dailyInstallment =
        installmentCount > 0 ? total / installmentCount : 0;
    const adminFee = administrationFee;
    const provisiFee = total * (provisionFee / 100);
    const totalFees =
        toNumber(adminFee) +
        toNumber(provisiFee) +
        toNumber(notaryFee) +
        toNumber(surveyFee);
    const totalDisbursement = principal + totalFees;

    return {
        valid: true,
        principal: toNumber(principal, 0),
        margin: toNumber(margin, 0),
        total: toNumber(total, 0),
        daily: toNumber(dailyInstallment, 0),
        adminFee: toNumber(adminFee, 0),
        provisiFee: toNumber(provisiFee, 0),
        notaryFee: toNumber(notaryFee, 0),
        surveyFee: toNumber(surveyFee, 0),
        totalFees: toNumber(totalFees, 0),
        totalDisbursement: toNumber(totalDisbursement, 0),
        installmentCount: toNumber(installmentCount, 1),
        marginRate: toNumber(marginRate, 0),
    };
}
