<?php
/*
* Plugin Name: LucyDream Credits
 * Description: Manage credits on LucyDream, admin dashboard views, user balance tracking, and in-place balance editing
 * Version: 1.0
 * Author: LucyDream
 */

if (!defined('ABSPATH')) {
    exit; // Prevent direct access
}

// Include the payments page file
require_once __DIR__ . '/lucydream-payments-page.php';

// Include the transaction history file
require_once __DIR__ . '/lucydream-transaction-history.php';

// Calculate real-time balance
function lucydream_calculate_balance($user_id) {
    $purchased = get_user_meta($user_id, 'purchased_credits', true) ?: 0.00;
    $expended = get_user_meta($user_id, 'expended_credits', true) ?: 0.00;
    $pending = get_user_meta($user_id, 'pending_credits', true) ?: 0.00;
    $balance = round($purchased - $expended - $pending, 2); // Round to 2 decimal places
    return $balance;
}

// Add function to hold credits in pending state
function lucydream_hold_credits($user_id, $credits, $reason = 'Service request') {
    $current_balance = lucydream_calculate_balance($user_id);
    if ($current_balance < $credits) {
        return new WP_Error('insufficient_credits', 'Insufficient credits', array('status' => 400));
    }

    $current_pending = get_user_meta($user_id, 'pending_credits', true) ?: 0.00;
    $new_pending = $current_pending + $credits;
    $update_success = false;
    for ($i = 0; $i < 3; $i++) {
        $update_success = update_user_meta($user_id, 'pending_credits', $new_pending);
        if ($update_success !== false) {
            break;
        }
        sleep(1);
    }
    if ($update_success === false) {
        return new WP_Error('db_error', 'Failed to hold credits', array('status' => 500));
    }
    wp_cache_delete($user_id, 'user_meta');

    $pending_data = array(
        'transaction_id' => 'PENDING_' . time() . '_' . rand(100, 999),
        'credits' => $credits,
        'reason' => $reason,
        'date' => current_time('mysql'),
    );
    update_user_meta($user_id, 'pending_transactions_' . $pending_data['transaction_id'], $pending_data);

    return array(
        'success' => true,
        'pending_credits' => $new_pending,
        'transaction_id' => $pending_data['transaction_id']
    );
}

// Add function to commit pending credits on success
function lucydream_commit_pending_credits($user_id, $credits, $transaction_id, $reason = 'Service usage') {
    $current_pending = get_user_meta($user_id, 'pending_credits', true) ?: 0.00;
    if ($current_pending < $credits) {
        return new WP_Error('insufficient_pending', 'Insufficient pending credits', array('status' => 400));
    }

    $new_pending = $current_pending - $credits;
    $update_success = false;
    for ($i = 0; $i < 3; $i++) {
        $update_success = update_user_meta($user_id, 'pending_credits', $new_pending);
        if ($update_success !== false) {
            break;
        }
        sleep(1);
    }
    if ($update_success === false) {
        return new WP_Error('db_error', 'Failed to commit credits', array('status' => 500));
    }
    wp_cache_delete($user_id, 'user_meta');

    $current_expended = get_user_meta($user_id, 'expended_credits', true) ?: 0.00;
    $new_expended = $current_expended + $credits;
    $update_success = false;
    for ($i = 0; $i < 3; $i++) {
        $update_success = update_user_meta($user_id, 'expended_credits', $new_expended);
        if ($update_success !== false) {
            break;
        }
        sleep(1);
    }
    if ($update_success === false) {
        return new WP_Error('db_error', 'Failed to commit credits', array('status' => 500));
    }
    wp_cache_delete($user_id, 'user_meta');

    $expenditure_data = array(
        'transaction_id' => $transaction_id,
        'credits' => $credits,
        'reason' => $reason,
        'date' => current_time('mysql'),
    );
    update_user_meta($user_id, 'credit_expenditures_' . $transaction_id, $expenditure_data);
    delete_user_meta($user_id, 'pending_transactions_' . $transaction_id);

    return array(
        'success' => true,
        'new_expended' => $new_expended,
        'new_pending' => $new_pending
    );
}

