<?php
// ====== CRITICAL: No whitespace or output before this line ======

// Disable all error displaying
ini_set('display_errors', 0);
error_reporting(0);

// Enable error logging to a file instead of displaying them
ini_set('log_errors', 1);
ini_set('error_log', 'billr_errors.log');

// Set output buffering to catch any unexpected output
ob_start();

// Function to ensure clean JSON response even if errors occur
function sendJSONResponse($status, $message, $data = null, $httpCode = 200)
{
    // Clear any previous output
    if (ob_get_length())
        ob_clean();

    // Set headers
    header('Content-Type: application/json');
    header('Cache-Control: no-cache, no-store, must-revalidate');
    header('Pragma: no-cache');
    header('Expires: 0');
    http_response_code($httpCode);

    // Prepare response
    $response = array(
        'status' => $status,
        'message' => $message
    );

    if ($data !== null) {
        $response['data'] = $data;
    }

    // Send response
    echo json_encode($response);
    exit();
}

// Set CORS headers
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

// Handle OPTIONS method for CORS preflight
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

// Only allow POST requests
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    sendJSONResponse(false, 'Method Not Allowed. Only POST requests are accepted.', null, 405);
}

// Get and validate raw input data
try {
    $input = file_get_contents("php://input");

    if (empty($input)) {
        sendJSONResponse(false, 'No input data provided.', null, 400);
    }

    $data = json_decode($input, true);

    if ($data === null && json_last_error() !== JSON_ERROR_NONE) {
        sendJSONResponse(false, 'Invalid JSON: ' . json_last_error_msg(), null, 400);
    }

    // Check required fields
    if (!isset($data['mobile']) || !isset($data['password'])) {
        sendJSONResponse(false, 'Missing required fields: mobile and password.', null, 400);
    }

    $mobile = trim($data['mobile']);
    $password = trim($data['password']);

    if (empty($mobile) || empty($password)) {
        sendJSONResponse(false, 'Username and password cannot be empty.', null, 400);
    }
} catch (Exception $e) {
    error_log("Input processing error: " . $e->getMessage());
    sendJSONResponse(false, 'Error processing request.', null, 400);
}

