<?php

declare(strict_types=1);

require_once __DIR__ . '/init.php';

function af_payment_has_column(PDO $pdo, string $table, string $column): bool
{
    $stmt = $pdo->prepare(
        'SELECT COUNT(*) FROM information_schema.COLUMNS
         WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?'
    );
    $stmt->execute([$table, $column]);
    return (int) $stmt->fetchColumn() > 0;
}

function af_payment_money(mixed $value): float
{
    return is_numeric($value) ? (float) $value : 0.0;
}

function af_payment_state_label(string $state): string
{
    return $state === 'anulado' ? 'Anulado' : 'Confirmado';
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    Security::headers(true);
    Security::requireCsrf();

    $action = trim((string) ($_POST['action'] ?? ''));
    $paymentId = filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT) ?: 0;

    try {
        if ($paymentId <= 0) {
            throw new InvalidArgumentException('El pago seleccionado no es válido.');
        }

        if ($action === 'set_payment_status_ajax') {
            $newState = trim((string) ($_POST['estado'] ?? ''));
            if (!in_array($newState, ['confirmado', 'anulado'], true)) {
                throw new InvalidArgumentException('El estado solicitado no es válido.');
            }

            $pdo->beginTransaction();
            $stmt = $pdo->prepare(
                "SELECT p.id, COALESCE(p.estado_pago, 'confirmado') AS estado_pago,
                        EXISTS(
                            SELECT 1 FROM beneficios_referidos br
                            WHERE br.id_pago = p.id AND br.estado = 'otorgado'
                        ) AS tiene_beneficio
                 FROM pagos p
                 WHERE p.id = ?
                 LIMIT 1
                 FOR UPDATE"
            );
            $stmt->execute([$paymentId]);
            $payment = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$payment) {
                throw new RuntimeException('El pago ya no existe.');
            }
            if ((string) $payment['estado_pago'] === $newState) {
                $pdo->commit();
                Security::json([
                    'success' => true,
                    'message' => 'El pago ya se encuentra ' . mb_strtolower(af_payment_state_label($newState), 'UTF-8') . '.',
                ]);
            }
            if ((int) ($payment['tiene_beneficio'] ?? 0) === 1) {
                throw new RuntimeException(
                    'Este pago generó un beneficio de referido. Para evitar alterar la vigencia del referente, revísalo primero desde Referidos.'
                );
            }

            $update = $pdo->prepare('UPDATE pagos SET estado_pago = ? WHERE id = ?');
            $update->execute([$newState, $paymentId]);
            $pdo->commit();

            Security::json([
                'success' => true,
                'message' => $newState === 'anulado'
                    ? 'Pago anulado correctamente. La vigencia de la suscripción no fue modificada.'
                    : 'Pago restaurado como confirmado.',
            ]);
        }

        if ($action === 'delete_payment_ajax') {
            $pdo->beginTransaction();
            $stmt = $pdo->prepare(
                "SELECT p.id, COALESCE(p.estado_pago, 'confirmado') AS estado_pago,
                        EXISTS(SELECT 1 FROM beneficios_referidos br WHERE br.id_pago = p.id) AS tiene_beneficio
                 FROM pagos p
                 WHERE p.id = ?
                 LIMIT 1
                 FOR UPDATE"
            );
            $stmt->execute([$paymentId]);
            $payment = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$payment) {
                throw new RuntimeException('El pago ya no existe.');
            }
            if ((string) $payment['estado_pago'] !== 'anulado') {
                throw new RuntimeException('Primero debes anular el pago antes de eliminarlo definitivamente.');
            }
            if ((int) ($payment['tiene_beneficio'] ?? 0) === 1) {
                throw new RuntimeException('No se puede eliminar porque el pago conserva un vínculo de referido para auditoría.');
            }

            $delete = $pdo->prepare('DELETE FROM pagos WHERE id = ?');
            $delete->execute([$paymentId]);
            if ($delete->rowCount() !== 1) {
                throw new RuntimeException('No fue posible eliminar el pago.');
            }
            $pdo->commit();

            Security::json(['success' => true, 'message' => 'Pago eliminado definitivamente.']);
        }

        throw new InvalidArgumentException('La acción solicitada no está disponible.');
    } catch (Throwable $e) {
        if ($pdo->inTransaction()) {
            $pdo->rollBack();
        }
        error_log('Gestionar pagos: ' . $e->getMessage());
        Security::json(['success' => false, 'message' => $e->getMessage()], 422);
    }
}

$titulo_pagina = 'Gestionar Pagos';
require_once __DIR__ . '/admin_header.php';

$error_message_db = '';
$pagos = [];
$admins_dropdown = [];
$planes_dropdown = [];
$hasCycleColumn = false;
$hasIncomeTypeColumn = false;
$hasCreditGrantedColumn = false;
$hasCreditMovementColumn = false;

