<?php
header('Content-Type: application/json; charset=utf-8');
require_once __DIR__ . '/../../../config/database.php';
require_once __DIR__ . '/../../../config/helpers/notification.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'message' => 'Method not allowed']);
    exit;
}

$input = json_decode(file_get_contents('php://input'), true) ?? [];
$reference = trim($input['reference'] ?? '');
$type = strtolower(trim($input['type'] ?? 'enrollment'));
$enrollmentId = (int)($input['enrollment_id'] ?? 0);
$appointmentId = (int)($input['appointment_id'] ?? 0);
$userId = (int)($input['user_id'] ?? 0);

if ($reference === '') {
    echo json_encode(['success' => false, 'message' => 'reference is required']);
    exit;
}

if ($type === 'appointment') {
    if (!$appointmentId) {
        echo json_encode(['success' => false, 'message' => 'appointment_id required for appointment payments']);
        exit;
    }
} elseif ($type === 'ai_premium') {
    if (!$userId) {
        echo json_encode(['success' => false, 'message' => 'user_id required for ai_premium payments']);
        exit;
    }
} else {
    if (!$enrollmentId) {
        echo json_encode(['success' => false, 'message' => 'enrollment_id required']);
        exit;
    }
}

$db = Database::getInstance();
$secret = PAYSTACK_SECRET_KEY;
$verifyUrl = 'https://api.paystack.co/transaction/verify/' . urlencode($reference);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $verifyUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer {$secret}"]); 
$response = curl_exec($ch);
$errno = curl_errno($ch);
$err = curl_error($ch);
curl_close($ch);
if ($errno) { echo json_encode(['success' => false, 'message' => 'Paystack verify failed: ' . $err]); exit; }
$data = json_decode($response, true);
if (empty($data['status']) || $data['status'] !== true) { echo json_encode(['success' => false, 'message' => 'Paystack returned error', 'response' => $data]); exit; }

$refData = $data['data'];
if (($refData['status'] ?? '') !== 'success') { echo json_encode(['success' => false, 'message' => 'Payment not successful', 'data' => $refData]); exit; }

// Amount paid in major units (Paystack returns kobo)
$paidAmount = ((float)$refData['amount']) / 100.0;

if ($type === 'ai_premium') {
    $expectedAmount = defined('AI_PREMIUM_PRICE') ? (float)AI_PREMIUM_PRICE : 0.0;
    if ($expectedAmount <= 0) {
        echo json_encode(['success' => false, 'message' => 'Invalid AI Premium amount configuration']);
        exit;
    }

    if (abs($paidAmount - $expectedAmount) > 0.01) {
        echo json_encode([
            'success' => false,
            'message' => 'Amount mismatch for AI Premium purchase',
            'paid' => $paidAmount,
            'expected' => $expectedAmount,
        ]);
        exit;
    }

    // Optional metadata consistency checks
    if (!empty($refData['metadata']) && is_array($refData['metadata'])) {
        $meta = $refData['metadata'];
        if (!empty($meta['type']) && $meta['type'] !== 'ai_premium') {
            echo json_encode(['success' => false, 'message' => 'Payment metadata type mismatch for AI Premium']);
            exit;
        }
        if (!empty($meta['user_id']) && (int)$meta['user_id'] !== $userId) {
            echo json_encode(['success' => false, 'message' => 'Payment metadata user mismatch for AI Premium']);
            exit;
        }
    }

    // Ensure user exists
    $user = $db->get('SELECT id FROM users WHERE id = ?', [$userId]);
    if (!$user) {
        echo json_encode(['success' => false, 'message' => 'User not found for AI Premium payment']);
        exit;
    }

    try {
        $txnId = $refData['reference'] ?? $reference;
        $existingPayment = $db->get('SELECT id FROM payments WHERE transaction_id = ? AND payment_method = ? LIMIT 1', [$txnId, 'paystack']);
        if (!$existingPayment) {
            $currency = strtoupper($refData['currency'] ?? (defined('AI_PREMIUM_CURRENCY_PAYSTACK') ? AI_PREMIUM_CURRENCY_PAYSTACK : 'NGN'));

            $db->insert('payments', [
                'user_id' => $userId,
                'course_id' => null,
                'enrollment_id' => null,
                'appointment_id' => null,
                'payment_type' => 'ai_premium',
                'amount' => $paidAmount,
                'currency' => $currency,
                'payment_method' => 'paystack',
                'payment_status' => 'completed',
                'transaction_id' => $txnId,
                'gateway_response' => json_encode($refData),
                'paid_at' => formatDate(),
            ]);
        }
    } catch (Exception $e) {
        echo json_encode(['success' => false, 'message' => 'Failed to record AI Premium payment.']);
        exit;
    }

    echo json_encode(['success' => true, 'data' => $refData]);
    exit;
}

