<?php
require_once __DIR__ . '/../../../config/database.php';
require_once __DIR__ . '/../../../config/helpers/notification.php';

$type = strtolower(trim($_GET['type'] ?? 'enrollment'));
$enrollmentId = (int)($_GET['enrollment_id'] ?? 0);
$appointmentId = (int)($_GET['appointment_id'] ?? 0);
$userId = (int)($_GET['user_id'] ?? 0);
$transactionId = trim($_GET['transactionId'] ?? ($_GET['paymentId'] ?? ''));

if ($type === 'appointment') {
    if (!$appointmentId) {
        http_response_code(400);
        echo 'Invalid Square verification request: missing appointment_id.';
        exit;
    }
} elseif ($type === 'ai_premium') {
    if (!$userId) {
        http_response_code(400);
        echo 'Invalid Square verification request: missing user_id.';
        exit;
    }
} else {
    if (!$enrollmentId) {
        http_response_code(400);
        echo 'Invalid Square verification request: missing enrollment_id.';
        exit;
    }
}

if (!defined('SQUARE_ACCESS_TOKEN') || !SQUARE_ACCESS_TOKEN) {
    http_response_code(500);
    echo 'Square access token is not configured.';
    exit;
}

$db = Database::getInstance();

// Load context and expected amount depending on type
if ($type === 'appointment') {
    $appointment = $db->get('SELECT * FROM appointments WHERE id = ?', [$appointmentId]);
    if (!$appointment) {
        http_response_code(404);
        echo 'Appointment not found.';
        exit;
    }

    if (($appointment['payment_status'] ?? 'free') !== 'pending') {
        // If already processed, just redirect to learner appointments page
        header('Location: ' . APP_URL . '/lms/appointments.php');
        exit;
    }

    $expectedAmount = (float)($appointment['amount'] ?? 0.0);
    if ($expectedAmount <= 0) {
        http_response_code(400);
        echo 'Appointment has no payable amount.';
        exit;
    }
} elseif ($type === 'ai_premium') {
    // Ensure user exists
    $user = $db->get('SELECT id FROM users WHERE id = ?', [$userId]);
    if (!$user) {
        http_response_code(404);
        echo 'User not found.';
        exit;
    }

    $expectedAmount = defined('AI_PREMIUM_PRICE') ? (float)AI_PREMIUM_PRICE : 0.0;
    if ($expectedAmount <= 0) {
        http_response_code(500);
        echo 'Invalid AI Premium amount configuration.';
        exit;
    }
} else {
    $enrollment = $db->get('SELECT * FROM course_enrollments WHERE id = ?', [$enrollmentId]);

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

    if ($enrollment['payment_status'] !== 'pending') {
        header('Location: ' . APP_URL . '/lms/dashboard.php');
        exit;
    }

    $expectedAmount = (float)($enrollment['payment_amount'] ?? 0.0);
    if ($expectedAmount <= 0) {
        http_response_code(400);
        echo 'Enrollment has no payable amount.';
        exit;
    }
}