try {
    $hasCycleColumn = af_payment_has_column($pdo, 'pagos', 'ciclo');
    $hasIncomeTypeColumn = af_payment_has_column($pdo, 'pagos', 'tipo_ingreso');
    $hasCreditGrantedColumn = af_payment_has_column($pdo, 'pagos', 'credito_otorgado');
    $hasCreditMovementColumn = af_payment_has_column($pdo, 'pagos', 'id_movimiento_credito');
    $incomeTypeExpression = $hasIncomeTypeColumn ? "COALESCE(NULLIF(p.tipo_ingreso, ''), 'renovacion')" : "'renovacion'";
    $creditGrantedExpression = $hasCreditGrantedColumn ? 'p.credito_otorgado' : 'NULL';
    $creditMovementExpression = $hasCreditMovementColumn ? 'p.id_movimiento_credito' : 'NULL';
    $hasSubscriptionCycleColumn = af_payment_has_column($pdo, 'suscripciones', 'ciclo_facturacion');
    if ($hasCycleColumn && $hasSubscriptionCycleColumn) {
        $cycleExpression = "COALESCE(NULLIF(p.ciclo, ''), NULLIF(s.ciclo_facturacion, ''), 'manual')";
    } elseif ($hasCycleColumn) {
        $cycleExpression = "COALESCE(NULLIF(p.ciclo, ''), 'manual')";
    } elseif ($hasSubscriptionCycleColumn) {
        $cycleExpression = "COALESCE(NULLIF(s.ciclo_facturacion, ''), 'manual')";
    } else {
        $cycleExpression = "'manual'";
    }

    $sql = "
        SELECT
            p.id,
            p.id_suscripcion,
            p.monto,
            {$creditGrantedExpression} AS credito_otorgado,
            {$creditMovementExpression} AS id_movimiento_credito,
            {$incomeTypeExpression} AS tipo_ingreso,
            p.moneda,
            p.fecha_pago,
            p.metodo_pago,
            p.referencia_transaccion,
            p.comprobante_url,
            p.notas,
            COALESCE(p.estado_pago, 'confirmado') AS estado_pago,
            p.registrado_por_admin_id,
            {$cycleExpression} AS ciclo,
            s.id_admin,
            s.fecha_inicio AS suscripcion_inicio,
            s.fecha_fin AS suscripcion_fin,
            s.estado AS suscripcion_estado,
            u.nombre_usuario,
            u.correo,
            pl.id AS id_plan,
            pl.nombre_plan,
            registrador.nombre_usuario AS registrado_por_nombre,
            EXISTS(
                SELECT 1 FROM beneficios_referidos br
                WHERE br.id_pago = p.id
            ) AS tiene_beneficio_referido
        FROM pagos p
        JOIN suscripciones s ON s.id = p.id_suscripcion
        JOIN usuarios u ON u.id = s.id_admin
        JOIN planes pl ON pl.id = s.id_plan
        LEFT JOIN usuarios registrador ON registrador.id = p.registrado_por_admin_id
        ORDER BY p.fecha_pago DESC, p.id DESC
    ";
    $pagos = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);

    $admins_dropdown = $pdo->query(
        "SELECT DISTINCT u.id, u.nombre_usuario
         FROM pagos p
         JOIN suscripciones s ON s.id = p.id_suscripcion
         JOIN usuarios u ON u.id = s.id_admin
         ORDER BY u.nombre_usuario"
    )->fetchAll(PDO::FETCH_ASSOC);

    $planes_dropdown = $pdo->query(
        "SELECT DISTINCT pl.id, pl.nombre_plan
         FROM pagos p
         JOIN suscripciones s ON s.id = p.id_suscripcion
         JOIN planes pl ON pl.id = s.id_plan
         ORDER BY pl.nombre_plan"
    )->fetchAll(PDO::FETCH_ASSOC);

} catch (Throwable $e) {
    $error_message_db = 'Error al cargar los pagos: ' . $e->getMessage();
    error_log('Gestionar pagos carga: ' . $e->getMessage());
}

$monthStart = date('Y-m-01');
$monthEnd = date('Y-m-t');
$totalConfirmedAmount = 0.0;
$currentMonthAmount = 0.0;
$currentMonthTransactions = 0;
$currentMonthConfirmed = 0;
$currentMonthCancelled = 0;

foreach ($pagos as &$payment) {
    $payment['monto_numero'] = af_payment_money($payment['monto'] ?? 0);
    $payment['estado_pago'] = (string) (($payment['estado_pago'] ?? 'confirmado') === 'anulado' ? 'anulado' : 'confirmado');
    $payment['tipo_ingreso'] = (string) (($payment['tipo_ingreso'] ?? 'renovacion') === 'recarga_saldo' ? 'recarga_saldo' : 'renovacion');
    $payment['credito_otorgado_numero'] = af_payment_money($payment['credito_otorgado'] ?? 0);
    $paymentDate = date('Y-m-d', strtotime((string) $payment['fecha_pago']));

    if ($payment['estado_pago'] === 'confirmado') {
        $totalConfirmedAmount += $payment['monto_numero'];
    }
    if ($paymentDate >= $monthStart && $paymentDate <= $monthEnd) {
        $currentMonthTransactions++;
        if ($payment['estado_pago'] === 'confirmado') {
            $currentMonthAmount += $payment['monto_numero'];
            $currentMonthConfirmed++;
        } else {
            $currentMonthCancelled++;
        }
    }
}
unset($payment);

