<?php
// ============================================================
// CARD FUNCTION LIBRARY
// Located at: /include/Function/cardFunction.php
// ============================================================

/**
 * Fee schedule for each card level.
 * Update these values if your pricing changes.
 */
if (!function_exists('getCardFees')) {
    function getCardFees() {
        return [
            'Standard' => 5.00,
            'Gold'     => 15.00,
            'Platinum' => 30.00,
            'Black'    => 50.00,
        ];
    }
}

/**
 * Get the fee for a specific card level.
 */
if (!function_exists('getCardFee')) {
    function getCardFee($level) {
        $fees = getCardFees();
        return $fees[$level] ?? 5.00;
    }
}

/**
 * Generate a new card number based on the card type.
 * Uses issuer prefixes:
 *   Visa                -> starts with 4
 *   Mastercard          -> starts with 5
 *   American Express    -> starts with 34 or 37 (15 digits)
 *   Discover            -> starts with 6011
 */
if (!function_exists('generateCardNumber')) {
    function generateCardNumber($cardType = 'Visa') {
        $rand = function ($length) {
            $digits = '';
            for ($i = 0; $i < $length; $i++) {
                $digits .= random_int(0, 9);
            }
            return $digits;
        };

        switch ($cardType) {
            case 'Mastercard':
                return '5' . $rand(3) . ' ' . $rand(4) . ' ' . $rand(4) . ' ' . $rand(4);
            case 'American Express':
                // Amex is 15 digits grouped 4-6-5
                return '3' . $rand(3) . ' ' . $rand(6) . ' ' . $rand(5);
            case 'Discover':
                return '6011 ' . $rand(4) . ' ' . $rand(4) . ' ' . $rand(4);
            case 'Visa':
            default:
                return '4' . $rand(3) . ' ' . $rand(4) . ' ' . $rand(4) . ' ' . $rand(4);
        }
    }
}

/**
 * Generate a realistic card expiry date (3 years from today, MM / YY format).
 */
if (!function_exists('generateCardExpiry')) {
    function generateCardExpiry() {
        $expiry = strtotime('+3 years');
        return date('m', $expiry) . ' / ' . date('y', $expiry);
    }
}

/**
 * Generate a CVV for the card based on type.
 * Amex uses 4 digits, everyone else uses 3.
 */
if (!function_exists('generateCardCvv')) {
    function generateCardCvv($cardType = 'Visa') {
        $length = ($cardType === 'American Express') ? 4 : 3;
        $cvv = '';
        for ($i = 0; $i < $length; $i++) {
            $cvv .= random_int(0, 9);
        }
        return $cvv;
    }
}

/**
 * Main card application handler.
 * Validates input, deducts fee from user balance, and inserts into card table.
 *
 * @param PDO   $conn   PDO connection
 * @param int   $user_id
 * @param array $data   POST data (card_level, card_type, cardholder_name, billing_*)
 * @param array $row    Current user row (for balance check and email)
 * @param array $extras Optional: sendMail, email_message, page, APP_NAME, APP_URL
 *
 * @return array ['success' => bool, 'message' => string, 'card_id' => int|null]
 */