if ($type === 'appointment') {
    // Verify against appointment amount and update appointment payment fields
    $appointment = $db->get('SELECT * FROM appointments WHERE id = ?', [$appointmentId]);
    if (!$appointment) {
        echo json_encode(['success' => false, 'message' => 'Appointment not found']);
        exit;
    }

    if (($appointment['payment_status'] ?? 'free') !== 'pending') {
        echo json_encode(['success' => false, 'message' => 'Appointment is not pending payment']);
        exit;
    }

    $expectedAmount = (float)($appointment['amount'] ?? 0.0);
    if ($expectedAmount <= 0) {
        echo json_encode(['success' => false, 'message' => 'Invalid appointment amount']);
        exit;
    }

    if (abs($paidAmount - $expectedAmount) > 0.01) {
        echo json_encode([
            'success' => false,
            'message' => 'Amount mismatch for appointment',
            'paid' => $paidAmount,
            'expected' => $expectedAmount,
        ]);
        exit;
    }

    // Optional: cross-check metadata if present
    if (!empty($refData['metadata']) && is_array($refData['metadata'])) {
        $meta = $refData['metadata'];
        if (!empty($meta['appointment_id']) && (int)$meta['appointment_id'] !== $appointmentId) {
            echo json_encode(['success' => false, 'message' => 'Payment metadata does not match appointment.']);
            exit;
        }
    }

    $paidAt = formatDate();

    $db->update('appointments', [
        'payment_status' => 'paid',
        'payment_gateway' => 'paystack',
        'payment_reference' => $refData['reference'] ?? $reference,
        'paid_at' => $paidAt,
    ], 'id = ?', [$appointmentId]);

    // Record payment in payments table for admin reporting
    $appointmentUserId = (int)($appointment['user_id'] ?? 0);
    if ($appointmentUserId > 0) {
        $txnId = $refData['reference'] ?? $reference;
        $existingPayment = $db->get('SELECT id FROM payments WHERE transaction_id = ? AND payment_method = ? LIMIT 1', [$txnId, 'paystack']);
        if (!$existingPayment) {
            // Try to resolve course_id from related enrollment if any
            $courseId = null;
            if (!empty($appointment['course_id'])) {
                $courseId = (int)$appointment['course_id'];
            }

            $currency = strtoupper($appointment['currency'] ?? ($refData['currency'] ?? 'GHS'));

            $db->insert('payments', [
                'user_id' => $appointmentUserId,
                'course_id' => $courseId,
                'enrollment_id' => null,
                'appointment_id' => $appointmentId,
                'payment_type' => 'appointment',
                'amount' => $paidAmount,
                'currency' => $currency,
                'payment_method' => 'paystack',
                'payment_status' => 'completed',
                'transaction_id' => $txnId,
                'gateway_response' => json_encode($refData),
                'paid_at' => $paidAt,
            ]);
        }
    }

    echo json_encode(['success' => true, 'data' => $refData]);
    exit;
}

// Default behaviour: verify against enrollment or next installment
$enrollment = $db->get('SELECT * FROM course_enrollments WHERE id = ?', [$enrollmentId]);
if (!$enrollment) { echo json_encode(['success' => false, 'message' => 'Enrollment not found']); exit; }

$hasInstallments = $db->get('SELECT id FROM enrollment_installments WHERE enrollment_id = ? LIMIT 1', [$enrollmentId]);