$paymentDetails = [];
foreach ($pagos as $payment) {
    $paymentDetails[(int) $payment['id']] = [
        'id' => (int) $payment['id'],
        'fecha' => date('d/m/Y H:i', strtotime((string) $payment['fecha_pago'])),
        'fecha_iso' => date('Y-m-d', strtotime((string) $payment['fecha_pago'])),
        'monto' => $payment['monto_numero'],
        'moneda' => (string) ($payment['moneda'] ?: 'PEN'),
        'estado' => (string) $payment['estado_pago'],
        'ciclo' => ucfirst((string) ($payment['ciclo'] ?: 'manual')),
        'tipo' => (string) $payment['tipo_ingreso'],
        'tipo_label' => $payment['tipo_ingreso'] === 'recarga_saldo' ? 'Recarga de saldo' : 'Renovación',
        'credito_otorgado' => $payment['credito_otorgado_numero'],
        'admin' => (string) $payment['nombre_usuario'],
        'correo' => (string) $payment['correo'],
        'plan' => (string) $payment['nombre_plan'],
        'metodo' => trim((string) ($payment['metodo_pago'] ?? '')),
        'referencia' => trim((string) ($payment['referencia_transaccion'] ?? '')),
        'notas' => trim((string) ($payment['notas'] ?? '')),
        'registrado_por' => trim((string) ($payment['registrado_por_nombre'] ?? '')),
        'suscripcion_fin' => !empty($payment['suscripcion_fin'])
            ? date('d/m/Y', strtotime((string) $payment['suscripcion_fin']))
            : 'Sin fecha',
        'tiene_beneficio' => (int) ($payment['tiene_beneficio_referido'] ?? 0) === 1,
    ];
}
?>
<link rel="stylesheet" href="../assets/css/superadmin-commercial.css?v=1.5.0">
<style>
/* Pagos: filtros compactos y acciones alineadas. */
.super-commercial-ui .payment-toolbar{
    grid-template-columns:
        minmax(220px,1.15fr)
        minmax(135px,.72fr)
        minmax(135px,.72fr)
        minmax(125px,.62fr)
        118px
        132px
        132px
        minmax(205px,.82fr) !important;
}
.super-commercial-ui .payment-search-filter{min-width:0;max-width:360px}
.super-commercial-ui .payment-status-filter{max-width:118px}
.super-commercial-ui .payment-length-actions{
    display:grid;
    grid-template-columns:96px auto;
    align-items:end;
    gap:8px;
    min-width:205px;
}
.super-commercial-ui .payment-length-actions .payment-length-filter{width:96px}
.super-commercial-ui .payment-length-actions .payment-clear-action{
    justify-self:stretch;
    align-self:end;
}
.super-commercial-ui .payment-length-actions .payment-clear-action .sc-btn-secondary{
    width:100%;
    min-width:96px;
    padding:0 12px;
}
@media(max-width:1360px){
    .super-commercial-ui .payment-toolbar{
        grid-template-columns:repeat(4,minmax(0,1fr)) !important;
    }
    .super-commercial-ui .payment-toolbar .payment-search-filter{
        grid-column:span 2;
        max-width:none;
    }
    .super-commercial-ui .payment-status-filter{max-width:none}
    .super-commercial-ui .payment-length-actions{
        min-width:0;
        grid-column:span 2;
        grid-template-columns:minmax(100px,130px) auto;
    }
}
@media(max-width:760px){
    .super-commercial-ui .payment-toolbar{
        grid-template-columns:1fr !important;
    }
    .super-commercial-ui .payment-toolbar .payment-search-filter,
    .super-commercial-ui .payment-length-actions{
        grid-column:auto;
    }
    .super-commercial-ui .payment-length-actions{
        grid-template-columns:1fr 1fr;
    }
    .super-commercial-ui .payment-length-actions .payment-length-filter{
        width:100%;
    }
}
</style>
<div class="super-commercial-ui px-4 md:px-6 pb-8">
    <div class="sc-shell">
        <?php if ($error_message_db !== ''): ?>
            <div class="sc-alert error"><i class="fas fa-database"></i><div><strong>No se pudo cargar el módulo</strong><br><?= htmlspecialchars($error_message_db) ?></div></div>
        <?php else: ?>
            <section class="sc-card sc-hero">
                <div class="sc-hero-main">
                    <span class="sc-icon"><i class="fas fa-receipt"></i></span>
                    <div>
                        <div class="sc-eyebrow">Control financiero</div>
                        <h1 class="sc-title">Pagos</h1>
                        <p class="sc-copy">Revisa ingresos por renovaciones y recargas de saldo, con el dinero realmente recibido y su trazabilidad.</p>
                    </div>
                </div>
                <div class="sc-actions">
                    <span class="sc-pill blue" id="paymentPeriodBadge"><i class="fas fa-calendar"></i><?= date('d/m/Y', strtotime($monthStart)) ?> – <?= date('d/m/Y', strtotime($monthEnd)) ?></span>
                </div>
            </section>

            <section class="sc-stats">
                <article class="sc-stat">
                    <span class="sc-stat-icon"><i class="fas fa-sack-dollar"></i></span>
                    <div><div class="sc-stat-label">Ingresos históricos</div><div class="sc-stat-value">S/ <?= number_format((float) $totalConfirmedAmount, 2) ?></div><div class="sc-stat-note">Solo pagos confirmados</div></div>
                </article>
                <article class="sc-stat">
                    <span class="sc-stat-icon green"><i class="fas fa-chart-line"></i></span>
                    <div><div class="sc-stat-label">Ingresos visibles</div><div class="sc-stat-value" id="visibleIncome">S/ <?= number_format((float) $currentMonthAmount, 2) ?></div><div class="sc-stat-note">Según filtros aplicados</div></div>
                </article>
                <article class="sc-stat">
                    <span class="sc-stat-icon blue"><i class="fas fa-receipt"></i></span>
                    <div><div class="sc-stat-label">Transacciones visibles</div><div class="sc-stat-value" id="visibleTransactions"><?= (int) $currentMonthTransactions ?></div><div class="sc-stat-note"><span id="visibleConfirmed"><?= (int) $currentMonthConfirmed ?></span> confirmadas en el resultado</div></div>
                </article>
                <article class="sc-stat">
                    <span class="sc-stat-icon amber"><i class="fas fa-ban"></i></span>
                    <div><div class="sc-stat-label">Anulados visibles</div><div class="sc-stat-value" id="visibleCancelled"><?= (int) $currentMonthCancelled ?></div><div class="sc-stat-note">Conservados para auditoría</div></div>
                </article>
            </section>

            <section class="sc-card sc-records">
                <div class="sc-records-head">
                    <span class="sc-section-icon"><i class="fas fa-list"></i></span>
                    <div><h2 class="sc-records-title">Historial de pagos</h2><p class="sc-records-copy">Los filtros se aplican automáticamente. Utiliza Limpiar para volver al mes actual.</p></div>
                </div>

                <div class="sc-toolbar payment-toolbar">
                    <div class="payment-search-filter">
                        <label class="sc-label" for="paymentSearch"><i class="fas fa-search"></i>Buscar</label>
                        <div class="sc-search"><i class="fas fa-search"></i><input type="search" id="paymentSearch" class="sc-field" placeholder="Admin, correo, plan, tipo, monto o referencia"></div>
                    </div>
                    <div>
                        <label class="sc-label" for="paymentAdmin"><i class="fas fa-user"></i>Admin</label>
                        <select id="paymentAdmin" class="sc-field"><option value="">Todos</option><?php foreach ($admins_dropdown as $admin): ?><option value="<?= (int) $admin['id'] ?>"><?= htmlspecialchars((string) $admin['nombre_usuario']) ?></option><?php endforeach; ?></select>
                    </div>
                    <div>
                        <label class="sc-label" for="paymentPlan"><i class="fas fa-layer-group"></i>Plan</label>
                        <select id="paymentPlan" class="sc-field"><option value="">Todos</option><?php foreach ($planes_dropdown as $plan): ?><option value="<?= (int) $plan['id'] ?>"><?= htmlspecialchars((string) $plan['nombre_plan']) ?></option><?php endforeach; ?></select>
                    </div>
                    <div>
                        <label class="sc-label" for="paymentType"><i class="fas fa-file-invoice-dollar"></i>Tipo</label>
                        <select id="paymentType" class="sc-field"><option value="">Todos</option><option value="renovacion">Renovación</option><option value="recarga_saldo">Recarga de saldo</option></select>
                    </div>
                    <div class="payment-status-filter">
                        <label class="sc-label" for="paymentStatus"><i class="fas fa-signal"></i>Estado</label>
                        <select id="paymentStatus" class="sc-field"><option value="">Todos</option><option value="confirmado">Confirmado</option><option value="anulado">Anulado</option></select>
                    </div>
                    <div>
                        <label class="sc-label" for="paymentFrom"><i class="fas fa-calendar-minus"></i>Desde</label>
                        <input type="date" id="paymentFrom" class="sc-field" value="<?= htmlspecialchars($monthStart) ?>">
                    </div>
                    <div>
                        <label class="sc-label" for="paymentTo"><i class="fas fa-calendar-plus"></i>Hasta</label>
                        <input type="date" id="paymentTo" class="sc-field" value="<?= htmlspecialchars($monthEnd) ?>">
                    </div>
                    <div class="payment-length-actions">
                        <div class="payment-length-filter">
                            <label class="sc-label" for="paymentPageLength"><i class="fas fa-list-ol"></i>Mostrar</label>
                            <select id="paymentPageLength" class="sc-field"><option value="100" selected>100</option><option value="200">200</option><option value="400">400</option><option value="-1">Todos</option></select>
                        </div>
                        <div class="sc-filter-actions payment-clear-action">
                            <button type="button" id="clearPaymentFilters" class="sc-btn-secondary"><i class="fas fa-eraser"></i> Limpiar</button>
                        </div>
                    </div>
                </div>

                <div class="sc-summary"><span><?= count($pagos) ?> pagos registrados</span><span id="paymentInfo">Mostrando 0–0 de 0 registros</span></div>
                <div class="sc-table-wrap">
                    <table id="tablaPagos">
                        <thead><tr><th>Fecha</th><th>Admin suscriptor</th><th>Plan</th><th>Tipo</th><th>Modalidad</th><th>Ingreso</th><th>Estado</th><th>Registrado por</th><th class="text-right">Acciones</th></tr></thead>
                        <tbody>
                        <?php foreach ($pagos as $payment): ?>
                            <?php
                                $state = (string) $payment['estado_pago'];
                                $cycle = mb_strtolower(trim((string) ($payment['ciclo'] ?: 'manual')), 'UTF-8');
                                $incomeType = (string) $payment['tipo_ingreso'];
                                $dateIso = date('Y-m-d', strtotime((string) $payment['fecha_pago']));
                            ?>
                            <tr
                                data-payment-id="<?= (int) $payment['id'] ?>"
                                data-admin-id="<?= (int) $payment['id_admin'] ?>"
                                data-plan-id="<?= (int) $payment['id_plan'] ?>"
                                data-cycle="<?= htmlspecialchars($cycle, ENT_QUOTES) ?>"
                                data-type="<?= htmlspecialchars($incomeType, ENT_QUOTES) ?>"
                                data-status="<?= htmlspecialchars($state, ENT_QUOTES) ?>"
                                data-date="<?= htmlspecialchars($dateIso, ENT_QUOTES) ?>"
                                data-amount="<?= htmlspecialchars(number_format((float) $payment['monto_numero'], 2, '.', ''), ENT_QUOTES) ?>"
                            >
                                <td><strong><?= date('d/m/Y', strtotime((string) $payment['fecha_pago'])) ?></strong><div class="sc-muted"><?= date('H:i', strtotime((string) $payment['fecha_pago'])) ?></div></td>
                                <td><strong><?= htmlspecialchars((string) $payment['nombre_usuario']) ?></strong><div class="sc-muted"><?= htmlspecialchars((string) $payment['correo']) ?></div></td>
                                <td><span class="sc-pill blue"><?= htmlspecialchars((string) $payment['nombre_plan']) ?></span></td>
                                <td><span class="sc-pill <?= $incomeType === 'recarga_saldo' ? 'amber' : 'blue' ?>"><?= $incomeType === 'recarga_saldo' ? 'Recarga de saldo' : 'Renovación' ?></span><?php if ($incomeType === 'recarga_saldo' && (float) $payment['credito_otorgado_numero'] > 0): ?><div class="sc-muted">Saldo acreditado: S/ <?= number_format((float) $payment['credito_otorgado_numero'], 2) ?></div><?php endif; ?></td>
                                <td><?= $incomeType === 'recarga_saldo' ? '<span class="sc-muted">No aplica</span>' : htmlspecialchars(ucfirst($cycle)) ?></td>
                                <td><strong>S/ <?= number_format((float) $payment['monto_numero'], 2) ?></strong><div class="sc-muted">Dinero recibido · <?= htmlspecialchars((string) ($payment['moneda'] ?: 'PEN')) ?></div></td>
                                <td><span class="sc-pill <?= $state === 'anulado' ? 'red' : 'green' ?>"><?= htmlspecialchars(af_payment_state_label($state)) ?></span><?php if ((int) ($payment['tiene_beneficio_referido'] ?? 0) === 1): ?><div class="sc-muted sc-payment-referral"><i class="fas fa-gift"></i> Beneficio de referido</div><?php endif; ?></td>
                                <td><?= htmlspecialchars((string) ($payment['registrado_por_nombre'] ?: 'Sistema')) ?></td>
                                <td class="sc-actions-cell">
                                    <button type="button" class="sc-action view payment-view-btn" title="Ver detalles" data-id="<?= (int) $payment['id'] ?>"><i class="fas fa-eye"></i></button>
                                    <?php if ($state === 'confirmado'): ?>
                                        <button type="button" class="sc-action cancel payment-status-btn" title="Anular pago" data-id="<?= (int) $payment['id'] ?>" data-state="anulado"><i class="fas fa-ban"></i></button>
                                    <?php else: ?>
                                        <button type="button" class="sc-action restore payment-status-btn" title="Restaurar pago" data-id="<?= (int) $payment['id'] ?>" data-state="confirmado"><i class="fas fa-rotate-left"></i></button>
                                        <button type="button" class="sc-action delete payment-delete-btn" title="Eliminar definitivamente" data-id="<?= (int) $payment['id'] ?>"><i class="fas fa-trash"></i></button>
                                    <?php endif; ?>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                        </tbody>
                    </table>
                </div>
                <div class="sc-table-foot"><span>Los ingresos anulados se conservan para auditoría. Anular una recarga no revierte automáticamente el saldo acreditado.</span><div id="paymentPagination" class="sc-pagination"></div></div>
            </section>
        <?php endif; ?>
    </div>