if (!function_exists('applyForCard')) {
    function applyForCard($conn, $user_id, $data, $row, $extras = []) {
        // Validate required inputs
        $required = ['card_level', 'card_type', 'cardholder_name', 'billing_address', 'billing_city', 'billing_zipcode', 'billing_country'];
        foreach ($required as $field) {
            if (empty($data[$field])) {
                return ['success' => false, 'message' => 'Please fill in all required fields: ' . $field, 'card_id' => null];
            }
        }

        $cardLevel      = trim($data['card_level']);
        $cardType       = trim($data['card_type']);
        $cardholderName = trim($data['cardholder_name']);
        $billingAddress = trim($data['billing_address']);
        $billingCity    = trim($data['billing_city']);
        $billingZip     = trim($data['billing_zipcode']);
        $billingCountry = trim($data['billing_country']);

        // Validate allowed values
        $validLevels = ['Standard', 'Gold', 'Platinum', 'Black'];
        $validTypes  = ['Visa', 'Mastercard', 'American Express', 'Discover'];

        if (!in_array($cardLevel, $validLevels, true)) {
            return ['success' => false, 'message' => 'Invalid card level selected', 'card_id' => null];
        }
        if (!in_array($cardType, $validTypes, true)) {
            return ['success' => false, 'message' => 'Invalid card type selected', 'card_id' => null];
        }

        // Get fee
        $cardFee = getCardFee($cardLevel);

        // Check user's current balance (fresh read)
        $checkUser = $conn->prepare("SELECT * FROM users WHERE id = :id LIMIT 1");
        $checkUser->execute(['id' => $user_id]);
        $userRow = $checkUser->fetch(PDO::FETCH_ASSOC);

        if (!$userRow) {
            return ['success' => false, 'message' => 'User not found', 'card_id' => null];
        }

        if ((float) $userRow['acct_balance'] < $cardFee) {
            return ['success' => false, 'message' => 'Insufficient balance to cover the ' . $cardLevel . ' card fee', 'card_id' => null];
        }

        // Generate card details
        $seriaKey      = uniqid('CARD', false);
        $cardNumber    = generateCardNumber($cardType);
        $cardExpiry    = generateCardExpiry();
        $cardSecurity  = generateCardCvv($cardType);
        $cardName      = $cardLevel . ' ' . $cardType;

        try {
            $conn->beginTransaction();

            // Deduct the card fee from user balance
            $newBalance = (float) $userRow['acct_balance'] - $cardFee;
            $updateSql = "UPDATE users SET acct_balance = :new_balance WHERE id = :user_id";
            $updateStmt = $conn->prepare($updateSql);
            $updateStmt->execute([
                'new_balance' => $newBalance,
                'user_id'     => $user_id
            ]);

            // Insert the card record
            $insertSql = "INSERT INTO card
                (card_name, card_level, card_type, card_number, card_expiration, card_security,
                 cardholder_name, billing_address, billing_city, billing_zipcode, billing_country,
                 card_fee, user_id, seria_key, card_status)
                VALUES
                (:card_name, :card_level, :card_type, :card_number, :card_expiration, :card_security,
                 :cardholder_name, :billing_address, :billing_city, :billing_zipcode, :billing_country,
                 :card_fee, :user_id, :seria_key, :card_status)";

            $insertStmt = $conn->prepare($insertSql);
            $insertStmt->execute([
                'card_name'        => $cardName,
                'card_level'       => $cardLevel,
                'card_type'        => $cardType,
                'card_number'      => $cardNumber,
                'card_expiration'  => $cardExpiry,
                'card_security'    => $cardSecurity,
                'cardholder_name'  => $cardholderName,
                'billing_address'  => $billingAddress,
                'billing_city'     => $billingCity,
                'billing_zipcode'  => $billingZip,
                'billing_country'  => $billingCountry,
                'card_fee'         => $cardFee,
                'user_id'          => $user_id,
                'seria_key'        => $seriaKey,
                'card_status'      => 0  // 0 = pending approval
            ]);

            $cardId = $conn->lastInsertId();
            $conn->commit();

            // Send confirmation email (optional — only if mailer is provided)
            if (!empty($extras['sendMail']) && !empty($extras['email_message'])) {
                try {
                    $fullName    = ($row['firstname'] ?? '') . ' ' . ($row['lastname'] ?? '');
                    $userEmail   = $row['acct_email'] ?? '';
                    $userAcctNo  = $row['acct_no'] ?? '';
                    $appName     = $extras['APP_NAME'] ?? (defined('WEB_TITLE') ? WEB_TITLE : 'Bank');
                    $appUrl      = $extras['APP_URL'] ?? (defined('WEB_URL') ? WEB_URL : '');
                    $siteAddress = $extras['page']['url_address'] ?? '';
                    $cardStatus  = 'Processing';

                    if (!empty($userEmail)) {
                        $emailBody = $extras['sendMail']->CardMsg(
                            $fullName,
                            $cardName,
                            $userAcctNo,
                            $cardFee,
                            $cardStatus,
                            $appName,
                            $appUrl,
                            $siteAddress
                        );
                        $subject = "Card Request - " . $appName;
                        $extras['email_message']->send_mail($userEmail, $emailBody, $subject);
                    }
                } catch (Exception $mailEx) {
                    // Email failure shouldn't roll back the card — just silently continue
                }
            }

            return [
                'success' => true,
                'message' => 'Your ' . $cardLevel . ' ' . $cardType . ' card application has been submitted successfully!',
                'card_id' => $cardId
            ];

        } catch (Exception $e) {
            if ($conn->inTransaction()) {
                $conn->rollBack();
            }
            return ['success' => false, 'message' => 'An error occurred while processing your application. Please try again.', 'card_id' => null];
        }
    }
}

// ============================================================
// Keep any existing functions in your original cardFunction.php
// file by appending this new code BELOW them, or merge manually.
// ============================================================