import type {
    InvestmentDuration,
    InvestmentProjection,
} from '@/pages/investments/types';

const currencyFormatter = new Intl.NumberFormat('es-US', {
    style: 'currency',
    currency: 'USD',
    minimumFractionDigits: 2,
});

export function formatCurrency(value: number): string {
    return `${currencyFormatter.format(value).replace('$', '')} US$`;
}

/** Normaliza texto del teclado móvil (coma o punto) a número USD. */
export function parseUsdInput(raw: string): number | null {
    const trimmed = raw.trim().replace(/\s/g, '');
    if (trimmed === '' || trimmed === '.' || trimmed === ',') {
        return null;
    }

    const normalized = trimmed.replace(',', '.');
    const n = Number.parseFloat(normalized);

    return Number.isFinite(n) ? n : null;
}

/** Solo dígitos y un separador decimal (para controlar el draft mientras se escribe). */
export function sanitizeUsdDraft(raw: string): string {
    let next = raw.replace(/[^\d.,]/g, '');
    const firstSep = next.search(/[.,]/);

    if (firstSep >= 0) {
        const head = next.slice(0, firstSep + 1);
        const tail = next.slice(firstSep + 1).replace(/[.,]/g, '');
        next = head + tail;
    }

    return next;
}

export function formatUsdDraft(amount: number): string {
    if (!Number.isFinite(amount)) {
        return '';
    }

    const rounded = Math.round(amount * 100) / 100;

    return Number.isInteger(rounded) ? String(rounded) : rounded.toFixed(2);
}

export function clampInvestmentAmount(
    value: number,
    minAmount: number,
    maxAmount: number,
): number {
    return Math.round(Math.min(maxAmount, Math.max(minAmount, value)) * 100) / 100;
}

/**
 * Proyección simple (tipo wizard de invertir): % mensual fijo aplicado cada mes
 * del plazo, usando el capital indicado (p. ej. snapshot al registrar).
 */
export function projectionFromMonthlyPercent(args: {
    principal: number;
    durationMonths: number;
    monthlyReturnPercent: number;
}): {
    monthlyProfit: number;
    totalProfitEstimate: number;
    projectedTotal: number;
} {
    const { principal, durationMonths, monthlyReturnPercent } = args;
    const monthlyProfit = principal * (monthlyReturnPercent / 100);
    const totalProfitEstimate = monthlyProfit * durationMonths;

    return {
        monthlyProfit,
        totalProfitEstimate,
        projectedTotal: principal + totalProfitEstimate,
    };
}

export function calculateProjection({
    amount,
    durationMonths,
    durations,
    monthlyReturn,
}: {
    amount: number;
    durationMonths: number;
    durations: InvestmentDuration[];
    monthlyReturn: number;
}): InvestmentProjection {
    const { monthlyProfit, totalProfitEstimate, projectedTotal } =
        projectionFromMonthlyPercent({
            principal: amount,
            durationMonths,
            monthlyReturnPercent: monthlyReturn,
        });

    return {
        amount,
        durationMonths,
        monthlyReturn,
        monthlyProfit,
        totalProfit: totalProfitEstimate,
        projectedTotal,
        totalReturn: monthlyReturn * durationMonths,
        selectedDuration:
            durations.find((duration) => duration.months === durationMonths) ??
            durations[0],
    };
}