</div>

<div id="paymentDetailModal" class="super-commercial-ui sc-modal fixed inset-0 hidden items-center justify-center z-[2147483000] px-3 py-4">
    <div class="sc-modal-shell wide">
        <div class="sc-modal-head">
            <div class="sc-modal-main"><span class="sc-modal-icon"><i class="fas fa-receipt"></i></span><div><div class="sc-modal-kicker">Pagos · detalle</div><div class="sc-modal-title">Detalle del pago</div><p class="sc-modal-copy">Información financiera y vínculo con la suscripción.</p></div></div>
            <button type="button" class="sc-modal-close close-payment-detail"><i class="fas fa-times"></i></button>
        </div>
        <div class="sc-modal-body">
            <div class="payment-detail-grid">
                <article><small>Admin suscriptor</small><strong id="detailAdmin">—</strong><span id="detailEmail">—</span></article>
                <article><small>Plan</small><strong id="detailPlan">—</strong><span id="detailCycle">—</span></article>
                <article><small>Ingreso recibido</small><strong id="detailAmount">—</strong><span id="detailState">—</span></article>
                <article><small>Fecha de pago</small><strong id="detailDate">—</strong><span id="detailRegisteredBy">—</span></article>
            </div>
            <div class="payment-detail-list">
                <div><span>Tipo de ingreso</span><strong id="detailType">—</strong></div>
                <div><span>Saldo acreditado</span><strong id="detailCreditGranted">No aplica</strong></div>
                <div><span>Referencia</span><strong id="detailReference">No registrada</strong></div>
                <div><span>Vigencia actual</span><strong id="detailSubscriptionEnd">—</strong></div>
                <div><span>Beneficio de referido</span><strong id="detailReferral">No</strong></div>
            </div>
            <div class="payment-detail-notes"><small>Notas</small><p id="detailNotes">Sin notas registradas.</p></div>
        </div>
        <div class="sc-modal-foot"><button type="button" class="sc-btn-secondary close-payment-detail">Cerrar</button><button type="button" id="copyPaymentSummary" class="sc-btn-primary"><i class="fas fa-copy"></i> Copiar resumen</button></div>
    </div>