// Add function to revert pending credits on failure
function lucydream_revert_pending_credits($user_id, $credits, $transaction_id, $reason = 'Service failed') {
    if (empty($transaction_id)) {
        return array(
            'success' => false,
            'message' => 'Invalid transaction ID'
        );
    }

    // Check if transaction was already processed
    $processed_key = 'processed_reversion_' . $transaction_id;
    if (get_user_meta($user_id, $processed_key, true)) {
        return array(
            'success' => false,
            'message' => 'Transaction already reverted'
        );
    }

    // Log initial credit state
    $initial_purchased = get_user_meta($user_id, 'purchased_credits', true) ?: 0.00;
    $initial_pending = get_user_meta($user_id, 'pending_credits', true) ?: 0.00;
    $initial_balance = lucydream_calculate_balance($user_id);

    // Acquire a lock for the user
    $lock_key = 'credit_lock_' . $user_id;
    $lock_acquired = set_transient($lock_key, 1, 10); // Lock for 10 seconds
    if (!$lock_acquired) {
        sleep(1); // Wait and retry
        $lock_acquired = set_transient($lock_key, 1, 10);
        if (!$lock_acquired) {
            return array(
                'success' => false,
                'message' => 'Unable to process due to concurrent updates'
            );
        }
    }

    try {

        // Check if the pending transaction exists
        $pending_transaction = get_user_meta($user_id, 'pending_transactions_' . $transaction_id, true);
        if (!$pending_transaction) {
            return array(
                'success' => false,
                'message' => 'No pending transaction to revert'
            );
        }

        // Mark transaction as being processed
        $flag_updated = update_user_meta($user_id, $processed_key, true);
        if ($flag_updated === false) {
        } else {
        }
        wp_cache_delete($user_id, 'user_meta');

        $current_pending = get_user_meta($user_id, 'pending_credits', true) ?: 0.00;
        if ($current_pending < $credits) {
            $credits = $current_pending; // Adjust to available credits
        }

        $new_pending = $current_pending - $credits;
        $update_success = false;
        for ($i = 0; $i < 3; $i++) {
            $update_success = update_user_meta($user_id, 'pending_credits', $new_pending);
            if ($update_success !== false) {
                break;
            }
            sleep(1);
        }
        if ($update_success === false) {
            delete_user_meta($user_id, $processed_key); // Clean up flag
            return array(
                'success' => false,
                'message' => 'Failed to update pending credits'
            );
        }
        wp_cache_delete($user_id, 'user_meta');

        $new_purchased = get_user_meta($user_id, 'purchased_credits', true) ?: 0.00;

        $delete_success = delete_user_meta($user_id, 'pending_transactions_' . $transaction_id);
        if ($delete_success === false) {
        } else {
        }

        $new_balance = lucydream_calculate_balance($user_id);

        // Log final state
        $final_purchased = get_user_meta($user_id, 'purchased_credits', true) ?: 0.00;
        $final_pending = get_user_meta($user_id, 'pending_credits', true) ?: 0.00;
        $final_balance = lucydream_calculate_balance($user_id);

        return array(
            'success' => true,
            'new_purchased' => $new_purchased,
            'new_pending' => $new_pending,
            'new_balance' => $new_balance
        );
    } catch (Exception $e) {
        delete_user_meta($user_id, $processed_key); // Clean up flag
        return array(
            'success' => false,
            'message' => 'Reversion failed: ' . $e->getMessage()
        );
    } finally {
        // Release the lock
        delete_transient($lock_key);
    }
}

// Add custom columns to the Users table
add_filter('manage_users_columns', 'lucydream_add_users_columns');
function lucydream_add_users_columns($columns) {
    $new_columns = array();
    $added_user_id = false;

    foreach ($columns as $key => $value) {
        if ($key === 'username' && !$added_user_id) {
            $new_columns['user_id'] = 'User ID';
            $added_user_id = true;
        }
        $new_columns[$key] = $value;

        if ($key === 'email' && !isset($new_columns['balance'])) {
            $new_columns['balance'] = 'Balance';
        }
    }

    return $new_columns;
}

// Populate custom columns in the Users table
add_action('manage_users_custom_column', 'lucydream_populate_users_columns', 10, 3);
function lucydream_populate_users_columns($value, $column_name, $user_id) {
    if ($column_name === 'user_id') {
        return $user_id;
    }
    if ($column_name === 'balance') {
        $nonce = wp_create_nonce('lucydream_edit_balance_' . $user_id);
        $balance = lucydream_calculate_balance($user_id);
        $value = '<span class="lucydream-editable-balance" data-user-id="' . $user_id . '" data-nonce="' . $nonce . '" data-balance="' . number_format($balance, 2) . '">' . number_format($balance, 2) . '</span>';
        return $value;
    }
    return $value;
}