// Database connection
try {
    $db_host = "localhost";
    $db_username = "driftdevelopers_Sudh";
    $db_password = "Xboxlive@12";
    $db_name = "driftdevelopers_biller_datatable";

    $conn = new PDO("mysql:host=$db_host;dbname=$db_name", $db_username, $db_password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    error_log("Database connection error: " . $e->getMessage());
    sendJSONResponse(false, 'Database connection failed.', null, 500);
}

// Process login
try {
    // First check if the table exists
    $tableCheck = $conn->query("SHOW TABLES LIKE 'client_management'");
    if ($tableCheck->rowCount() === 0) {
        error_log("Table 'client_management' does not exist");
        sendJSONResponse(false, 'Database configuration error.', null, 500);
    }

    // Check column names to make sure they match
    $columnCheck = $conn->query("SHOW COLUMNS FROM client_management");
    $columns = $columnCheck->fetchAll(PDO::FETCH_COLUMN);

    // Log the available columns for debugging
    error_log("Available columns: " . implode(", ", $columns));

    // Use fallback query if columns don't match expected names
    $userField = in_array('client_username', $columns) ? 'client_username' : 'user_name';
    $passwordField = in_array('client_password', $columns) ? 'client_password' : 'user_pass';
    $idField = in_array('client_user_id', $columns) ? 'client_user_id' : 'id';
    $nameField = in_array('client_full_name', $columns) ? 'client_full_name' : 'full_name';
    $emailField = in_array('client_email', $columns) ? 'client_email' : 'email';
    $statusField = in_array('client_status', $columns) ? 'client_status' : 'status';
    $phoneField = in_array('client_phone', $columns) ? 'client_phone' : 'phone';

    // STEP 1: First check if the username exists by checking both username and phone fields
    error_log("Checking if username exists: " . $mobile);

    // Query to check if user exists - check by username OR phone
    $user_check_query = "SELECT $idField FROM client_management WHERE ";

    if (in_array($userField, $columns)) {
        $user_check_query .= "$userField = :mobile";
    }

    if (in_array($phoneField, $columns)) {
        if (in_array($userField, $columns)) {
            $user_check_query .= " OR ";
        }
        $user_check_query .= "$phoneField = :mobile";
    }

    // Add status check if available
    if (in_array($statusField, $columns)) {
        $user_check_query .= " AND ($statusField = 'active' OR $statusField IS NULL)";
    }

    error_log("User check query: " . $user_check_query);

    $user_check_stmt = $conn->prepare($user_check_query);
    $user_check_stmt->bindParam(':mobile', $mobile);
    $user_check_stmt->execute();

    // If user not found, return username not found error
    if ($user_check_stmt->rowCount() == 0) {
        error_log("User not found with mobile: " . $mobile);
        sendJSONResponse(false, 'Username not found', null, 401);
        exit;
    }

    // STEP 2: If username exists, check the password
    error_log("Username found, checking password");

    // Get full user details for password check
    $query = "SELECT $idField, $userField, $passwordField, $nameField";

    if (in_array($emailField, $columns)) {
        $query .= ", $emailField";
    }

    if (in_array($phoneField, $columns)) {
        $query .= ", $phoneField";
    }

    if (in_array($statusField, $columns)) {
        $query .= ", $statusField";
    }

    $query .= " FROM client_management WHERE ";

    if (in_array($userField, $columns)) {
        $query .= "$userField = :mobile";
    }

    if (in_array($phoneField, $columns)) {
        if (in_array($userField, $columns)) {
            $query .= " OR ";
        }
        $query .= "$phoneField = :mobile";
    }

    // Add status check if available
    if (in_array($statusField, $columns)) {
        $query .= " AND ($statusField = 'active' OR $statusField IS NULL)";
    }

    error_log("Full user query: " . $query);

    $stmt = $conn->prepare($query);
    $stmt->bindParam(':mobile', $mobile);
    $stmt->execute();

    $user = $stmt->fetch(PDO::FETCH_ASSOC);

    // Log the retrieved user data (excluding password)
    $user_log = $user;
    unset($user_log[$passwordField]); // Don't log the password hash
    error_log("User data retrieved: " . json_encode($user_log));

    // Get stored password hash and log it with some obfuscation
    $stored_hash = $user[$passwordField];
    $obfuscated_hash = substr($stored_hash, 0, 10) . "..." . substr($stored_hash, -5);
    error_log("Stored password hash (partial): " . $obfuscated_hash);

    // Check password - first try using password_verify for hashed passwords
    if (password_verify($password, $stored_hash)) {
        error_log("Password verification succeeded with password_verify()");

        // Generate token and return success
        $token = bin2hex(random_bytes(16));
        $issued_at = time();
        $expiration = $issued_at + (24 * 60 * 60); // 24 hours

        $userData = array(
            'user_id' => $user[$idField],
            'username' => $user[$userField],
            'full_name' => $user[$nameField] ?? 'Unknown',
            'email' => $user[$emailField] ?? '',
            'phone' => $user[$phoneField] ?? $mobile,
            'token' => $token,
            'expires' => $expiration
        );

        if (isset($user[$statusField])) {
            $userData['status'] = $user[$statusField];
        }

        sendJSONResponse(true, 'Login successful', $userData, 200);
    }
    // Then try direct comparison for plaintext passwords
    else if ($password === $stored_hash) {
        error_log("Password verification succeeded with direct comparison (plain text)");

        // Generate token and return success
        $token = bin2hex(random_bytes(16));
        $issued_at = time();
        $expiration = $issued_at + (24 * 60 * 60); // 24 hours

        $userData = array(
            'user_id' => $user[$idField],
            'username' => $user[$userField],
            'full_name' => $user[$nameField] ?? 'Unknown',
            'email' => $user[$emailField] ?? '',
            'phone' => $user[$phoneField] ?? $mobile,
            'token' => $token,
            'expires' => $expiration
        );

        if (isset($user[$statusField])) {
            $userData['status'] = $user[$statusField];
        }

        sendJSONResponse(true, 'Login successful', $userData, 200);
    }
    // If everything fails, return password incorrect error
    else {
        error_log("Password verification failed for user: " . $mobile);
        error_log("Input password: " . $password);

        // Try the specific hash you provided
        $known_hash = '$2y$10$lQHvmyH9xTyV8SJur3oGp.3W9chiyYnVl7f1h2VvxJ6eRLwDBZ0Na';
        $verify_result = password_verify($password, $known_hash);
        error_log("Testing with known hash result: " . ($verify_result ? "SUCCESS" : "FAILURE"));

        // Return password incorrect message
        sendJSONResponse(false, 'Password not matched', null, 401);
    }
} catch (PDOException $e) {
    error_log("Login query error: " . $e->getMessage());
    sendJSONResponse(false, 'Error processing login request.', null, 500);
} catch (Exception $e) {
    error_log("General error: " . $e->getMessage());
    sendJSONResponse(false, 'An unexpected error occurred.', null, 500);
}

// Close connection
$conn = null;

// Clean any remaining output to avoid corruption
if (ob_get_length())
    ob_end_clean();
?>