// Some Square checkout/payment-link flows (including the sandbox testing panel)
// redirect back without appending transactionId/paymentId to the URL. In that
// case, during development we treat the redirect as a successful payment
// confirmation and mark the enrollment as paid/active without an extra API
// verify call. In production we still require a transactionId for safety.
if ($transactionId === '') {
    if (!defined('APP_ENV') || APP_ENV !== 'development') {
        http_response_code(400);
        echo 'Invalid Square verification request: missing transactionId.';
        exit;
    }

    // In development, treat redirect without transactionId as success
    if ($type === 'ai_premium') {
        $paymentId = 'square-ai-premium-' . $userId . '-' . time();

        try {
            $existingPayment = $db->get('SELECT id FROM payments WHERE transaction_id = ? AND payment_method = ? LIMIT 1', [$paymentId, 'square']);
            if (!$existingPayment) {
                $amount = defined('AI_PREMIUM_PRICE') ? (float)AI_PREMIUM_PRICE : 0.0;
                $currency = defined('AI_PREMIUM_CURRENCY_SQUARE') ? strtoupper(AI_PREMIUM_CURRENCY_SQUARE) : 'USD';

                $fakePayment = [
                    'id' => $paymentId,
                    'status' => 'COMPLETED',
                    'amount_money' => [
                        'amount' => (int)round($amount * 100),
                        'currency' => $currency,
                    ],
                ];

                $db->insert('payments', [
                    'user_id' => $userId,
                    'course_id' => null,
                    'enrollment_id' => null,
                    'appointment_id' => null,
                    'payment_type' => 'ai_premium',
                    'amount' => $amount,
                    'currency' => $currency,
                    'payment_method' => 'square',
                    'payment_status' => 'completed',
                    'transaction_id' => $paymentId,
                    'gateway_response' => json_encode($fakePayment),
                    'paid_at' => formatDate(),
                ]);
            }
        } catch (Exception $e) {
            // Reporting-only; ignore
        }

        header('Location: ' . APP_URL . '/lms/ai_premium.php');
        exit;
    }

    $paymentId = 'square-' . ($type === 'appointment' ? $appointmentId : $enrollmentId) . '-' . time();

    if ($type === 'appointment') {
        $paidAt = formatDate();

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

        // Record appointment payment in payments table (dev-mode shortcut)
        $appointmentUserId = (int)($appointment['user_id'] ?? 0);
        if ($appointmentUserId > 0) {
            try {
                $existingPayment = $db->get('SELECT id FROM payments WHERE transaction_id = ? AND payment_method = ? LIMIT 1', [$paymentId, 'square']);
                if (!$existingPayment) {
                    $currency = strtoupper($appointment['currency'] ?? 'USD');
                    $db->insert('payments', [
                        'user_id' => $appointmentUserId,
                        'course_id' => !empty($appointment['course_id']) ? (int)$appointment['course_id'] : null,
                        'enrollment_id' => null,
                        'appointment_id' => $appointmentId,
                        'payment_type' => 'appointment',
                        'amount' => $expectedAmount,
                        'currency' => $currency,
                        'payment_method' => 'square',
                        'payment_status' => 'completed',
                        'transaction_id' => $paymentId,
                        'gateway_response' => json_encode($fakePayment),
                        'paid_at' => $paidAt,
                    ]);
                }
            } catch (Exception $e) {
                // Reporting-only; ignore
            }
        }

        header('Location: ' . APP_URL . '/lms/appointments.php');
        exit;
    }

    // For enrollments we treat Square as full-payment only here. If installments
    // were configured, they will be considered fully paid as well.
    $db->update('course_enrollments', [
        'payment_status' => 'paid',
        'payment_id' => $paymentId,
        'status' => 'active',
    ], 'id = ?', [$enrollmentId]);

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

    // Build a minimal payment payload for invoice logging
    $fakePayment = [
        'id' => $paymentId,
        'status' => 'COMPLETED',
        'amount_money' => [
            'amount' => (int)round($expectedAmount * 100),
        ],
    ];

    // Record course enrollment payment in payments table (dev-mode shortcut)
    $enrollmentUserId = (int)($enrollment['student_id'] ?? 0);
    if ($enrollmentUserId > 0) {
        try {
            $existingPayment = $db->get('SELECT id FROM payments WHERE transaction_id = ? AND payment_method = ? LIMIT 1', [$paymentId, 'square']);
            if (!$existingPayment) {
                $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' => $expectedAmount,
                    'currency' => strtoupper($enrollment['payment_currency'] ?? 'USD'),
                    'payment_method' => 'square',
                    'payment_status' => 'completed',
                    'transaction_id' => $paymentId,
                    'gateway_response' => json_encode($fakePayment),
                    'paid_at' => formatDate(),
                ]);
            }
        } catch (Exception $e) {
            // Reporting-only; ignore
        }
    }

    sendEnrollmentInvoice($enrollmentId, 'square', $fakePayment);

    header('Location: ' . APP_URL . '/lms/dashboard.php');
    exit;
}

$base = defined('SQUARE_API_BASE') && SQUARE_API_BASE ? SQUARE_API_BASE : 'https://connect.squareupsandbox.com';
$url = rtrim($base, '/') . '/v2/payments/' . urlencode($transactionId);

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . SQUARE_ACCESS_TOKEN,
        'Content-Type: application/json',
    ],
]);

$response = curl_exec($ch);
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);

if ($errno) {
    http_response_code(500);
    echo 'Square verify failed: ' . $error;
    exit;
}

$data = json_decode($response, true);
if (!is_array($data) || empty($data['payment'])) {
    http_response_code(500);
    echo 'Unexpected verify response from Square.';
    exit;
}

$payment = $data['payment'];
$status = $payment['status'] ?? '';

if ($status !== 'COMPLETED') {
    http_response_code(400);
    echo 'Payment is not completed.';
    exit;
}

$money = $payment['amount_money'] ?? [];
$paidAmountBase = isset($money['amount']) ? (float)$money['amount'] : 0.0;
$paidAmount = $paidAmountBase / 100.0;

if ($paidAmount <= 0) {
    http_response_code(400);
    echo 'Invalid amount in Square verify response.';
    exit;
}

if ($type === 'ai_premium') {
    $expectedAmount = defined('AI_PREMIUM_PRICE') ? (float)AI_PREMIUM_PRICE : 0.0;
    if ($expectedAmount <= 0) {
        http_response_code(500);
        echo 'Invalid AI Premium amount configuration.';
        exit;
    }

    if (abs($paidAmount - $expectedAmount) > 0.01) {
        http_response_code(400);
        echo 'Amount mismatch between Square and AI Premium.';
        exit;
    }

    $paymentId = $payment['id'] ?? $transactionId;

    try {
        $existingPayment = $db->get('SELECT id FROM payments WHERE transaction_id = ? AND payment_method = ? LIMIT 1', [$paymentId, 'square']);
        if (!$existingPayment) {
            $currency = strtoupper($money['currency'] ?? (defined('AI_PREMIUM_CURRENCY_SQUARE') ? AI_PREMIUM_CURRENCY_SQUARE : 'USD'));
            $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' => 'square',
                'payment_status' => 'completed',
                'transaction_id' => $paymentId,
                'gateway_response' => json_encode($payment),
                'paid_at' => formatDate(),
            ]);
        }
    } catch (Exception $e) {
        // Reporting-only; ignore
    }

    header('Location: ' . APP_URL . '/lms/ai_premium.php');
    exit;
}