// Handle AJAX request to update balance
add_action('wp_ajax_lucydream_update_balance', 'lucydream_update_balance');
function lucydream_update_balance() {
    if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'lucydream_edit_balance_' . $_POST['user_id'])) {
        wp_send_json_error(array('message' => 'Security check failed'));
        wp_die();
    }

    $user_id = intval($_POST['user_id']);
    $new_balance = floatval($_POST['new_balance']);

    $user = get_user_by('ID', $user_id);
    if (!$user) {
        wp_send_json_error(array('message' => 'User not found'));
        wp_die();
    }

    $current_purchased = get_user_meta($user_id, 'purchased_credits', true) ?: 0.00;
    $current_expended = get_user_meta($user_id, 'expended_credits', true) ?: 0.00;
    $current_balance = $current_purchased - $current_expended;

    $adjustment = $new_balance - $current_balance;
    $new_purchased = $current_purchased + $adjustment;
    $update_success = update_user_meta($user_id, 'purchased_credits', $new_purchased);
    if ($update_success === false) {
        wp_send_json_error(array('message' => 'Failed to update balance'));
        wp_die();
    }
    wp_cache_delete($user_id, 'user_meta');

    $transaction_id = 'GIFT_' . time() . '_' . rand(100, 999);
    $transaction_data = array(
        'transaction_id' => $transaction_id,
        'payment_type' => 'manual_gift',
        'credits' => $adjustment,
        'date' => current_time('mysql'),
    );
    update_user_meta($user_id, 'credit_transactions_' . $transaction_id, $transaction_data);

    wp_send_json_success(array(
        'message' => 'Balance updated successfully (Gift credits added)',
        'new_balance' => number_format($new_balance, 2),
    ));
    wp_die();
}

// Enqueue JavaScript for in-place balance editing and refresh button
add_action('admin_enqueue_scripts', 'lucydream_enqueue_admin_scripts');
function lucydream_enqueue_admin_scripts($hook) {
    if ($hook !== 'users.php' && $hook !== 'toplevel_page_lucydream-credits') {
        return;
    }
    wp_enqueue_script('lucydream-admin-js', plugin_dir_url(__FILE__) . 'lucydream-admin.js', array('jquery'), '1.1', true);
    wp_localize_script('lucydream-admin-js', 'lucydream_ajax', array(
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('lucydream_refresh_transactions'),
    ));
}

// Add shortcode to display user's real-time balance
add_shortcode('user_balance', 'lucydream_user_balance_shortcode');
function lucydream_user_balance_shortcode() {
    if (!is_user_logged_in()) {
        return 'Please log in to see your balance.';
    }
    $user_id = get_current_user_id();
    $balance = lucydream_calculate_balance($user_id);
    return 'Balance: ' . number_format($balance, 2);
}

/**
 * Add shortcode to display user info
 */
function lucydream_user_info_shortcode() {
    
    if (!is_user_logged_in()) {
        return '';
    }

    $user_id = get_current_user_id();
    $balance = lucydream_calculate_balance($user_id);
    $user_name = wp_get_current_user()->user_login;
    $logout_url = wp_logout_url(home_url('/home'));
    

    ob_start();
    ?>
    <div class="account-container">
    <div class="account-header">
            <div class="user-info">
            <span class="balance">Balance: <?php echo number_format($balance, 2); ?></span>
            <div class="buy-credits-container">
                <button class="buy-credits" data-user-id="<?php echo esc_attr($user_id); ?>">BUY CREDITS</button>
            </div>
            <span class="username"><?php echo esc_html($user_name); ?></span>
        </div>
    </div>
    </div>

    <style>
      .user-info {
        display: flex;
        align-items: center;
        gap: 15px;
      }
      .balance, .username {
        font-size: 16px;
      }
      .buy-credits {
        padding: 8px 16px;
        font-size: 14px;
      }
    </style>

    <script>
    document.addEventListener('DOMContentLoaded', function() {
        const buyCreditsContainers = document.querySelectorAll('.buy-credits-container');

        buyCreditsContainers.forEach(function(container) {
            const button = container.querySelector('.buy-credits');
            button.addEventListener('click', function(e) {
                e.preventDefault();
                window.location.href = '/payments/';
                console.log('BUY CREDITS clicked for user: <?php echo esc_js($user_name); ?>, Role: <?php echo current_user_can('administrator') ? 'admin' : 'non-admin'; ?>');
            });
        });
    });
    </script>
    <?php
    $output = ob_get_clean();
    return $output;
}

// Ensure the shortcode is registered
add_shortcode('user_info', 'lucydream_user_info_shortcode');

// Create database table on activation
register_activation_hook(__FILE__, 'lucydream_create_payments_table');

function lucydream_create_payments_table() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'lucydream_payments';
    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE $table_name (
        id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
        user_id bigint(20) UNSIGNED NOT NULL,
        amount decimal(10,2) NOT NULL,
        credits int NOT NULL,
        psp varchar(20) NOT NULL,
        transaction_id varchar(100) DEFAULT '',
        status varchar(20) DEFAULT 'pending',
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id)
    ) $charset_collate;";

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
    
    // Create payments page if it doesn't exist
    $payments_page = get_page_by_path('payments');
    if (!$payments_page) {
        $page_data = array(
            'post_title'    => 'Payments',
            'post_content'  => '[payments_form]',
            'post_status'   => 'publish',
            'post_type'     => 'page',
            'post_name'     => 'payments',
            'post_author'   => 1,
        );
        wp_insert_post($page_data);
    }
}

?>