<?php
declare(strict_types=1);

session_start();
require_once 'config.php';
$conn = getDBConnection();

$is_admin = isset($_SESSION['user_id']);
$is_parent = isset($_SESSION['parent_id']);
if (!$is_admin && !$is_parent) {
    header('Location: login.php');
    exit;
}

ini_set('display_errors', '0');
error_reporting(E_ALL);

if (!$conn) {
    http_response_code(500);
    exit('Unable to connect to the database.');
}

function e(string $value): string
{
    return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}

function fetchReceipt(mysqli $conn, ?int $id, ?string $ref): ?array
{
    if ($id !== null) {
        $stmt = $conn->prepare(
            "SELECT op.*, s.first_name, s.last_name, s.class
             FROM online_payments op
             INNER JOIN students s ON s.id = op.student_id
             WHERE op.id = ?
             LIMIT 1"
        );
        $stmt->bind_param('i', $id);
    } else {
        $stmt = $conn->prepare(
            "SELECT op.*, s.first_name, s.last_name, s.class
             FROM online_payments op
             INNER JOIN students s ON s.id = op.student_id
             WHERE op.receipt_number = ?
             LIMIT 1"
        );
        $stmt->bind_param('s', $ref);
    }
    $stmt->execute();
    $result = $stmt->get_result();
    $row = $result->fetch_assoc();
    $stmt->close();
    return $row ?: null;
}

/**
 * Raw payments+students join for a `payments.id` (cash/manual/express-scanner
 * ledger row). Kept separate from the shaping below so the transaction_id can
 * be checked against online_payments before deciding how to render it.
 */
function fetchRawPayment(mysqli $conn, int $paymentId): ?array
{
    $stmt = $conn->prepare(
        "SELECT p.id, p.student_id, p.fee_structure_id, p.amount_paid, p.payment_date,
                p.payment_method, p.transaction_id, p.batch_id,
                s.first_name, s.last_name, s.class, s.father_name, s.father_phone, s.mother_phone
         FROM payments p
         INNER JOIN students s ON s.id = p.student_id
         WHERE p.id = ?
         LIMIT 1"
    );
    $stmt->bind_param('i', $paymentId);
    $stmt->execute();
    $row = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    return $row ?: null;
}

/**
 * A `payments` row created by the bursar bulk-payment flow (fees.php's
 * add_bulk_payment) carries a batch_id. If present, this takes priority
 * over the single-item/online-sibling paths below — show the whole
 * batch's receipt (every fee item the transaction covered), not just the
 * one row that happened to be clicked.
 */
function fetchBatchReceipt(mysqli $conn, int $batchId): ?array
{
    $stmt = $conn->prepare(
        "SELECT bpb.*, s.first_name, s.last_name, s.class, s.father_name, s.father_phone, s.mother_phone
         FROM bulk_payment_batches bpb
         INNER JOIN students s ON s.id = bpb.student_id
         WHERE bpb.id = ?
         LIMIT 1"
    );
    $stmt->bind_param('i', $batchId);
    $stmt->execute();
    $batch = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    if (!$batch) {
        return null;
    }

    $paymentsStmt = $conn->prepare("SELECT fee_structure_id, amount_paid FROM payments WHERE batch_id = ?");
    $paymentsStmt->bind_param('i', $batchId);
    $paymentsStmt->execute();
    $paymentRows = $paymentsStmt->get_result()->fetch_all(MYSQLI_ASSOC);
    $paymentsStmt->close();

    $feeIds = [];
    $amountsPaidByFeeId = [];
    foreach ($paymentRows as $row) {
        $feeId = (int) $row['fee_structure_id'];
        $feeIds[] = $feeId;
        $amountsPaidByFeeId[$feeId] = (float) $row['amount_paid'];
    }

    return [
        'id'                   => $batchId,
        'student_id'           => (int) $batch['student_id'],
        'first_name'           => $batch['first_name'],
        'last_name'            => $batch['last_name'],
        'class'                => $batch['class'],
        'parent_name'          => $batch['father_name'] ?? '',
        'parent_phone'         => $batch['father_phone'] ?: ($batch['mother_phone'] ?? ''),
        'payment_method'       => $batch['payment_channel'],
        'gateway'              => $batch['gateway'] ?: 'manual',
        'status'               => $batch['status'] === 'completed' ? 'success' : $batch['status'],
        'receipt_number'       => $batch['receipt_number'] ?: ('BLK-' . str_pad((string) $batchId, 6, '0', STR_PAD_LEFT)),
        'initiated_at'         => $batch['created_at'],
        'amount'               => (float) $batch['total_amount'],
        'fee_structure_ids'    => json_encode($feeIds),
        // Batch line items are split proportionally to each item's own
        // remaining balance (see proportionalPaymentShares()), not its
        // sticker price — the per-item amount below must reflect that split,
        // or "GHS 80 + GHS 300" wouldn't reconcile with a GHS 208 total paid.
        'amounts_paid_by_fee'  => $amountsPaidByFeeId,
    ];
}