if ($hasInstallments) {
    // Find next pending installment
    $inst = $db->get('SELECT * FROM enrollment_installments WHERE enrollment_id = ? AND status = ? ORDER BY installment_no ASC LIMIT 1', [$enrollmentId, 'pending']);
    if (!$inst) {
        echo json_encode(['success' => false, 'message' => 'No pending installment found for this enrollment']);
        exit;
    }

    if (abs($paidAmount - (float)$inst['amount']) > 0.01) {
        echo json_encode([
            'success' => false,
            'message' => 'Amount mismatch for installment',
            'paid' => $paidAmount,
            'expected' => (float)$inst['amount'],
        ]);
        exit;
    }

    // Mark installment as paid
    $db->update('enrollment_installments', [
        'status' => 'paid',
        'payment_id' => $refData['reference'],
        'gateway' => 'paystack',
        'paid_at' => formatDate(),
    ], 'id = ?', [$inst['id']]);

    // Check if more installments remain
    $next = $db->get('SELECT * FROM enrollment_installments WHERE enrollment_id = ? AND status = ? ORDER BY installment_no ASC LIMIT 1', [$enrollmentId, 'pending']);

    if ($next) {
        // Still installments remaining: keep payment_status pending but activate course access
        $db->update('course_enrollments', [
            'payment_status' => 'pending',
            'payment_id' => $refData['reference'],
            'status' => 'active',
            'payment_amount' => (float)$next['amount'],
        ], 'id = ?', [$enrollmentId]);
    } else {
        // All installments paid: mark enrollment fully paid and active
        $db->update('course_enrollments', [
            'payment_status' => 'paid',
            'payment_id' => $refData['reference'],
            'status' => 'active',
        ], 'id = ?', [$enrollmentId]);

        // Increment enrollment count once when plan is fully paid
        $db->query('UPDATE courses SET enrollment_count = enrollment_count + 1 WHERE id = ?', [$enrollment['course_id']]);
    }
} else {
    if (abs($paidAmount - (float)$enrollment['payment_amount']) > 0.01) {
        echo json_encode([
            'success' => false,
            'message' => 'Amount mismatch',
            'paid' => $paidAmount,
            'expected' => (float)$enrollment['payment_amount'],
        ]);
        exit;
    }

    // mark enrollment paid in full
    $db->update('course_enrollments', [
        'payment_status' => 'paid',
        'payment_id' => $refData['reference'],
        'status' => 'active',
    ], 'id = ?', [$enrollmentId]);

    $db->query('UPDATE courses SET enrollment_count = enrollment_count + 1 WHERE id = ?', [$enrollment['course_id']]);
}

// Record course enrollment payment in payments table for admin reporting
try {
    $enrollmentUserId = (int)($enrollment['student_id'] ?? 0);
    if ($enrollmentUserId > 0) {
        $txnId = $refData['reference'] ?? $reference;
        $existingPayment = $db->get('SELECT id FROM payments WHERE transaction_id = ? AND payment_method = ? LIMIT 1', [$txnId, 'paystack']);
        if (!$existingPayment) {
            $currency = strtoupper($enrollment['payment_currency'] ?? ($refData['currency'] ?? 'USD'));

            $db->insert('payments', [
                'user_id' => $enrollmentUserId,
                'course_id' => (int)($enrollment['course_id'] ?? 0) ?: null,
                'enrollment_id' => $enrollmentId,
                'appointment_id' => null,
                'payment_type' => 'course_enrollment',
                'amount' => $paidAmount,
                'currency' => $currency,
                'payment_method' => 'paystack',
                'payment_status' => 'completed',
                'transaction_id' => $txnId,
                'gateway_response' => json_encode($refData),
                'paid_at' => formatDate(),
            ]);
        }
    }
} catch (Exception $e) {
    // Payments table is for reporting; ignore errors here
}

// send invoice email
sendEnrollmentInvoice($enrollmentId, 'paystack', $refData);

echo json_encode(['success' => true, 'data' => $refData]);
exit;