</div>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
$(function(){
    const payments = <?= json_encode($paymentDetails, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
    const csrf = <?= json_encode(Security::csrfToken()) ?>;
    const defaultFrom = <?= json_encode($monthStart) ?>;
    const defaultTo = <?= json_encode($monthEnd) ?>;
    let selectedPayment = null;

    async function postPaymentAction(payload){
        const body = new URLSearchParams({...payload,_csrf:csrf});
        const response = await fetch('gestionar_pagos.php',{
            method:'POST',
            headers:{'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'},
            body:body.toString()
        });
        let data = null;
        try { data = await response.json(); } catch (error) {
            throw new Error('El servidor devolvió una respuesta no válida.');
        }
        if (!response.ok || !data?.success) {
            throw new Error(data?.message || 'No se pudo completar la operación.');
        }
        return data;
    }

    $.fn.dataTable.ext.search.push(function(settings, data, dataIndex){
        if (settings.nTable.id !== 'tablaPagos') return true;
        const row = settings.aoData[dataIndex]?.nTr;
        if (!row) return true;

        const admin = $('#paymentAdmin').val();
        const plan = $('#paymentPlan').val();
        const type = $('#paymentType').val();
        const status = $('#paymentStatus').val();
        const from = $('#paymentFrom').val();
        const to = $('#paymentTo').val();
        const rowDate = row.dataset.date || '';

        if (admin && row.dataset.adminId !== admin) return false;
        if (plan && row.dataset.planId !== plan) return false;
        if (type && row.dataset.type !== type) return false;
        if (status && row.dataset.status !== status) return false;
        if (from && rowDate < from) return false;
        if (to && rowDate > to) return false;
        return true;
    });

    const table = $('#tablaPagos').DataTable({
        dom: 't',
        language: {url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/es_es.json'},
        pageLength: 100,
        lengthMenu: [[100,200,400,-1],[100,200,400,'Todos']],
        order: [],
        autoWidth: false,
        columnDefs: [{orderable:false,targets:[8]}]
    });

    function formatDate(value){
        if (!value) return '';
        const parts = value.split('-');
        return parts.length === 3 ? `${parts[2]}/${parts[1]}/${parts[0]}` : value;
    }

    function updatePeriodBadge(){
        const from = $('#paymentFrom').val();
        const to = $('#paymentTo').val();
        let label = 'Todos los periodos';
        if (from && to) label = `${formatDate(from)} – ${formatDate(to)}`;
        else if (from) label = `Desde ${formatDate(from)}`;
        else if (to) label = `Hasta ${formatDate(to)}`;
        $('#paymentPeriodBadge').html(`<i class="fas fa-calendar"></i>${label}`);
    }

    function updateVisibleStats(){
        let income = 0;
        let confirmed = 0;
        let cancelled = 0;
        table.rows({search:'applied'}).nodes().each(function(row){
            const amount = Number(row.dataset.amount || 0);
            if (row.dataset.status === 'anulado') cancelled++;
            else { confirmed++; income += amount; }
        });
        $('#visibleIncome').text(`S/ ${income.toLocaleString('es-PE',{minimumFractionDigits:2,maximumFractionDigits:2})}`);
        $('#visibleTransactions').text(confirmed + cancelled);
        $('#visibleConfirmed').text(confirmed);
        $('#visibleCancelled').text(cancelled);
    }

    function renderPagination(){
        const info = table.page.info();
        const total = info.recordsDisplay || 0;
        const start = total ? info.start + 1 : 0;
        const end = total ? info.end : 0;
        const pages = info.pages || 0;
        const current = info.page || 0;
        $('#paymentInfo').text(`Mostrando ${start}–${end} de ${total} registros`);

        let html = `<button class="sc-page" data-page="prev" ${current===0||!pages?'disabled':''}><i class="fas fa-chevron-left"></i></button>`;
        if (!pages) {
            html += '<button class="sc-page active" disabled>1</button>';
        } else {
            for (let page=0; page<pages; page++) {
                if (pages<=5 || page===0 || page===pages-1 || Math.abs(page-current)<=1) {
                    html += `<button class="sc-page ${page===current?'active':''}" data-page="${page}">${page+1}</button>`;
                } else if (page===current-2 || page===current+2) {
                    html += '<span>…</span>';
                }
            }
        }
        html += `<button class="sc-page" data-page="next" ${current>=pages-1||!pages?'disabled':''}><i class="fas fa-chevron-right"></i></button>`;
        $('#paymentPagination').html(html);
        updateVisibleStats();
        updatePeriodBadge();
    }

    function redraw(){ table.draw(); }

    $('#paymentSearch').on('input', function(){ table.search(this.value).draw(); });
    $('#paymentAdmin,#paymentPlan,#paymentType,#paymentStatus,#paymentFrom,#paymentTo').on('change', redraw);
    $('#paymentPageLength').on('change', function(){ table.page.len(parseInt(this.value,10)).draw(); });
    $('#clearPaymentFilters').on('click', function(){
        $('#paymentSearch').val('');
        $('#paymentAdmin,#paymentPlan,#paymentType,#paymentStatus').val('');
        $('#paymentFrom').val(defaultFrom);
        $('#paymentTo').val(defaultTo);
        $('#paymentPageLength').val('100');
        table.search('').page.len(100).draw();
    });

    table.on('draw page.dt search.dt length.dt', renderPagination);
    renderPagination();

    $('#paymentPagination').on('click','.sc-page',function(){
        if (this.disabled) return;
        const page = $(this).data('page');
        if (page === 'prev') table.page('previous').draw('page');
        else if (page === 'next') table.page('next').draw('page');
        else table.page(parseInt(page,10)).draw('page');
    });

    function openDetail(payment){
        selectedPayment = payment;
        $('#detailAdmin').text(payment.admin || '—');
        $('#detailEmail').text(payment.correo || '—');
        $('#detailPlan').text(payment.plan || '—');
        $('#detailCycle').text(payment.tipo === 'recarga_saldo' ? 'Modalidad: No aplica' : `Modalidad: ${payment.ciclo || 'Manual'}`);
        $('#detailAmount').text(`S/ ${Number(payment.monto||0).toLocaleString('es-PE',{minimumFractionDigits:2,maximumFractionDigits:2})}`);
        $('#detailState').text(`Estado: ${payment.estado === 'anulado' ? 'Anulado' : 'Confirmado'}`);
        $('#detailDate').text(payment.fecha || '—');
        $('#detailRegisteredBy').text(`Registrado por: ${payment.registrado_por || 'Sistema'}`);
        $('#detailType').text(payment.tipo_label || 'Renovación');
        $('#detailCreditGranted').text(payment.tipo === 'recarga_saldo' && Number(payment.credito_otorgado||0)>0
            ? `S/ ${Number(payment.credito_otorgado).toLocaleString('es-PE',{minimumFractionDigits:2,maximumFractionDigits:2})}`
            : 'No aplica');
        $('#detailReference').text(payment.referencia || 'No registrada');
        $('#detailSubscriptionEnd').text(payment.suscripcion_fin || 'Sin fecha');
        $('#detailReferral').text(payment.tiene_beneficio ? 'Sí, este pago generó un beneficio' : 'No');
        $('#detailNotes').text(payment.notas || 'Sin notas registradas.');
        $('#paymentDetailModal').removeClass('hidden').addClass('flex');
        $('body').addClass('sc-commercial-modal-open');
    }

    function closeDetail(){
        $('#paymentDetailModal').addClass('hidden').removeClass('flex');
        $('body').removeClass('sc-commercial-modal-open');
        selectedPayment = null;
    }

    $('#tablaPagos').on('click','.payment-view-btn',function(){
        const payment = payments[Number($(this).data('id'))];
        if (payment) openDetail(payment);
    });
    $('.close-payment-detail').on('click', closeDetail);
    $('#paymentDetailModal').on('click', function(event){ if (event.target === this) closeDetail(); });

    $('#copyPaymentSummary').on('click', async function(){
        if (!selectedPayment) return;
        const text = [
            `Pago #${selectedPayment.id}`,
            `Admin: ${selectedPayment.admin}`,
            `Correo: ${selectedPayment.correo}`,
            `Plan: ${selectedPayment.plan}`,
            `Tipo: ${selectedPayment.tipo_label}`,
            `Modalidad: ${selectedPayment.tipo === 'recarga_saldo' ? 'No aplica' : selectedPayment.ciclo}`,
            `Ingreso recibido: S/ ${Number(selectedPayment.monto||0).toFixed(2)}`,
            ...(selectedPayment.tipo === 'recarga_saldo' ? [`Saldo acreditado: S/ ${Number(selectedPayment.credito_otorgado||0).toFixed(2)}`] : []),
            `Fecha: ${selectedPayment.fecha}`,
            `Estado: ${selectedPayment.estado === 'anulado' ? 'Anulado' : 'Confirmado'}`
        ].join('\n');
        try {
            await navigator.clipboard.writeText(text);
            Swal.fire({icon:'success',title:'Resumen copiado',timer:1300,showConfirmButton:false});
        } catch (error) {
            Swal.fire('No se pudo copiar','Copia el contenido manualmente desde el detalle.','warning');
        }
    });

    $('#tablaPagos').on('click','.payment-status-btn',function(){
        const id = Number($(this).data('id'));
        const state = String($(this).data('state'));
        const isCancel = state === 'anulado';
        Swal.fire({
            title: isCancel ? '¿Anular este pago?' : '¿Restaurar este pago?',
            html: isCancel
                ? 'El registro se conservará para auditoría.<br><strong>La vigencia de la suscripción no se modificará automáticamente.</strong>'
                : 'El pago volverá a contabilizarse como ingreso confirmado.',
            icon: 'warning',
            showCancelButton: true,
            confirmButtonText: isCancel ? 'Sí, anular pago' : 'Sí, restaurar',
            cancelButtonText: 'Cancelar',
            confirmButtonColor: isCancel ? '#dc2626' : '#16a34a',
            showLoaderOnConfirm: true,
            preConfirm: async () => {
                try {
                    return await postPaymentAction({action:'set_payment_status_ajax',id:id,estado:state});
                } catch (error) {
                    Swal.showValidationMessage(error.message);
                    return false;
                }
            }
        }).then(result => {
            if (!result.isConfirmed || !result.value) return;
            Swal.fire({icon:'success',title:'Estado actualizado',text:result.value.message,confirmButtonColor:'#ef3b43'}).then(()=>location.reload());
        });
    });

    $('#tablaPagos').on('click','.payment-delete-btn',function(){
        const id = Number($(this).data('id'));
        Swal.fire({
            title: 'Eliminar pago definitivamente',
            html: 'Esta acción solo está disponible para pagos anulados y <strong>no se puede deshacer</strong>.',
            icon: 'warning',
            showCancelButton: true,
            confirmButtonText: 'Eliminar definitivamente',
            cancelButtonText: 'Cancelar',
            confirmButtonColor: '#dc2626',
            showLoaderOnConfirm: true,
            preConfirm: () => postPaymentAction({action:'delete_payment_ajax',id:id}).catch(error => {
                Swal.showValidationMessage(error.message);
                return false;
            })
        }).then(result => {
            if (!result.isConfirmed || !result.value) return;
            Swal.fire({icon:'success',title:'Pago eliminado',text:result.value.message,confirmButtonColor:'#ef3b43'}).then(()=>location.reload());
        });
    });
});
</script>
<?php require_once __DIR__ . '/admin_footer.php'; ?>
