<?php

if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME'])) {
    die('No direct script access allowed');
}


function getUser(int $platform_id, string $platform): ?array {
    $column = ($platform === 'bale') ? 'bale_user_id' : 'telegram_user_id';
    try {
        $stmt = pdo()->prepare("SELECT * FROM users WHERE {$column} = ?");
        $stmt->execute([$platform_id]);
        return $stmt->fetch() ?: null;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting user by platform ID: " . $e->getMessage() . "\n", FILE_APPEND);
        return null;
    }
}


function getUserById(int $user_id): ?array {
    try {
         $stmt = pdo()->prepare("SELECT * FROM users WHERE id = ?");
        $stmt->execute([$user_id]);
        return $stmt->fetch() ?: null;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting user by ID {$user_id}: " . $e->getMessage() . "\n", FILE_APPEND);
        return null;
    }
}


function getUserByPhoneNumber(string $phone_number): ?array {
    $normalizedPhone = normalizePhoneNumber($phone_number); 
    try {
        $stmt = pdo()->prepare("SELECT * FROM users WHERE phone_number = ?");
        $stmt->execute([$normalizedPhone]);
        return $stmt->fetch() ?: null;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting user by phone: " . $e->getMessage() . "\n", FILE_APPEND);
        return null;
    }
}

function getUserByNationalId(string $national_code): ?array {
    $cleaned_nid = preg_replace('/\D/', '', $national_code);
    try {
        $stmt = pdo()->prepare("SELECT * FROM users WHERE national_id_code = ?");
        $stmt->execute([$cleaned_nid]);
        return $stmt->fetch() ?: null;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting user by NID: " . $e->getMessage() . "\n", FILE_APPEND);
        return null;
    }
}


function getUserByReferralCode(string $referral_code): ?array {
    try {
        $stmt = pdo()->prepare("SELECT * FROM users WHERE referral_code = ?");
        $stmt->execute([$referral_code]);
        return $stmt->fetch() ?: null;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting user by referral code: " . $e->getMessage() . "\n", FILE_APPEND);
        return null;
    }
}


function createUser(int $platform_id, int $chat_id, string $first_name, string $platform, ?int $referred_by_user_id = null): int {
    $user_id_column = ($platform === 'bale') ? 'bale_user_id' : 'telegram_user_id';
    $chat_id_column = ($platform === 'bale') ? 'bale_chat_id' : 'telegram_chat_id';
  
    try {
        $sql = "INSERT INTO users ({$user_id_column}, {$chat_id_column}, first_name, status, referred_by_user_id, session_last_activity) VALUES (?, ?, ?, 'awaiting_phone', ?, NOW())";
        $stmt = pdo()->prepare($sql);
   
        
        $stmt->execute([$platform_id, $chat_id, $first_name, $referred_by_user_id]);
        return (int)pdo()->lastInsertId();
    } catch (PDOException $e) {
       
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error creating user: " . $e->getMessage() . "\n", FILE_APPEND);
      
        
        $existingUser = getUser($platform_id, $platform);
        return $existingUser['id'] ?? 0;
    }
}


function updateUserField(int $user_id, string $field, $value): bool {
    $allowed_fields = [
       'phone_number', 'otp_code', 'otp_timestamp', 'status', 'session', 'national_id_code', 
       'birth_date', 'national_id_data', 'selfie_data',
        'admin_rejection_reason',
        'final_verification_code', 'is_active', 'first_name', 'telegram_user_id',
        'bale_user_id', 'telegram_chat_id', 'bale_chat_id', 'session_last_activity',
          'is_admin', 'referral_code', 'referred_by_user_id'
    ];
    if (!in_array($field, $allowed_fields)) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - Security Warning: Invalid field '{$field}' in updateUserField for user {$user_id}.\n", FILE_APPEND);
        return false;
    }
    
   
    
    
    $sql = ($field === 'session' || $field === 'otp_timestamp' || $field === 'otp_code')
        ? "UPDATE users SET `{$field}` = ?, session_last_activity = NOW() WHERE id = ?"
        : "UPDATE users SET `{$field}` = ?, session_last_activity = NOW() WHERE id = ?"; 
    
    try {
         $stmt = pdo()->prepare($sql);
        
        if ($field === 'national_id_data' || $field === 'selfie_data') {
            $stmt->bindParam(1, $value, PDO::PARAM_LOB);
            $stmt->bindParam(2, $user_id, PDO::PARAM_INT);
            return $stmt->execute();
        } else {
            return $stmt->execute([$value, $user_id]);
        }
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - Error in updateUserField ({$field}) for user {$user_id}: " . $e->getMessage() . "\n", FILE_APPEND);
        return false;
    }
}


