<?php
require 'connection.php';

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

session_start();
$current_user_id = $_SESSION['user_id'] ?? 0;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $sponsor_id = (int) $_POST['sponsor_id'];
    $name = $conn->real_escape_string(trim($_POST['name']));
    $email = isset($_POST['email']) ? $conn->real_escape_string(trim($_POST['email'])) : '';
    $phone = $conn->real_escape_string(trim($_POST['phone']));
    $aadhaar = isset($_POST['aadhaar']) ? $conn->real_escape_string(trim($_POST['aadhaar'])) : '';
    $password = $_POST['password']; // Will be hashed
    $pin = $conn->real_escape_string(trim($_POST['pin']));
    $package_id = isset($_POST['package_id']) ? (int)$_POST['package_id'] : 0;

    // Validate required fields
    if (empty($name) || empty($phone) || empty($aadhaar) || empty($password) || empty($pin) || empty($package_id)) {
        header("Location: ../registration.php?error=" . urlencode("All fields are required"));
        exit();
    }

    // Validate phone number
    if (!preg_match('/^[0-9]{10}$/', $phone)) {
        header("Location: ../registration.php?error=" . urlencode("Invalid phone number. Must be 10 digits."));
        exit();
    }

    // Validate Aadhaar
    if (!preg_match('/^[0-9]{12}$/', $aadhaar)) {
        header("Location: ../registration.php?error=" . urlencode("Invalid Aadhaar number. Must be 12 digits."));
        exit();
    }

    // Validate password length
    if (strlen($password) < 6) {
        header("Location: ../registration.php?error=" . urlencode("Password must be at least 6 characters"));
        exit();
    }

    // Validate email if provided
    if (!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
        header("Location: ../registration.php?error=" . urlencode("Invalid email format"));
        exit();
    }

    // Check if phone already exists
    $phone_check = $conn->query("SELECT user_id FROM users WHERE mobile = '$phone' OR phone = '$phone'");
    if ($phone_check && $phone_check->num_rows > 0) {
        header("Location: ../registration.php?error=" . urlencode("Phone number already registered"));
        exit();
    }

    // Check if Aadhaar already exists
    $aadhaar_check = $conn->query("SELECT user_id FROM users WHERE aadharno = '$aadhaar'");
    if ($aadhaar_check && $aadhaar_check->num_rows > 0) {
        header("Location: ../registration.php?error=" . urlencode("Aadhaar number already registered"));
        exit();
    }

    // Check if email already exists (if provided)
    if (!empty($email)) {
        $email_check = $conn->query("SELECT user_id FROM users WHERE email = '$email'");
        if ($email_check && $email_check->num_rows > 0) {
            header("Location: ../registration.php?error=" . urlencode("Email already registered"));
            exit();
        }
    }

    $conn->begin_transaction();

    try {
        // Validate PIN belongs to current user and is unused
        $pin_query = $conn->query("SELECT * FROM pin WHERE pin_value = '$pin' AND status = '0' AND allcote_user = '$current_user_id'");
        if (!$pin_query || $pin_query->num_rows == 0) {
            throw new Exception("Invalid PIN or PIN does not belong to you.");
        }
        
        $pin_data = $pin_query->fetch_assoc();

        // Check if PIN has package_id and verify it matches
        if (isset($pin_data['package_id']) && $pin_data['package_id'] > 0 && $pin_data['package_id'] != $package_id) {
            throw new Exception("This PIN is not valid for the selected package.");
        }

        // Check if sponsor exists
        $checkSponsor = $conn->query("SELECT * FROM users WHERE user_id = $sponsor_id");
        if (!$checkSponsor || $checkSponsor->num_rows == 0) {
            throw new Exception("Sponsor ID not found.");
        }
        $sponsor_data = $checkSponsor->fetch_assoc();

        // Get the TOP ROOT user
        $topRootQuery = $conn->query("SELECT user_id FROM users WHERE user_id = 12345678");
        if (!$topRootQuery || $topRootQuery->num_rows == 0) {
            throw new Exception("Top root user not found.");
        }
        $topRoot = $topRootQuery->fetch_assoc();
        $root_id = $topRoot['user_id'];

        // Generate unique 8-digit user_id
        $max_attempts = 100;
        $attempts = 0;
        do {
            $new_user_id = rand(10000000, 99999999);
            $check = $conn->query("SELECT 1 FROM users WHERE user_id = $new_user_id");
            $attempts++;
            if ($attempts > $max_attempts) {
                throw new Exception("Unable to generate unique user ID. Please try again.");
            }
        } while ($check && $check->num_rows > 0);

        // Find placement
        $placement = findGlobalLevelWisePlacement($conn, $root_id);
        
        if (!$placement['success']) {
            throw new Exception($placement['message']);
        }

        $placement_id = $placement['placement_id'];
        $position = $placement['position'];

        // Hash password
        $hashed_password = $password;

        // Insert new user with Aadhaar and package_id
        $insert = $conn->query("INSERT INTO users (
            user_id, name, email, mobile, aadharno, password, sponsor_id, placement_id, package_id,
            left_1_id, left_2_id, right_1_id, right_2_id, wallet, rank, joining_date, status, pin_used
        ) VALUES (
            $new_user_id, '$name', " . ($email ? "'$email'" : "NULL") . ", '$phone', '$aadhaar', '$hashed_password', $sponsor_id, $placement_id, $package_id,
            0, 0, 0, 0, 0, 'STARTER', NOW(), 1, '$pin'
        )");

        if (!$insert) {
            throw new Exception("Failed to insert user: " . $conn->error);
        }

        // Update parent's position
        $update_parent = $conn->query("UPDATE users SET $position = $new_user_id WHERE user_id = $placement_id");
        if (!$update_parent) {
            throw new Exception("Failed to update parent position");
        }

        // Update PIN status
        $update_pin = $conn->query("UPDATE pin SET status = '1', used_by = '$new_user_id', used_at = NOW() WHERE pin_value = '$pin'");
        if (!$update_pin) {
            throw new Exception("Failed to update PIN status");
        }

        // ========== CHECK IF SPONSOR NOW HAS 4 DIRECTS ==========
        $directCount = getDirectCount($conn, $sponsor_id);
        if ($directCount >= 4) {
            $conn->query("UPDATE users SET c1_achieved_at = NOW() WHERE user_id = $sponsor_id AND c1_achieved_at IS NULL");
        }

        // ========== REFERRAL BONUS FOR SPONSOR ==========
        $referral_bonus = 500; // Adjust as needed
        if ($referral_bonus > 0) {
            // Get sponsor's current wallet
            $sponsor_before = (float)($sponsor_data['wallet'] ?? 0);
            $sponsor_after = $sponsor_before + $referral_bonus;
            
            // Update wallet
            $conn->query("UPDATE users SET wallet = wallet + $referral_bonus WHERE user_id = $sponsor_id");
            
            // Insert income history
            $txn_id = 'REF' . time() . rand(100, 999);
            $conn->query("INSERT INTO income_history (
                user_id, amount, description, credit_debit, admin_charges, tds,
                from_user_id, to_user_id, income_type, transaction_id,
                balance_before, balance_after, processed_at
            ) VALUES (
                '$sponsor_id', '$referral_bonus', 'Direct Referral Bonus',
                1, 0, 0,
                '$new_user_id', '$sponsor_id', 'Referral Bonus', '$txn_id',
                '$sponsor_before', '$sponsor_after', NOW()
            )");
        }

        $conn->commit();
        
        $success_message = "Member registered successfully! User ID: $new_user_id";
        header("Location: ../registration.php?success=" . urlencode($success_message));
        exit();

    } catch (Exception $e) {
        $conn->rollback();
        error_log("Registration Error: " . $e->getMessage());
        header("Location: ../registration.php?error=" . urlencode($e->getMessage()));
        exit();
    }
} else {
    header("Location: ../registration.php");
    exit();
}

