<?php
/**
 * SAC 2026 - MASTER REGISTER PAYMENT v26.2 (KERNEL CACHE SYNC)
 * Kernel V4.1.87: Soporte para slots de tasa (AM/PM/Parallel) y reparación nuclear.
 */
require_once 'config.php';

if (!isset($_SESSION['user_id'])) response(["error" => "No autorizado"], 401);

$data = $REQUEST_DATA;
if (!$data || !isset($data['feeId']) || !isset($data['propertyId'])) {
    response(["error" => "Parámetros incompletos"], 400);
}

try {
    $pdo->beginTransaction();

    $feeId = $data['feeId'];
    $propertyId = (int)$data['propertyId'];
    $montoEnviadoBs = (float)($data['amount_bs'] ?? 0); 
    $montoTotalUsd = round((float)($data['amount'] ?? 0), 2); 
    $method = $data['method'] ?? 'Transferencia';
    $reference = $data['reference'] ?? 'S/R';
    $paymentDate = $data['date'] ?? date('Y-m-d');
    $skipCommission = isset($data['skip_commission']) && $data['skip_commission'] === true;
    $timeSlot = $data['slot'] ?? 'pm';

    // --- FASE 1: CERROJO DE DEUDA HISTÓRICA ---
    $stmtProp = $pdo->prepare("SELECT id, code, initial_debt FROM properties WHERE id = ? FOR UPDATE");
    $stmtProp->execute([$propertyId]);
    $prop = $stmtProp->fetch();
    $propCode = $prop['code'];
    $initialDebtOriginal = (float)$prop['initial_debt'];

    $remainingPayment = $montoTotalUsd;
    $remainingPaymentBs = $montoEnviadoBs;

    $isCash = stripos($method, 'Efectivo') !== false;
    $descType = $isCash ? " (EFECTIVO/CAJA)" : " (Ref: $reference)";

    if ($initialDebtOriginal > 0 && $remainingPayment > 0) {
        $absorbed = min($remainingPayment, $initialDebtOriginal);
        $absorbedBs = ($montoTotalUsd > 0) ? ($montoEnviadoBs * ($absorbed / $montoTotalUsd)) : 0;

        $newInitialDebt = round($initialDebtOriginal - $absorbed, 2);
        $pdo->prepare("UPDATE properties SET initial_debt = ? WHERE id = ?")->execute([$newInitialDebt, $propertyId]);
        
        $bankIn = $pdo->prepare("INSERT INTO bank_transactions (date, description, amount_usd, amount_bs, type, category, reference) VALUES (?, ?, ?, ?, 'Ingreso', 'Ingresos', ?)");
        $bankIn->execute([$paymentDate, "RECUPERACIÓN DEUDA HISTÓRICA: $propCode" . $descType, $absorbed, $absorbedBs, $reference]);
        
        if (!$isCash && !$skipCommission) {
            $stmtSet = $pdo->prepare("SELECT setting_value FROM system_settings WHERE setting_key = 'bank_comm_income'");
            $stmtSet->execute();
            $pct = (float)($stmtSet->fetchColumn() ?: 1.5);
            if ($pct > 0) {
                $commBs = round(($absorbedBs * $pct) / 100, 2);
                $appliedRate = ($absorbed > 0) ? ($absorbedBs / $absorbed) : 45.0;
                $commUsd = round($commBs / $appliedRate, 2);
                $pdo->prepare("INSERT INTO bank_transactions (date, description, amount_usd, amount_bs, type, category, reference) VALUES (?, ?, ?, ?, 'Egreso', 'Comisiones', ?)")
                    ->execute([$paymentDate, "COMISIÓN RECUPERACIÓN HISTÓRICA: $propCode", $commUsd, $commBs, $reference]);
            }
        }

        // MOTOR DE ARCHIVO
        if ($newInitialDebt <= 0) {
            $stmtH = $pdo->prepare("SELECT date, description, amount_usd, reference FROM bank_transactions WHERE (description LIKE ? OR description LIKE ?) ORDER BY date ASC");
            $stmtH->execute(["%DEUDA HISTÓRICA: $propCode%", "%DEUDA ANTERIOR: $propCode%"]);
            $historyRaw = $stmtH->fetchAll();

            // REPARACIÓN NUCLEAR: Filtrado estricto para evitar colisiones (ej: prop 7 vs 70)
            $history = array_filter($historyRaw, function($h) use ($propCode) {
                $desc = $h['description'];
                $pattern = "/RECUPERACIÓN DEUDA (HISTÓRICA|ANTERIOR): " . preg_quote($propCode) . "([^0-9]|$)/";
                return preg_match($pattern, $desc);
            });

            $totalSaldado = 0;
            foreach($history as $h) { $totalSaldado += (float)$h['amount_usd']; }
            $stmtU = $pdo->prepare("SELECT u.full_name FROM residents r JOIN users u ON r.user_id = u.id WHERE r.property_id = ? AND r.is_owner = 1 LIMIT 1");
            $stmtU->execute([$propertyId]);
            $oName = $stmtU->fetchColumn() ?: 'S/N';
            $stmtArch = $pdo->prepare("INSERT INTO payment_agreements_archive (property_id, code, owner_name, original_amount, completion_date, payment_history_json) VALUES (?, ?, ?, ?, CURDATE(), ?)");
            $stmtArch->execute([$propertyId, $propCode, $oName, $totalSaldado, json_encode($history)]);
        }

        $remainingPayment = round($remainingPayment - $absorbed, 2);
        $remainingPaymentBs = round($remainingPaymentBs - $absorbedBs, 2);
    }

    // --- FASE 2: LÓGICA CUOTA ACTUAL Y EXCEDENTES ---
    if ($remainingPayment > 0) {
        $montoTotalUsd = $remainingPayment;
        $montoEnviadoBs = $remainingPaymentBs;

        $bankIn = $pdo->prepare("INSERT INTO bank_transactions (date, description, amount_usd, amount_bs, type, category, reference) VALUES (?, ?, ?, ?, 'Ingreso', 'Ingresos', ?)");
        $bankIn->execute([$paymentDate, "LIQUIDACIÓN CUOTA MES: $propCode" . $descType, $montoTotalUsd, $montoEnviadoBs, $reference]);

        if (!$isCash && !$skipCommission) {
            $stmtSet = $pdo->prepare("SELECT setting_value FROM system_settings WHERE setting_key = 'bank_comm_income'");
            $stmtSet->execute();
            $pct = (float)($stmtSet->fetchColumn() ?: 1.5);
            if ($pct > 0) {
                $commBs = round(($montoEnviadoBs * $pct) / 100, 2);
                $appliedRate = ($montoTotalUsd > 0) ? ($montoEnviadoBs / $montoTotalUsd) : 45.0;
                $commUsd = round($commBs / $appliedRate, 2);
                $pdo->prepare("INSERT INTO bank_transactions (date, description, amount_usd, amount_bs, type, category, reference) VALUES (?, ?, ?, ?, 'Egreso', 'Comisiones', ?)")
                    ->execute([$paymentDate, "COMISIÓN PAGO CUOTA/EXCEDENTE: $propCode", $commUsd, $commBs, $reference]);
            }
        }

        $stmtDebt = $pdo->prepare("SELECT id, amount_usd, paid_amount FROM property_debts WHERE fee_id = ? AND property_id = ?");
        $stmtDebt->execute([$feeId, $propertyId]);
        $debtRow = $stmtDebt->fetch();

        if ($debtRow) {
            $deudaMes = round((float)$debtRow['amount_usd'] - (float)$debtRow['paid_amount'], 2);
            $abono = min($montoTotalUsd, $deudaMes);
            if ($abono > 0) {
                $pdo->prepare("INSERT INTO payments (debt_id, amount_usd, method, reference, payment_date, time_slot) VALUES (?, ?, ?, ?, ?, ?)")
                    ->execute([$debtRow['id'], $abono, $method, $reference, $paymentDate, $timeSlot]);
                $nuevoPagado = round((float)$debtRow['paid_amount'] + $abono, 2);
                $nuevoStatus = ($nuevoPagado >= ((float)$debtRow['amount_usd'] - 0.01)) ? 'Pagado' : 'Parcial';
                $pdo->prepare("UPDATE property_debts SET paid_amount = ?, status = ? WHERE id = ?")->execute([$nuevoPagado, $nuevoStatus, $debtRow['id']]);
                $montoTotalUsd = round($montoTotalUsd - $abono, 2);
            }
        }

        if ($montoTotalUsd > 0) {
            $pdo->prepare("UPDATE properties SET credit_balance = credit_balance + ? WHERE id = ?")->execute([$montoTotalUsd, $propertyId]);
            $pdo->prepare("INSERT INTO credit_movements (property_id, fee_id, amount_usd, source_reference, method_origin, type, description) VALUES (?, ?, ?, ?, ?, 'Generado', 'Sobrante a saldo a favor')")
                ->execute([$propertyId, $feeId, $montoTotalUsd, $reference, $method]);
        }
    }

    $pdo->commit();
    logSystemAction("REGISTRÓ PAGO: Unidad $propCode por $$montoTotalUsd Ref: $reference", "PAGOS");
    response(["success" => true]);
} catch (Exception $e) {
    if ($pdo && $pdo->inTransaction()) $pdo->rollBack();
    response(["error" => "Error Nuclear: " . $e->getMessage()], 500);
}
?>