function updateUserStatus(int $user_id, string $status): bool {
    
    return updateUserField($user_id, 'status', $status);
}


function toggleUserActiveStatus(int $user_id, bool $is_active): bool {
    return updateUserField($user_id, 'is_active', $is_active ? 1 : 0);
}


function resetUser(int $user_id): bool {
    try {
        $sql = "UPDATE users SET 
                    status = 'awaiting_phone', 
                    phone_number = NULL, 
                    otp_code = NULL, 
                    otp_timestamp = NULL,
                    national_id_code = NULL, 
 
                    birth_date = NULL, 
                    national_id_data = NULL, 
                    selfie_data = NULL, 
                    session = NULL, 
                
            
            session_last_activity = NOW() 
          WHERE id = ?";
        $stmt = pdo()->prepare($sql);
        return $stmt->execute([$user_id]);
    } catch (PDOException $e) {
  
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error resetting user {$user_id}: " . $e->getMessage() . "\n", FILE_APPEND);
         return false;
    }
}


function isAdminPhoneNumber(string $phone_number): bool {
    try {
        $stmt = pdo()->prepare("SELECT COUNT(*) FROM admins WHERE phone_number = ?");
        $stmt->execute([normalizePhoneNumber($phone_number)]);
        return (int)$stmt->fetchColumn() > 0;
    } catch (PDOException $e) {

      file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error checking admin phone: " . $e->getMessage() . "\n", FILE_APPEND);
        return false;
    }
}


function getAllUsers(int $limit, int $offset, ?bool $is_admin_level = null): array {
     try {
         $sql = "SELECT id, telegram_user_id, bale_user_id, first_name, phone_number, status, is_active FROM users";
         
         $params = [];
         
         if ($is_admin_level !== null) {
             $sql .= " WHERE is_admin = :is_admin";
              $params[':is_admin'] = (int)$is_admin_level;
         }
         
         $sql .= " ORDER BY id DESC LIMIT :limit OFFSET :offset";
         $params[':limit'] = $limit;
         $params[':offset'] = $offset;

         $stmt = pdo()->prepare($sql);
         
         $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
         $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
         if ($is_admin_level !== null) {
             $stmt->bindValue(':is_admin', (int)$is_admin_level, PDO::PARAM_INT);
         }

          $stmt->execute();
         return $stmt->fetchAll();
     } catch (PDOException $e) {
         file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting all users: " . $e->getMessage() . "\n", FILE_APPEND);
         return [];
     }
}


function countAllUsers(?bool $is_admin_level = null): int {
    try {
        $sql = "SELECT COUNT(*) FROM users";
        $params = [];
        
        if ($is_admin_level !== null) {
            $sql .= " WHERE is_admin = :is_admin";
            $params[':is_admin'] = (int)$is_admin_level;
        }

        $stmt = pdo()->prepare($sql);
        $stmt->execute($params);
        return (int)$stmt->fetchColumn();
    } catch (PDOException $e) {
       file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error counting users: " . $e->getMessage() . "\n", FILE_APPEND);
         return 0;
    }
}