/**
 * A `payments` row inserted by the Hubtel/Paystack webhooks carries
 * transaction_id = the gateway reference it was fanned out from. If that
 * reference still matches an online_payments row, show that transaction's
 * full multi-item receipt instead of just this one fee-item line.
 */
function fetchOnlinePaymentByGatewayReference(mysqli $conn, string $reference, int $studentId): ?array
{
    $stmt = $conn->prepare(
        "SELECT op.*, s.first_name, s.last_name, s.class
         FROM online_payments op
         INNER JOIN students s ON s.id = op.student_id
         WHERE op.gateway_reference = ? AND op.student_id = ?
         LIMIT 1"
    );
    $stmt->bind_param('si', $reference, $studentId);
    $stmt->execute();
    $row = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    return $row ?: null;
}

/**
 * Shape a raw `payments` row into the same fields the template below reads
 * off an online_payments row. The manual ledger has no receipt_number or
 * gateway of its own, so these are clearly-labelled equivalents rather than
 * fields borrowed from a different meaning.
 */
function shapeManualReceipt(array $row): array
{
    return [
        'id'                => (int) $row['id'],
        'student_id'        => (int) $row['student_id'],
        'first_name'        => $row['first_name'],
        'last_name'         => $row['last_name'],
        'class'             => $row['class'],
        'parent_name'       => $row['father_name'] ?? '',
        'parent_phone'      => $row['father_phone'] ?: ($row['mother_phone'] ?? ''),
        'payment_method'    => $row['payment_method'],
        'gateway'           => 'manual',
        'status'            => 'success',
        'receipt_number'    => 'PAY-' . str_pad((string) $row['id'], 6, '0', STR_PAD_LEFT),
        'initiated_at'      => $row['payment_date'],
        'amount'            => (float) $row['amount_paid'],
        'fee_structure_ids' => json_encode([(int) $row['fee_structure_id']]),
    ];
}

function fetchReceiptFees(mysqli $conn, array $feeIds): array
{
    if ($feeIds === []) {
        return [];
    }
    $placeholders = implode(',', array_fill(0, count($feeIds), '?'));
    $types = str_repeat('i', count($feeIds));
    $stmt = $conn->prepare("SELECT id, fee_type, amount FROM fee_structures WHERE id IN ($placeholders) ORDER BY fee_type ASC");
    $stmt->bind_param($types, ...$feeIds);
    $stmt->execute();
    $result = $stmt->get_result();
    $rows = [];
    while ($row = $result->fetch_assoc()) {
        $rows[] = $row;
    }
    $stmt->close();
    return $rows;
}

$id = isset($_GET['id']) && ctype_digit((string) $_GET['id']) ? (int) $_GET['id'] : null;
$ref = isset($_GET['ref']) ? trim((string) $_GET['ref']) : null;
$paymentId = isset($_GET['payment_id']) && ctype_digit((string) $_GET['payment_id']) ? (int) $_GET['payment_id'] : null;