if ($type === 'appointment') {
    if (abs($paidAmount - $expectedAmount) > 0.01) {
        http_response_code(400);
        echo 'Amount mismatch between Square and appointment.';
        exit;
    }

    $paymentId = $payment['id'] ?? $transactionId;
    $paidAt = formatDate();

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

    // Record appointment payment in payments table
    $appointmentUserId = (int)($appointment['user_id'] ?? 0);
    if ($appointmentUserId > 0) {
        try {
            $existingPayment = $db->get('SELECT id FROM payments WHERE transaction_id = ? AND payment_method = ? LIMIT 1', [$paymentId, 'square']);
            if (!$existingPayment) {
                $currency = strtoupper($appointment['currency'] ?? ($money['currency'] ?? 'USD'));
                $db->insert('payments', [
                    'user_id' => $appointmentUserId,
                    'course_id' => !empty($appointment['course_id']) ? (int)$appointment['course_id'] : null,
                    'enrollment_id' => null,
                    'appointment_id' => $appointmentId,
                    'payment_type' => 'appointment',
                    'amount' => $paidAmount,
                    'currency' => $currency,
                    'payment_method' => 'square',
                    'payment_status' => 'completed',
                    'transaction_id' => $paymentId,
                    'gateway_response' => json_encode($payment),
                    'paid_at' => $paidAt,
                ]);
            }
        } catch (Exception $e) {
            // Reporting-only; ignore
        }
    }

    header('Location: ' . APP_URL . '/lms/appointments.php');
    exit;
}

// Default behaviour: enrollment verification, including installments
$hasInstallments = $db->get('SELECT id FROM enrollment_installments WHERE enrollment_id = ? LIMIT 1', [$enrollmentId]);

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

    if (abs($paidAmount - (float)$inst['amount']) > 0.01) {
        http_response_code(400);
        echo 'Amount mismatch between Square and installment.';
        exit;
    }

    $paymentId = $payment['id'] ?? $transactionId;

    $db->update('enrollment_installments', [
        'status' => 'paid',
        'payment_id' => $paymentId,
        'gateway' => 'square',
        'paid_at' => formatDate(),
    ], 'id = ?', [$inst['id']]);

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

    if ($next) {
        $db->update('course_enrollments', [
            'payment_status' => 'pending',
            'payment_id' => $paymentId,
            'status' => 'active',
            'payment_amount' => (float)$next['amount'],
        ], 'id = ?', [$enrollmentId]);
    } else {
        $db->update('course_enrollments', [
            'payment_status' => 'paid',
            'payment_id' => $paymentId,
            'status' => 'active',
        ], 'id = ?', [$enrollmentId]);

        $db->query('UPDATE courses SET enrollment_count = enrollment_count + 1 WHERE id = ?', [$enrollment['course_id']]);
    }
} else {
    if (abs($paidAmount - $expectedAmount) > 0.01) {
        http_response_code(400);
        echo 'Amount mismatch between Square and enrollment.';
        exit;
    }

    $paymentId = $payment['id'] ?? $transactionId;

    $db->update('course_enrollments', [
        'payment_status' => 'paid',
        'payment_id' => $paymentId,
        'status' => 'active',
    ], 'id = ?', [$enrollmentId]);

    $db->query('UPDATE courses SET enrollment_count = enrollment_count + 1 WHERE id = ?', [$enrollment['course_id']]);
}
// Record enrollment payment in payments table
try {
    $enrollmentUserId = (int)($enrollment['student_id'] ?? 0);
    if ($enrollmentUserId > 0) {
        $txnId = $payment['id'] ?? $transactionId;
        $existingPayment = $db->get('SELECT id FROM payments WHERE transaction_id = ? AND payment_method = ? LIMIT 1', [$txnId, 'square']);
        if (!$existingPayment) {
            $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' => strtoupper($enrollment['payment_currency'] ?? ($money['currency'] ?? 'USD')),
                'payment_method' => 'square',
                'payment_status' => 'completed',
                'transaction_id' => $txnId,
                'gateway_response' => json_encode($payment),
                'paid_at' => formatDate(),
            ]);
        }
    }
} catch (Exception $e) {
    // Reporting-only; ignore
}

sendEnrollmentInvoice($enrollmentId, 'square', $payment);

header('Location: ' . APP_URL . '/lms/dashboard.php');
exit;
