<?php
require_auth();
$method = $_SERVER['REQUEST_METHOD'];
$d = input();
$id = (int)($d['id'] ?? 0);
$current = current_user();

function role_exists(int $roleId): bool {
    $s = db()->prepare('SELECT 1 FROM roles WHERE id=?');
    $s->execute([$roleId]);
    return (bool)$s->fetchColumn();
}
function assert_role_assignment_allowed(int $roleId): void {
    $me = current_user();
    if ($roleId === 1 && (($me['role_name'] ?? '') !== 'super_admin')) {
        json_error('Only a Super Admin can assign the Super Admin role', 403);
    }
    if (!role_exists($roleId)) json_error('Invalid role', 422);
}
function assert_not_last_super_admin(int $userId, array $changes = []): void {
    $s = db()->prepare('SELECT role_id, status FROM users WHERE id=? AND deleted_at IS NULL');
    $s->execute([$userId]);
    $target = $s->fetch();
    if (!$target || (int)$target['role_id'] !== 1) return;

    $willLoseSuper = isset($changes['role_id']) && (int)$changes['role_id'] !== 1;
    $willDeactivate = isset($changes['status']) && $changes['status'] !== 'active';
    $willDelete = !empty($changes['delete']);
    if (!$willLoseSuper && !$willDeactivate && !$willDelete) return;

    $count = (int)db()->query("SELECT COUNT(*) FROM users WHERE role_id=1 AND status='active' AND deleted_at IS NULL")->fetchColumn();
    if ($count <= 1) json_error('Cannot remove or deactivate the last active Super Admin', 409);
}

if ($method === 'GET') {
    require_permission('users.view');
    if ($id) {
        $s = db()->prepare('SELECT u.id,u.name,u.email,u.phone,u.status,u.role_id,r.label AS role_label,u.last_login,u.created_at FROM users u LEFT JOIN roles r ON r.id=u.role_id WHERE u.id=? AND u.deleted_at IS NULL');
        $s->execute([$id]);
        $row = $s->fetch();
        if (!$row) json_error('Not found', 404);
        json_ok($row);
    }
    $q = '%' . v_str($d, 'q', 80) . '%';
    $stmt = db()->prepare('SELECT u.id,u.name,u.email,u.phone,u.status,u.role_id,r.label AS role_label,u.last_login,u.created_at FROM users u LEFT JOIN roles r ON r.id=u.role_id WHERE u.deleted_at IS NULL AND (u.name LIKE ? OR u.email LIKE ?) ORDER BY u.created_at DESC LIMIT 200');
    $stmt->execute([$q, $q]);
    json_ok($stmt->fetchAll());
}

csrf_check();

if ($method === 'POST') {
    require_permission('users.manage');
    $errors = v_required($d, ['name','email']);
    if ($errors) json_error('Validation failed', 422, $errors);
    $email = strtolower(trim((string)$d['email']));
    if (!v_email($email)) json_error('Invalid email', 422);
    $roleId = (int)($d['role_id'] ?? 4);
    assert_role_assignment_allowed($roleId);
    $exists = db()->prepare('SELECT id FROM users WHERE email=? AND deleted_at IS NULL');
    $exists->execute([$email]);
    if ($exists->fetch()) json_error('Email already registered', 409);
    $pass = (string)($d['password'] ?? bin2hex(random_bytes(6)));
    if (strlen($pass) < 8) json_error('Password must be at least 8 characters', 422);
    $hash = password_hash($pass, PASSWORD_BCRYPT);
    $status = v_enum($d['status'] ?? 'active', ['active','suspended','pending'], 'status', 'active');
    $stmt = db()->prepare('INSERT INTO users (name,email,phone,password,role_id,status) VALUES (?,?,?,?,?,?)');
    $stmt->execute([
        v_str($d,'name',150),
        $email,
        v_str($d,'phone',40) ?: null,
        $hash,
        $roleId,
        $status,
    ]);
    $newId = db()->lastInsertId();
    audit('user.create','user',$newId);
    json_ok(['id'=>$newId,'temp_password'=>$pass], 'User created');
}

if ($method === 'PUT' || ($method === 'POST' && !empty($d['_method']) && $d['_method']==='PUT')) {
    require_permission('users.manage');
    if (!$id) json_error('id required',422);
    $fields=[]; $vals=[]; $changes=[];
    foreach (['name','phone','status','role_id'] as $f) {
        if (array_key_exists($f,$d)) {
            if ($f === 'status') $d[$f] = v_enum($d[$f], ['active','suspended','pending'], 'status');
            if ($f === 'role_id') { $d[$f] = (int)$d[$f]; assert_role_assignment_allowed((int)$d[$f]); }
            $fields[]="$f=?"; $vals[]=$d[$f]; $changes[$f]=$d[$f];
        }
    }
    if (!empty($d['password'])) {
        if (strlen((string)$d['password']) < 8) json_error('Password must be at least 8 characters', 422);
        $fields[]='password=?'; $vals[]=password_hash($d['password'],PASSWORD_BCRYPT);
    }
    if (!$fields) json_error('Nothing to update',422);
    assert_not_last_super_admin($id, $changes);
    $vals[]=$id;
    db()->prepare('UPDATE users SET '.implode(',',$fields).' WHERE id=?')->execute($vals);
    audit('user.update','user',$id);
    json_ok([], 'Updated');
}

if ($method === 'DELETE' || (!empty($d['_method']) && $d['_method']==='DELETE')) {
    require_permission('users.manage');
    if (!$id) json_error('id required',422);
    if ($current && (int)$current['id'] === $id) json_error('You cannot remove your own account', 409);
    assert_not_last_super_admin($id, ['delete'=>true]);
    db()->prepare('UPDATE users SET deleted_at=NOW(), status="suspended" WHERE id=?')->execute([$id]);
    audit('user.delete','user',$id);
    json_ok([], 'User removed');
}

json_error('Method not allowed', 405);