$receipt = null;
if ($paymentId !== null) {
    $rawPayment = fetchRawPayment($conn, $paymentId);
    if ($rawPayment !== null) {
        if (!empty($rawPayment['batch_id'])) {
            $receipt = fetchBatchReceipt($conn, (int) $rawPayment['batch_id']);
        }
        if ($receipt === null) {
            $reference = (string) ($rawPayment['transaction_id'] ?? '');
            $sibling = $reference !== ''
                ? fetchOnlinePaymentByGatewayReference($conn, $reference, (int) $rawPayment['student_id'])
                : null;
            $receipt = $sibling ?? shapeManualReceipt($rawPayment);
        }
    }
} elseif ($id !== null || $ref !== null) {
    $receipt = fetchReceipt($conn, $id, $ref);
}

if (!$receipt) {
    http_response_code(404);
    echo 'Receipt not found.';
    exit;
}

if ($is_parent) {
    $ownershipStmt = $conn->prepare(
        "SELECT id FROM parent_student_link
         WHERE parent_id = ? AND student_id = ?"
    );
    $ownershipStmt->bind_param('ii', $_SESSION['parent_id'], $receipt['student_id']);
    $ownershipStmt->execute();
    if ($ownershipStmt->get_result()->num_rows === 0) {
        $ownershipStmt->close();
        header('Location: parent-portal/dashboard.php?error=unauthorized');
        exit;
    }
    $ownershipStmt->close();
}