// ==================== HELPER FUNCTIONS ====================

function getDirectCount($conn, $user_id) {
    $res = $conn->query("SELECT COUNT(*) as cnt FROM users WHERE sponsor_id = $user_id");
    return ($res) ? (int)$res->fetch_assoc()['cnt'] : 0;
}

function findGlobalLevelWisePlacement($conn, $root_id) {
    $positions = ['left_1_id', 'left_2_id', 'right_1_id', 'right_2_id'];
    
    // Check root's direct slots first
    $root_result = $conn->query("SELECT left_1_id, left_2_id, right_1_id, right_2_id FROM users WHERE user_id = $root_id");
    if (!$root_result) {
        return ['success' => false, 'message' => 'Error checking root'];
    }
    $root = $root_result->fetch_assoc();
    
    foreach ($positions as $pos) {
        if ($root[$pos] == 0) {
            return [
                'success' => true,
                'placement_id' => $root_id,
                'position' => $pos,
                'level' => 0
            ];
        }
    }
    
    // Get tree by level
    $treeByLevel = getGlobalTreeByLevel($conn, $root_id);
    $currentLevel = 1;
    
    while ($currentLevel <= 25) {
        
        if (!isset($treeByLevel[$currentLevel]) || empty($treeByLevel[$currentLevel])) {
            $prevLevel = $currentLevel - 1;
            
            if (isset($treeByLevel[$prevLevel])) {
                foreach ($treeByLevel[$prevLevel] as $nodeId) {
                    $node_result = $conn->query("SELECT left_1_id, left_2_id, right_1_id, right_2_id FROM users WHERE user_id = $nodeId");
                    if (!$node_result) continue;
                    $node = $node_result->fetch_assoc();
                    
                    foreach ($positions as $pos) {
                        if ($node[$pos] == 0) {
                            return [
                                'success' => true,
                                'placement_id' => $nodeId,
                                'position' => $pos,
                                'level' => $prevLevel
                            ];
                        }
                    }
                }
            }
            
            $currentLevel++;
            continue;
        }
        
        $levelNodes = $treeByLevel[$currentLevel];
        $nodeFillCounts = [];
        
        foreach ($levelNodes as $nodeId) {
            $node_result = $conn->query("SELECT left_1_id, left_2_id, right_1_id, right_2_id FROM users WHERE user_id = $nodeId");
            if (!$node_result) continue;
            $node = $node_result->fetch_assoc();
            
            $filledCount = 0;
            foreach ($positions as $pos) {
                if ($node[$pos] != 0) {
                    $filledCount++;
                }
            }
            
            if ($filledCount < 4) {
                $nodeFillCounts[$nodeId] = $filledCount;
            }
        }
        
        if (empty($nodeFillCounts)) {
            $currentLevel++;
            continue;
        }
        
        $minFill = min($nodeFillCounts);
        $candidateNodes = [];
        
        foreach ($nodeFillCounts as $nodeId => $fillCount) {
            if ($fillCount == $minFill) {
                $candidateNodes[] = $nodeId;
            }
        }
        
        foreach ($candidateNodes as $nodeId) {
            $node_result = $conn->query("SELECT left_1_id, left_2_id, right_1_id, right_2_id FROM users WHERE user_id = $nodeId");
            if (!$node_result) continue;
            $node = $node_result->fetch_assoc();
            
            foreach ($positions as $pos) {
                if ($node[$pos] == 0) {
                    return [
                        'success' => true,
                        'placement_id' => $nodeId,
                        'position' => $pos,
                        'level' => $currentLevel
                    ];
                }
            }
        }
        
        $currentLevel++;
    }
    
    return [
        'success' => false,
        'message' => 'Maximum tree depth reached. No positions available.'
    ];
}

function getGlobalTreeByLevel($conn, $root_id) {
    $treeByLevel = [];
    $queue = [[$root_id, 0]];
    $visited = [];
    $positions = ['left_1_id', 'left_2_id', 'right_1_id', 'right_2_id'];
    
    while (!empty($queue)) {
        list($current_id, $level) = array_shift($queue);
        
        if (in_array($current_id, $visited)) {
            continue;
        }
        $visited[] = $current_id;
        
        if (!isset($treeByLevel[$level])) {
            $treeByLevel[$level] = [];
        }
        $treeByLevel[$level][] = $current_id;
        
        $user_result = $conn->query("SELECT user_id, left_1_id, left_2_id, right_1_id, right_2_id FROM users WHERE user_id = $current_id");
        if (!$user_result) continue;
        $user = $user_result->fetch_assoc();
        
        if ($user) {
            foreach ($positions as $pos) {
                if (!empty($user[$pos]) && $user[$pos] != 0) {
                    $queue[] = [$user[$pos], $level + 1];
                }
            }
        }
    }
    
    return $treeByLevel;
}
?>