<?php
declare(strict_types=1);

require_once __DIR__ . '/../system/bootstrap.php';
require_once __DIR__ . '/../system/auth.php';
require_once __DIR__ . '/../system/response.php';

header('Content-Type: application/json');

/* =========================
   AUTH
   ========================= */
$actor = require_auth($pdo);

$actorRole = strtolower(trim((string)($actor['role_key'] ?? '')));

/* =========================
   METHOD
   ========================= */
if (!in_array($_SERVER['REQUEST_METHOD'], ['POST', 'PATCH'], true)) {
    error_bad_request('Invalid request method');
}

/* =========================
   INPUT
   ========================= */
$input = json_decode(file_get_contents('php://input'), true);
if (!is_array($input)) {
    error_bad_request('Invalid JSON');
}

$targetUserId = isset($input['user_id'])
    ? (int)$input['user_id']
    : (int)$actor['id'];

$email     = $input['email'] ?? null;
$password  = $input['password'] ?? null;
$firstName = $input['first_name'] ?? null;
$lastName  = $input['last_name'] ?? null;
$roleKey   = $input['role_key'] ?? null;
$status    = $input['status'] ?? null;

/* =========================
   LOAD TARGET USER
   ========================= */
$stmt = $pdo->prepare("
    SELECT id, company_id, role_key, status, email
    FROM users
    WHERE id = :id
      AND deleted_at IS NULL
    LIMIT 1
");
$stmt->execute(['id' => $targetUserId]);
$target = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$target) {
    error_not_found('User not found');
}

/* =========================
   SCOPE & SELF RULES
   ========================= */

// Non-privileged roles may only edit themselves
$privilegedRoles = ['super_admin', 'platform_admin', 'company_admin'];

if (!in_array($actorRole, $privilegedRoles, true) && $actor['id'] !== $targetUserId) {
    error_forbidden('Forbidden');
}

// Company admin isolation
if (
    $actorRole === 'company_admin' &&
    (int)$actor['company_id'] !== (int)$target['company_id']
) {
    error_forbidden('Forbidden');
}

// RSP isolation
if ($actorRole === 'rsp_admin') {
    $stmt = $pdo->prepare("
        SELECT 1 FROM companies
        WHERE id = :company_id AND rsp_id = :rsp_id
    ");
    $stmt->execute([
        'company_id' => $target['company_id'],
        'rsp_id'     => $actor['company_id']
    ]);

    if (!$stmt->fetch()) {
        error_forbidden('Forbidden');
    }
}

/* =========================
   VALIDATION
   ========================= */
$fields = [];
$params = [];
$sensitive = false;

/* Email */
if ($email !== null && $email !== $target['email']) {
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        error_bad_request('Invalid email');
    }

    $stmt = $pdo->prepare("
        SELECT id FROM users
        WHERE email = :email AND deleted_at IS NULL
        LIMIT 1
    ");
    $stmt->execute(['email' => strtolower($email)]);
    if ($stmt->fetch()) {
        error_bad_request('Email already in use');
    }

    $fields[] = 'email = :email';
    $fields[] = 'email_verified = 0';
    $params['email'] = strtolower($email);
    $sensitive = true;
}

/* Password */
if ($password !== null) {
    $fields[] = 'password_hash = :password_hash';
    $params['password_hash'] = password_hash($password, PASSWORD_DEFAULT);
    $sensitive = true;
}

/* Names */
if ($firstName !== null) {
    $fields[] = 'first_name = :first_name';
    $params['first_name'] = trim($firstName);
}

if ($lastName !== null) {
    $fields[] = 'last_name = :last_name';
    $params['last_name'] = trim($lastName);
}

/* =========================
   ROLE CHANGE (STRICT)
   ========================= */
if ($roleKey !== null) {

    if (!in_array($actorRole, ['super_admin', 'platform_admin'], true)) {
        error_forbidden('Role change forbidden');
    }

    $stmt = $pdo->prepare("
        SELECT id FROM roles WHERE role_key = :role_key
    ");
    $stmt->execute(['role_key' => $roleKey]);
    $roleId = (int)$stmt->fetchColumn();

    if ($roleId <= 0) {
        error_bad_request('Invalid role');
    }

    $fields[] = 'role = :role';
    $fields[] = 'role_key = :role_key';
    $fields[] = 'role_id = :role_id';

    $params['role']     = $roleKey;
    $params['role_key'] = $roleKey;
    $params['role_id']  = $roleId;

    $sensitive = true;
}

/* =========================
   STATUS CHANGE
   ========================= */
if ($status !== null) {

    if (!in_array($actorRole, ['super_admin', 'platform_admin'], true)) {
        error_forbidden('Status change forbidden');
    }

    if (!in_array($status, ['active', 'locked', 'disabled'], true)) {
        error_bad_request('Invalid status');
    }

    $fields[] = 'status = :status';
    $params['status'] = $status;
    $sensitive = true;
}

if (!$fields) {
    success('No changes applied');
}

/* =========================
   UPDATE
   ========================= */
$params['id'] = $targetUserId;

$pdo->beginTransaction();

try {
    $pdo->prepare(
        "UPDATE users SET " . implode(', ', $fields) . " WHERE id = :id"
    )->execute($params);

    if ($sensitive) {
        $pdo->prepare(
            "DELETE FROM auth_tokens WHERE user_id = :id"
        )->execute(['id' => $targetUserId]);
    }

    $pdo->commit();

} catch (Throwable $e) {
    $pdo->rollBack();
    error_server('Update failed');
}

/* =========================
   AUDIT
   ========================= */
auditLog(
    $actor['id'],
    $target['company_id'],
    'users',
    'user_updated',
    [
        'target_user_id' => $targetUserId,
        'fields' => array_keys($params)
    ]
);

/* =========================
   RESPONSE
   ========================= */
success('User updated', [
    'user_id' => $targetUserId
]);
