<?php
declare(strict_types=1);

/**
 * /public_html/test_erp/api/auth/create_user.php
 * Secure User Creation Endpoint — TEST Environment
 * Updated: 2026-07-22
 */

require_once __DIR__ . '/../../config/session.php';
require_once __DIR__ . '/../../config/db.php';
require_once __DIR__ . '/../_csrf_guard.php';

header('Content-Type: application/json; charset=UTF-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');

/**
 * Consistent JSON response.
 */
function create_user_response(
    int $httpCode,
    bool $success,
    string $message,
    ?array $data = null
): void {
    http_response_code($httpCode);

    echo json_encode([
        'status'  => $success,
        'success' => $success,
        'ok'      => $success,
        'code'    => $httpCode,
        'message' => $message,
        'data'    => $data,
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

    exit;
}

/**
 * Audit error হলেও User creation বন্ধ হবে না।
 */
function create_user_audit(
    PDO $pdo,
    int $recordId,
    int $changedBy,
    string $note
): void {
    try {
        $ipAddress = (string) ($_SERVER['REMOTE_ADDR'] ?? '');

        $stmt = $pdo->prepare(
            "INSERT INTO audit_log
                (
                    table_name,
                    record_id,
                    action,
                    changed_by,
                    changed_at,
                    ip_address,
                    note
                )
             VALUES
                (
                    'users',
                    ?,
                    'INSERT',
                    ?,
                    NOW(),
                    ?,
                    ?
                )"
        );

        $stmt->execute([
            $recordId,
            $changedBy,
            $ipAddress,
            $note,
        ]);
    } catch (Throwable $exception) {
        // Audit failure User creation আটকাবে না।
    }
}

/*
|--------------------------------------------------------------------------
| Request Method
|--------------------------------------------------------------------------
*/

$requestMethod = strtoupper(
    (string) ($_SERVER['REQUEST_METHOD'] ?? '')
);

if ($requestMethod === 'OPTIONS') {
    http_response_code(204);
    exit;
}

if ($requestMethod !== 'POST') {
    create_user_response(
        405,
        false,
        'শুধু POST অনুরোধ গ্রহণযোগ্য'
    );
}

/*
|--------------------------------------------------------------------------
| Login এবং Permission Verification
|--------------------------------------------------------------------------
*/

if (
    !isset($_SESSION['user_id'])
    || (int) $_SESSION['user_id'] <= 0
) {
    create_user_response(
        401,
        false,
        'প্রথমে লগইন করুন'
    );
}

$currentUserId = (int) $_SESSION['user_id'];

$currentRole = strtolower(
    trim(
        (string) (
            $_SESSION['user_role']
            ?? $_SESSION['role']
            ?? ''
        )
    )
);

if (!in_array($currentRole, ['admin', 'manager'], true)) {
    create_user_response(
        403,
        false,
        'নতুন ইউজার তৈরির অনুমতি নেই'
    );
}

/*
|--------------------------------------------------------------------------
| CSRF Verification
|--------------------------------------------------------------------------
|
| Compatibility mode রাখা হয়েছে, যাতে পুরোনো same-origin page না ভাঙে।
| পাঠানো ভুল token অবশ্যই reject হবে।
|--------------------------------------------------------------------------
*/

erp_csrf_required(true);

/*
|--------------------------------------------------------------------------
| Database Connection Verification
|--------------------------------------------------------------------------
*/

if (!isset($pdo) || !($pdo instanceof PDO)) {
    create_user_response(
        500,
        false,
        'ডাটাবেস সংযোগ পাওয়া যায়নি'
    );
}

/*
|--------------------------------------------------------------------------
| Input গ্রহণ — JSON এবং Form দুইটাই সমর্থিত
|--------------------------------------------------------------------------
*/

$rawInput = file_get_contents('php://input');
$jsonInput = json_decode((string) $rawInput, true);

if (!is_array($jsonInput)) {
    $jsonInput = [];
}

$input = array_merge($_POST, $jsonInput);

$name = trim(
    (string) ($input['name'] ?? '')
);

$email = strtolower(
    trim((string) ($input['email'] ?? ''))
);

$password = (string) ($input['password'] ?? '');

$role = strtolower(
    trim((string) ($input['role'] ?? 'staff'))
);

$status = strtolower(
    trim((string) ($input['status'] ?? 'active'))
);

/*
|--------------------------------------------------------------------------
| Validation
|--------------------------------------------------------------------------
*/

if ($name === '') {
    create_user_response(
        422,
        false,
        'নাম লিখুন'
    );
}

if (strlen($name) > 120) {
    create_user_response(
        422,
        false,
        'নাম সর্বোচ্চ ১২০ অক্ষরের হতে পারবে'
    );
}

if (
    $email === ''
    || strlen($email) > 190
    || !filter_var($email, FILTER_VALIDATE_EMAIL)
) {
    create_user_response(
        422,
        false,
        'সঠিক ইমেইল লিখুন'
    );
}

if (strlen($password) < 6) {
    create_user_response(
        422,
        false,
        'পাসওয়ার্ড কমপক্ষে ৬ অক্ষরের হতে হবে'
    );
}

if (strlen($password) > 255) {
    create_user_response(
        422,
        false,
        'পাসওয়ার্ড খুব বড় হয়েছে'
    );
}

$allowedRoles = [
    'admin',
    'manager',
    'staff',
];

if (!in_array($role, $allowedRoles, true)) {
    create_user_response(
        422,
        false,
        'সঠিক Role নির্বাচন করুন'
    );
}

$allowedStatuses = [
    'active',
    'inactive',
];

if (!in_array($status, $allowedStatuses, true)) {
    create_user_response(
        422,
        false,
        'সঠিক Status নির্বাচন করুন'
    );
}

/*
|--------------------------------------------------------------------------
| Privilege Escalation Protection
|--------------------------------------------------------------------------
|
| Manager নতুন Admin তৈরি করতে পারবে না।
|--------------------------------------------------------------------------
*/

if (
    $currentRole === 'manager'
    && $role === 'admin'
) {
    create_user_response(
        403,
        false,
        'Manager অ্যাকাউন্ট থেকে Admin তৈরি করা যাবে না'
    );
}

/*
|--------------------------------------------------------------------------
| User তৈরি
|--------------------------------------------------------------------------
*/

try {
    $checkStmt = $pdo->prepare(
        'SELECT id
         FROM users
         WHERE LOWER(email) = LOWER(?)
         LIMIT 1'
    );

    $checkStmt->execute([$email]);

    if ($checkStmt->fetchColumn()) {
        create_user_response(
            409,
            false,
            'এই ইমেইল আগে থেকেই ব্যবহার করা হয়েছে'
        );
    }

    $passwordHash = password_hash(
        $password,
        PASSWORD_DEFAULT
    );

    if ($passwordHash === false) {
        create_user_response(
            500,
            false,
            'পাসওয়ার্ড নিরাপদভাবে সংরক্ষণ করা যায়নি'
        );
    }

    $insertStmt = $pdo->prepare(
        "INSERT INTO users
            (
                name,
                email,
                password,
                role,
                status,
                password_changed_at
            )
         VALUES
            (
                ?,
                ?,
                ?,
                ?,
                ?,
                NOW()
            )"
    );

    $insertStmt->execute([
        $name,
        $email,
        $passwordHash,
        $role,
        $status,
    ]);

    $newUserId = (int) $pdo->lastInsertId();

    create_user_audit(
        $pdo,
        $newUserId,
        $currentUserId,
        'User created — role: '
        . $role
        . ', status: '
        . $status
        . ' — TEST environment'
    );

    create_user_response(
        201,
        true,
        'ইউজার সফলভাবে তৈরি হয়েছে',
        [
            'id'     => $newUserId,
            'name'   => $name,
            'email'  => $email,
            'role'   => $role,
            'status' => $status,
        ]
    );

} catch (PDOException $exception) {
    if ((string) $exception->getCode() === '23000') {
        create_user_response(
            409,
            false,
            'এই ইমেইল আগে থেকেই ব্যবহার করা হয়েছে'
        );
    }

    create_user_response(
        500,
        false,
        'সার্ভার সমস্যা হয়েছে, আবার চেষ্টা করুন'
    );

} catch (Throwable $exception) {
    create_user_response(
        500,
        false,
        'সার্ভার সমস্যা হয়েছে, আবার চেষ্টা করুন'
    );
}