<?php

    function dias_transcurridos($fecha1, $fecha2, $incluir_dia_final = false) {
        $f1 = new DateTime($fecha1);
        $f2 = new DateTime($fecha2);
        
        // Asegurarse de que f1 sea menor o igual que f2
        if ($f1 > $f2) {
            list($f1, $f2) = [$f2, $f1]; // intercambiar si están al revés
        }

        $dias = $f1->diff($f2)->days;

        // Sumar 1 SOLO si el día inicial es 1 (día 1 del mes)
        if ((int)$f1->format('j') === 1) {
            $dias += 1;
        }

        return $dias;
    }
    function calcular_rendimientos_compuestos_por_mes($fecha_inicial, $monto_inicial, $rendimiento_anual, $fecha_final) {
    	 // Si la fecha inicial es igual a la final, no hay rendimientos
        if ($fecha_inicial >= $fecha_final) {
            return [];
        }
        $resultados = [];
        $capital = $monto_inicial;
        $inicio = new DateTime($fecha_inicial);
        $fin = new DateTime($fecha_final);

        while ($inicio < $fin) {
            $ultimo_dia_mes = clone $inicio;
            $ultimo_dia_mes->modify('last day of this month');
            
            $fin_periodo = ($ultimo_dia_mes > $fin) ? clone $fin : $ultimo_dia_mes;
            
            // Determinar si es fin de mes
            $es_fin_de_mes = ($fin_periodo->format('Y-m-d') === $ultimo_dia_mes->format('Y-m-d'));
            
            $dias = dias_transcurridos($inicio->format('Y-m-d'), $fin_periodo->format('Y-m-d'), $es_fin_de_mes);
            
            $rendimiento = ($capital * ($rendimiento_anual / 100) / 365) * $dias;

            $resultados[] = [
                'fecha' => $inicio->format('Y-m-d'),
                'dias' => $dias,
                'capital' => $capital,
                'rendimiento' => $rendimiento,
                'es_fin_de_mes' => $es_fin_de_mes
            ];

            $capital += $rendimiento;
            $inicio = $fin_periodo;
            $inicio->modify('+1 day');
        }

        return $resultados;
    }


    function calcular_rendimientos_detallado($fecha_inicial, $monto_invertido, $rendimiento_anual, $fecha_final) {
        $fecha_inicial = new DateTime($fecha_inicial);
        $fecha_final = new DateTime($fecha_final);

        // Obtener el primer día de cada mes para dividir los periodos
        $periodos = [];
        $current_date = clone $fecha_inicial;
        
        while ($current_date < $fecha_final) {
            // Establecer el final de cada periodo (último día del mes)
            $ultimo_dia_mes = new DateTime($current_date->format('Y-m-t'));
            if ($ultimo_dia_mes > $fecha_final) {
                $ultimo_dia_mes = $fecha_final; // Si el último día de mes es después de la fecha final, tomar la fecha final
            }

            // Calcular los días transcurridos
            $dias = dias_transcurridos($current_date->format('Y-m-d'), $ultimo_dia_mes->format('Y-m-d'));

            // Calcular el rendimiento
            $rendimiento = (($monto_invertido * ($rendimiento_anual / 100)) / 365 ) * $dias;

            // Almacenar el rendimiento para este periodo
            $periodos[] = [
                'fecha' => $current_date->format('Y-m-d'),
                'rendimiento' => $rendimiento,
                'monto' => $monto_invertido
            ];

            // Actualizar el monto invertido
            $monto_invertido += $rendimiento;

            // Avanzar al siguiente mes
            $current_date = clone $ultimo_dia_mes;
            $current_date->modify('+1 day');
        }

        return $periodos;
    }

    /**
     * Calcula el saldo consolidado de un inversionista hasta una fecha dada.
     * @param mysqli $conn Conexión a la base de datos
     * @param int $idinv ID del inversionista
     * @param string $fecha_hasta Fecha límite en formato 'Y-m-d'
     * @return float Saldo disponible hasta la fecha
     */
    function dame_saldo($conn, $idinv, $fecha_hasta) {
        // Obtener movimientos hasta la fecha
        $sql_movimientos = "SELECT idreginv, fecinv as fecha_calculo, mntinv, reninv 
                           FROM inversion 
                           WHERE idinv = ? AND fecinv <= ? 
                           ORDER BY  fecinv";

        $stmt_movimientos = $conn->prepare($sql_movimientos);
        $stmt_movimientos->bind_param("is", $idinv, $fecha_hasta);
        $stmt_movimientos->execute();
        $result_movimientos = $stmt_movimientos->get_result();

        $eventos = [];

        // Recopilar eventos
        while ($row = $result_movimientos->fetch_assoc()) {
            $fecha_inversion = $row['fecha_calculo'];
            $monto = $row['mntinv'];
            $idreginv = $row['idreginv'];
            $rendimiento_anual = $row['reninv'];

            // Evento de inversión
            $eventos[] = [
                'tipo' => 'inversion',
                'fecha' => $fecha_inversion,
                'monto' => $monto,
                'idreginv' => $idreginv,
                'rendimiento_anual' => $rendimiento_anual
            ];

            // Generar tramos de rendimiento
            $tramos = calcular_rendimientos_compuestos_por_mes($fecha_inversion, $monto, $rendimiento_anual, $fecha_hasta);

            foreach ($tramos as $tramo) {
                $eventos[] = [
                    'tipo' => 'rendimiento',
                    'fecha' => $tramo['fecha'],
                    'monto' => $tramo['rendimiento'],
                    'dias' => $tramo['dias'],
                    'es_fin_de_mes' => $tramo['es_fin_de_mes'],
                    'idreginv' => $idreginv,
                    'rendimiento_anual' => $rendimiento_anual
                ];
            }
        }

        // Ordenar eventos
        usort($eventos, function($a, $b) {
            if ($a['fecha'] === $b['fecha']) {
                return ($a['tipo'] === 'inversion') ? -1 : 1;
            }
            return strcmp($a['fecha'], $b['fecha']);
        });

        // Calcular saldo acumulado
        $saldo = 0;

        foreach ($eventos as $evento) {
            if ($evento['tipo'] === 'inversion') {
                $saldo += $evento['monto'];
            } elseif ($evento['tipo'] === 'rendimiento') {
                $saldo += $evento['monto'];
            }
        }

        return $saldo;
    }

?>
