<?php
declare(strict_types=1);

/**
 * /public_html/test_erp/api/auth/update_user.php
 * Secure Partial/Full User Update — TEST Environment
 */

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');

function update_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;
}

function update_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',
                    ?,
                    'UPDATE',
                    ?,
                    NOW(),
                    ?,
                    ?
                )"
        );

        $stmt->execute([
            $recordId,
            $changedBy,
            $ipAddress,
            $note,
        ]);

    } catch (Throwable $exception) {
        // Audit fail হলেও update বন্ধ হবে না।
    }
}

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

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

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

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

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

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

if ($currentUserId <= 0) {
    update_user_response(
        401,
        false,
        'প্রথমে লগইন করুন'
    );
}

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

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

/*
|--------------------------------------------------------------------------
| CSRF Protection
|--------------------------------------------------------------------------
*/

erp_csrf_required(true);

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

/*
|--------------------------------------------------------------------------
| Input গ্রহণ
|--------------------------------------------------------------------------
*/

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

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

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

$userId = (int) ($input['id'] ?? 0);

if ($userId <= 0) {
    update_user_response(
        422,
        false,
        'User ID পাওয়া যায়নি'
    );
}

/*
|--------------------------------------------------------------------------
| বর্তমান User Data
|--------------------------------------------------------------------------
*/

try {
    $targetStmt = $pdo->prepare(
        "SELECT
            id,
            name,
            email,
            role,
            status
         FROM users
         WHERE id = ?
         LIMIT 1"
    );

    $targetStmt->execute([$userId]);

    $targetUser = $targetStmt->fetch(PDO::FETCH_ASSOC);

    if (!$targetUser) {
        update_user_response(
            404,
            false,
            'ইউজার পাওয়া যায়নি'
        );
    }

    /*
    |--------------------------------------------------------------------------
    | Partial Update Compatibility
    |--------------------------------------------------------------------------
    |
    | UI শুধু role/status পাঠালেও বর্তমান name/email রাখা হবে।
    |--------------------------------------------------------------------------
    */

    $name = array_key_exists('name', $input)
        ? trim((string) $input['name'])
        : (string) $targetUser['name'];

    $email = array_key_exists('email', $input)
        ? strtolower(trim((string) $input['email']))
        : strtolower((string) $targetUser['email']);

    $role = array_key_exists('role', $input)
        ? strtolower(trim((string) $input['role']))
        : strtolower((string) $targetUser['role']);

    $status = array_key_exists('status', $input)
        ? strtolower(trim((string) $input['status']))
        : strtolower((string) $targetUser['status']);

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

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

    if ($name === '') {
        update_user_response(
            422,
            false,
            'নাম খালি রাখা যাবে না'
        );
    }

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

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

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

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

    if (!in_array($role, ['admin', 'manager', 'staff'], true)) {
        update_user_response(
            422,
            false,
            'সঠিক Role নির্বাচন করুন'
        );
    }

    if (!in_array($status, ['active', 'inactive'], true)) {
        update_user_response(
            422,
            false,
            'সঠিক Status নির্বাচন করুন'
        );
    }

    $targetCurrentRole = strtolower(
        (string) ($targetUser['role'] ?? '')
    );

    /*
    |--------------------------------------------------------------------------
    | Permission Protection
    |--------------------------------------------------------------------------
    */

    if (
        $currentRole === 'manager'
        && $targetCurrentRole === 'admin'
    ) {
        update_user_response(
            403,
            false,
            'Manager account থেকে Admin পরিবর্তন করা যাবে না'
        );
    }

    if (
        $currentRole === 'manager'
        && $role === 'admin'
    ) {
        update_user_response(
            403,
            false,
            'Manager account থেকে Admin Role দেওয়া যাবে না'
        );
    }

    if (
        $userId === $currentUserId
        && $status !== 'active'
    ) {
        update_user_response(
            403,
            false,
            'নিজের account নিষ্ক্রিয় করা যাবে না'
        );
    }

    if (
        $userId === $currentUserId
        && $role !== $currentRole
    ) {
        update_user_response(
            403,
            false,
            'নিজের Role নিজে পরিবর্তন করা যাবে না'
        );
    }

    /*
    |--------------------------------------------------------------------------
    | Duplicate Email Check
    |--------------------------------------------------------------------------
    */

    $duplicateStmt = $pdo->prepare(
        "SELECT id
         FROM users
         WHERE LOWER(email) = LOWER(?)
           AND id <> ?
         LIMIT 1"
    );

    $duplicateStmt->execute([
        $email,
        $userId,
    ]);

    if ($duplicateStmt->fetchColumn()) {
        update_user_response(
            409,
            false,
            'এই ইমেইল অন্য ইউজার ব্যবহার করছে'
        );
    }

    /*
    |--------------------------------------------------------------------------
    | Database Update
    |--------------------------------------------------------------------------
    */

    if ($password !== '') {
        $passwordHash = password_hash(
            $password,
            PASSWORD_DEFAULT
        );

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

        $updateStmt = $pdo->prepare(
            "UPDATE users
             SET
                name = ?,
                email = ?,
                password = ?,
                role = ?,
                status = ?,
                password_changed_at = NOW(),
                failed_login_attempts = 0,
                locked_until = NULL
             WHERE id = ?"
        );

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

    } else {
        $updateStmt = $pdo->prepare(
            "UPDATE users
             SET
                name = ?,
                email = ?,
                role = ?,
                status = ?
             WHERE id = ?"
        );

        $updateStmt->execute([
            $name,
            $email,
            $role,
            $status,
            $userId,
        ]);
    }

    if ($userId === $currentUserId) {
        $_SESSION['user_name'] = $name;
    }

    update_user_audit(
        $pdo,
        $userId,
        $currentUserId,
        'User updated — role: '
        . $role
        . ', status: '
        . $status
        . ', password_changed: '
        . ($password !== '' ? 'yes' : 'no')
        . ' — TEST environment'
    );

    update_user_response(
        200,
        true,
        'ইউজার সফলভাবে আপডেট হয়েছে',
        [
            'id'     => $userId,
            'name'   => $name,
            'email'  => $email,
            'role'   => $role,
            'status' => $status,
        ]
    );

} catch (PDOException $exception) {
    if ((string) $exception->getCode() === '23000') {
        update_user_response(
            409,
            false,
            'এই ইমেইল অন্য ইউজার ব্যবহার করছে'
        );
    }

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

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