$feeIds = json_decode((string) $receipt['fee_structure_ids'], true);
$feeIds = is_array($feeIds) ? array_values(array_filter(array_map('intval', $feeIds))) : [];
$feeRows = fetchReceiptFees($conn, $feeIds);
if (isset($receipt['amounts_paid_by_fee']) && is_array($receipt['amounts_paid_by_fee'])) {
    foreach ($feeRows as &$feeRow) {
        $feeRowId = (int) $feeRow['id'];
        if (isset($receipt['amounts_paid_by_fee'][$feeRowId])) {
            $feeRow['amount'] = $receipt['amounts_paid_by_fee'][$feeRowId];
        }
    }
    unset($feeRow);
}
$studentName = trim($receipt['first_name'] . ' ' . $receipt['last_name']);
$methodLabels = [
    'card' => 'Card',
    'momo_mtn' => 'MTN Mobile Money',
    'momo_vodafone' => 'Vodafone Cash',
    'momo_airteltigo' => 'AirtelTigo Money',
];
$methodLabel = $methodLabels[$receipt['payment_method']] ?? $receipt['payment_method'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Payment Receipt - EduTrack</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="css/style.css">
    <style>
        .receipt-card { background:#fff; border-radius:1rem; box-shadow:0 .75rem 2rem rgba(15,23,42,.08); }
        .receipt-header { border-bottom:2px solid #e9ecef; }
        .total-row { background:#f8f9fa; font-weight:700; }
        @media print {
            body { background:#fff; }
            .no-print, .sidebar, .header, .footer, .content-header { display:none !important; }
            .main-content, .content { margin:0 !important; padding:0 !important; }
            .receipt-card { box-shadow:none; border:0; }
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <nav id="sidebar" class="sidebar">
        <?php echo buildSidebar(basename($_SERVER['PHP_SELF'])); ?>
        </nav>

        <div class="main-content">
            <header class="header no-print">
                <button class="btn-toggle" id="sidebarToggle">
                    <i class="fas fa-bars"></i>
                </button>
                <div class="header-right">
                    <div class="dropdown">
                        <button class="btn btn-link dropdown-toggle" type="button" data-bs-toggle="dropdown">
                            <i class="fas fa-user-circle me-2"></i><?php echo htmlspecialchars((string) ($_SESSION['full_name'] ?? '')); ?>
                        </button>
                        <ul class="dropdown-menu dropdown-menu-end">
                            <li><a class="dropdown-item" href="settings.php"><i class="fas fa-cog me-2"></i>Settings</a></li>
                            <li><hr class="dropdown-divider"></li>
                            <li><a class="dropdown-item" href="logout.php"><i class="fas fa-sign-out-alt me-2"></i>Logout</a></li>
                        </ul>
                    </div>
                </div>
            </header>

            <main class="content">
                <div class="content-header d-flex justify-content-between align-items-start flex-wrap gap-3 no-print">
                    <div>
                        <h2><i class="fas fa-receipt me-2"></i>Payment Receipt</h2>
                        <p>Review payment status and print the official receipt.</p>
                    </div>
                    <a href="fees.php" class="btn btn-outline-secondary">
                        <i class="fas fa-arrow-left me-1"></i>Back to Fees
                    </a>
                </div>

                <?php if ($receipt['status'] === 'pending'): ?>
                    <div class="alert alert-warning no-print">Payment Pending. This page will refresh automatically every 10 seconds.</div>
                <?php elseif ($receipt['status'] === 'failed'): ?>
                    <div class="alert alert-danger no-print">Payment Failed. <a href="payment_checkout.php?student_id=<?= (int) $receipt['student_id'] ?>" class="alert-link">Retry payment</a></div>
                <?php endif; ?>

                <div class="card receipt-card">
                    <div class="card-body p-4">
                        <div class="receipt-header pb-3 mb-4">
            <div class="d-flex justify-content-between align-items-center">
                <div>
                    <h3 class="mb-1"><?= e((string) (getSettingValue('school_name') ?: 'EduTrack School')) ?></h3>
                    <div class="text-muted">OFFICIAL PAYMENT RECEIPT</div>
                </div>
                <div class="text-end">
                    <div><strong>Receipt No:</strong> <?= e((string) $receipt['receipt_number']) ?></div>
                    <div><strong>Date:</strong> <?= e(date('d M Y', strtotime((string) $receipt['initiated_at']))) ?></div>
                </div>
            </div>
        </div>
        <div class="row mb-4">
            <div class="col-md-6">
                <p class="mb-2"><strong>Student:</strong> <?= e($studentName) ?></p>
                <p class="mb-2"><strong>Class:</strong> <?= e((string) $receipt['class']) ?></p>
                <p class="mb-2"><strong>Paid by:</strong> <?= e((string) ($receipt['parent_name'] ?? '')) ?></p>
                <p class="mb-0"><strong>Phone:</strong> <?= e((string) ($receipt['parent_phone'] ?? '')) ?></p>
            </div>
            <div class="col-md-6 text-md-end">
                <p class="mb-2"><strong>Method:</strong> <?= e($methodLabel) ?></p>
                <p class="mb-2"><strong>Gateway:</strong> <?= e(ucfirst((string) $receipt['gateway'])) ?></p>
                <p class="mb-0"><strong>Status:</strong> <?= $receipt['status'] === 'success' ? 'CONFIRMED' : strtoupper((string) $receipt['status']) ?></p>
            </div>
        </div>
        <div class="table-responsive mb-4">
            <table class="table">
                <thead><tr><th>Fee Item</th><th class="text-end">Amount</th></tr></thead>
                <tbody>
                <?php foreach ($feeRows as $fee): ?>
                    <tr><td><?= e((string) $fee['fee_type']) ?></td><td class="text-end">GHS <?= number_format((float) $fee['amount'], 2) ?></td></tr>
                <?php endforeach; ?>
                <tr class="total-row"><td>TOTAL PAID</td><td class="text-end">GHS <?= number_format((float) $receipt['amount'], 2) ?></td></tr>
                </tbody>
            </table>
        </div>
                        <div class="d-flex justify-content-between no-print">
                            <button type="button" class="btn btn-dark" onclick="window.print()">Print Receipt</button>
                            <a href="fees.php" class="btn btn-outline-secondary">Back to Fees</a>
                        </div>
                    </div>
                </div>
            </main>

            <footer class="footer no-print">
                <p>&copy; 2024 EduTrack PRO. All rights reserved.</p>
            </footer>
        </div>
    </div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script src="js/main.js"></script>
<script>
(() => {
    const status = <?= json_encode((string) $receipt['status']) ?>;
    const paymentId = <?= (int) $receipt['id'] ?>;
    if (status !== 'pending') return;
    setInterval(() => {
        $.post('ajax/check_payment_status.php', {payment_id: paymentId}, (response) => {
            if (response && (response.status === 'success' || response.status === 'failed')) {
                window.location.reload();
            }
        }, 'json');
    }, 10000);
})();
</script>
</body>
</html>