function searchUsers(string $term): array {

    try {
        $stmt = pdo()->prepare("SELECT id, first_name, phone_number, telegram_user_id, bale_user_id, is_active FROM users WHERE first_name LIKE ? OR phone_number LIKE ? OR telegram_user_id LIKE ? OR bale_user_id LIKE ? LIMIT 20");
        $searchTerm = "%{$term}%";
        $stmt->execute([$searchTerm, $searchTerm, $searchTerm, $searchTerm]);
          return $stmt->fetchAll();
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error searching users: " . $e->getMessage() . "\n", FILE_APPEND);
        return [];
    }
}


function getUserDetailsForAdmin(int $user_id): ?array {
    try {
        $user = getUserById($user_id);
        if (!$user) return null;

            
        
        $user['cart'] = getCartContents($user_id); 
        $user['orders'] = getOrdersByUserPaginated($user_id, 5, 0); 
        $user['cards'] = getUserCards($user_id); 

        return $user;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting user details for admin {$user_id}: " . $e->getMessage() . "\n", FILE_APPEND);
        return null;
    }
}


function getFirstAdminChatId(): ?array {
    try {
        $stmt = pdo()->query("SELECT telegram_chat_id, bale_chat_id FROM users WHERE is_admin = TRUE AND is_active = TRUE ORDER BY id ASC LIMIT 1");
        $admin = $stmt->fetch();


        if ($admin) {
             if (!empty($admin['telegram_chat_id'])) {
       
               
                  return ['chat_id' => $admin['telegram_chat_id'], 'platform' => 'telegram'];
            } elseif (!empty($admin['bale_chat_id'])) {
                 return ['chat_id' => $admin['bale_chat_id'], 'platform' => 'bale'];
            }
        }
 
        
return null; 
    } catch (PDOException $e) {
     
       if (defined('ERROR_LOG_PATH')) { file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting first admin chat ID: " . $e->getMessage() . "\n", FILE_APPEND); }
         return null;
 
   }
}

function getAllAdminsWithChatIds(): array {
    try {
        $stmt = pdo()->query("SELECT id, telegram_chat_id, bale_chat_id FROM users WHERE is_admin = TRUE AND is_active = TRUE AND (telegram_chat_id IS NOT NULL OR bale_chat_id IS NOT NULL)");
         return $stmt->fetchAll();
 
    } catch (PDOException $e) {
     
       if (defined('ERROR_LOG_PATH')) { file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error fetching all admins for notification: " . $e->getMessage() . "\n", FILE_APPEND); }
        return [];
    }
}


function generateAndSetReferralCode(int $user_id): ?string {
    $user = getUserById($user_id);
    if (!$user) {
        return null;
    }

    if (!empty($user['referral_code'])) {
        return $user['referral_code'];
    }

    $base_code = 'REF' . $user_id;
    $referral_code = $base_code;
    $counter = 1;

    while (getUserByReferralCode($referral_code) !== null) {
        $referral_code = $base_code . '_' . $counter;
        $counter++;
        if ($counter > 10) {
             file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - CRITICAL Error generating referral code for user {$user_id}: Too many collisions.\n", FILE_APPEND);
             return null;
        }
    }

    if (updateUserField($user_id, 'referral_code', $referral_code)) {
        return $referral_code;
    }

    return null;
}

function getUserVerificationFileData(int $user_id, string $file_type): ?string {
    $column = ($file_type === 'nid') ? 'national_id_data' : 'selfie_data';
    if (!in_array($column, ['national_id_data', 'selfie_data'])) {
        return null;
  }
  
  try {
        $stmt = pdo()->prepare("SELECT {$column} FROM users WHERE id = ?");
        $stmt->bindParam(1, $user_id, PDO::PARAM_INT);
        $stmt->execute();
        $encrypted_data = $stmt->fetchColumn();
        
     
      if ($encrypted_data) {
         return decryptFileData($encrypted_data);
        }
        return null;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting user file data ({$file_type}) for user {$user_id}: " . $e->getMessage() . "\n", FILE_APPEND);
        return null;
    }
}


?>