<?php
declare(strict_types=1);
require_once dirname(__FILE__) . '/../config.php';

if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
    jsonErr(405, 'Metodo no permitido.');
}

$jwt   = auth();
$idinv = (int)$jwt['idinv'];
$db    = getDB();

// Período: mes actual (o parámetros opcionales)
$anio = isset($_GET['anio']) ? (int)$_GET['anio'] : (int)date('Y');
$mes  = isset($_GET['mes'])  ? (int)$_GET['mes']  : (int)date('m');
$mesInicio = sprintf('%04d-%02d-01', $anio, $mes);
$mesFin    = date('Y-m-t', strtotime($mesInicio));

$MAX_NIVELES = 18;

// Porcentajes de ganancia por nivel
$PORCENTAJES = [
    1  => 0.10,
    2  => 0.17,
    3  => 0.17,
    4  => 0.17,
    5  => 0.01,
    6  => 0.01,
    7  => 0.01,
    8  => 0.01,
    9  => 0.01,
    10 => 0.01,
    11 => 0.01,
    12 => 0.01,
    13 => 0.01,
    14 => 0.01,
    15 => 0.01,
    16 => 0.01,
    17 => 0.01,
    18 => 0.01,
];

try {
    // ── BFS: construir red de 18 niveles ────────────────────────────────────────
    $currentLevel = [$idinv];
    $niveles      = [];
    $allIds       = [];

    // Para calcular directos calificados necesitamos los datos del nivel 1
    $directosData = []; // nivel 1: array de {id_inver, puntos}

    for ($nivel = 1; $nivel <= $MAX_NIVELES; $nivel++) {
        if (empty($currentLevel)) break;

        $placeholders = implode(',', array_fill(0, count($currentLevel), '?'));

        $stmt = $db->prepare(
            "SELECT 
                i.id_inver,
                i.referencia,
                i.nombre,
                i.appat,
                i.apmat,
                COALESCE(SUM(d.puntos), 0) AS puntos
             FROM inversionista i
             LEFT JOIN transacciones t 
                ON t.inversionista_id_inver = i.id_inver
                AND t.fechat BETWEEN ? AND ?
             LEFT JOIN depositos d 
                ON d.transacciones_idtransacciones = t.idtransacciones
             WHERE i.idprom IN ($placeholders)
             GROUP BY i.id_inver
             ORDER BY puntos DESC, i.appat ASC, i.nombre ASC"
        );

        $params = array_merge([$mesInicio, $mesFin], $currentLevel);
        $stmt->execute($params);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

        $nextLevel         = [];
        $personasConPuntos = [];
        $totalPuntos       = 0.0;

        foreach ($rows as $row) {
            $id = (int)$row['id_inver'];
            if (in_array($id, $allIds, true)) continue;
            $allIds[]    = $id;
            $nextLevel[] = $id;

            $puntos = (float)$row['puntos'];

            // Guardar datos de directos (nivel 1) para calcular niveles abiertos
            if ($nivel === 1) {
                $directosData[] = ['id_inver' => $id, 'puntos' => $puntos];
            }

            if ($puntos > 0) {
                $personasConPuntos[] = [
                    'id_inver'        => $id,
                    'referencia'      => $row['referencia'] ?? '',
                    'nombre_completo' => trim(
                        ($row['nombre'] ?? '') . ' ' .
                        ($row['appat']  ?? '') . ' ' .
                        ($row['apmat']  ?? '')
                    ),
                    'puntos'          => $puntos,
                ];
                $totalPuntos += $puntos;
            }
        }

        if (!empty($personasConPuntos)) {
            $niveles[$nivel] = [
                'nivel'          => $nivel,
                'personas'       => $personasConPuntos,
                'total_personas' => count($personasConPuntos),
                'total_puntos'   => $totalPuntos,
            ];
        }

        $currentLevel = $nextLevel;
    }

    // ── Totales generales ────────────────────────────────────────────────────────
    $totalPersonas      = 0;
    $totalPuntosGeneral = 0.0;
    foreach ($niveles as $n) {
        $totalPersonas      += $n['total_personas'];
        $totalPuntosGeneral += $n['total_puntos'];
    }

    // ── Puntos propios del período ───────────────────────────────────────────────
    $stmtPropios = $db->prepare(
        "SELECT COALESCE(SUM(d.puntos), 0) AS puntos_propios
         FROM transacciones t
         JOIN depositos d ON t.idtransacciones = d.transacciones_idtransacciones
         WHERE t.inversionista_id_inver = ?
           AND t.fechat BETWEEN ? AND ?"
    );
    $stmtPropios->execute([$idinv, $mesInicio, $mesFin]);
    $rowPropios    = $stmtPropios->fetch(PDO::FETCH_ASSOC);
    $puntosPropios = (float)($rowPropios['puntos_propios'] ?? 0);

    // ── Calificación del usuario ─────────────────────────────────────────────────
    // < 624: no calificado | 624–1499: parcial | >= 1500: completo
    if ($puntosPropios < 624) {
        $calificacion = 'no_calificado';
    } elseif ($puntosPropios < 1500) {
        $calificacion = 'parcial';
    } else {
        $calificacion = 'calificado';
    }

    // ── Calcular directos calificados ────────────────────────────────────────────
    $directos624  = 0; // directos con >= 624 pts
    $directos1500 = 0; // directos con >= 1500 pts
    foreach ($directosData as $d) {
        if ($d['puntos'] >= 624)  $directos624++;
        if ($d['puntos'] >= 1500) $directos1500++;
    }

    // ── Determinar niveles abiertos ──────────────────────────────────────────────
    // Reglas:
    //   - No calificado: 0 niveles
    //   - Parcial (624–1499): máximo 1 nivel, solo si tiene al menos 1 directo con 624+
    //   - Calificado (1500+):
    //       * Base: 1 nivel por cada directo con 624+ pts
    //       * Regla especial: 2 directos con 1500+ → 3 niveles en total
    //       * Regla especial: 3 directos con 1500+ → 5 niveles en total
    //       * Para nivel 6+: se necesitan 6+ directos con 624+
    //       * Máximo 13 niveles

    $nivelesAbiertos = 0;

    if ($calificacion === 'no_calificado') {
        $nivelesAbiertos = 0;

    } elseif ($calificacion === 'parcial') {
        // Solo nivel 1 si tiene al menos 1 directo calificado
        $nivelesAbiertos = ($directos624 >= 1) ? 1 : 0;

    } else {
        // Calificado completo (1500+)
        // Base: 1 nivel por directo con 624+
        $nivelesBase = $directos624;

        // Regla especial por directos con 1500+
        if ($directos1500 >= 3) {
            // 3 directos con 1500+ abren hasta nivel 5
            $nivelesEspecial = 5;
        } elseif ($directos1500 >= 2) {
            // 2 directos con 1500+ abren hasta nivel 3
            $nivelesEspecial = 3;
        } else {
            $nivelesEspecial = 0;
        }

        // Se toma el mayor entre la base y la regla especial
        $nivelesAbiertos = max($nivelesBase, $nivelesEspecial);
        // Para niveles 6 en adelante se necesitan 6+ directos con 624+
        // La regla especial (2 con 1500=3, 3 con 1500=5) aplica solo hasta nivel 5
        // Para nivel 6+ simplemente se necesitan N directos con 624+
        $nivelesAbiertos = min($nivelesAbiertos, $MAX_NIVELES);
    }

    // ── Calcular tabla de ganancias ──────────────────────────────────────────────
    $tablaGanancias = [];
    $totalGenerado  = 0.0;
    $totalRecibir   = 0.0;

    for ($n = 1; $n <= $MAX_NIVELES; $n++) {
        $puntosNivel  = isset($niveles[$n]) ? (float)$niveles[$n]['total_puntos'] : 0.0;
        $porcentaje   = $PORCENTAJES[$n] ?? 0.01;
        $generado     = $puntosNivel * $porcentaje;
        $recibir      = ($n <= $nivelesAbiertos) ? $generado : 0.0;

        $totalGenerado += $generado;
        $totalRecibir  += $recibir;

        $tablaGanancias[] = [
            'nivel'      => $n,
            'porcentaje' => $porcentaje * 100, // en %
            'puntos'     => $puntosNivel,
            'generado'   => round($generado, 2),
            'recibir'    => round($recibir, 2),
            'abierto'    => ($n <= $nivelesAbiertos),
        ];
    }

    jsonOk([
        'periodo' => [
            'anio'   => $anio,
            'mes'    => $mes,
            'inicio' => $mesInicio,
            'fin'    => $mesFin,
        ],
        'niveles'             => array_values($niveles),
        'total_personas'      => $totalPersonas,
        'total_puntos'        => $totalPuntosGeneral,
        'niveles_con_datos'   => count($niveles),
        'puntos_propios'      => $puntosPropios,
        'calificacion'        => $calificacion,
        'directos_624'        => $directos624,
        'directos_1500'       => $directos1500,
        'niveles_abiertos'    => $nivelesAbiertos,
        'tabla_ganancias'     => $tablaGanancias,
        'total_generado'      => round($totalGenerado, 2),
        'total_recibir'       => round($totalRecibir, 2),
    ]);

} catch (Throwable $e) {
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'message' => 'Error interno: ' . $e->getMessage(),
    ], JSON_UNESCAPED_UNICODE);
    exit;
}
