<?php
// app/controllers/admin.php

declare(strict_types=1);

use ScMedia\Http\Response;
use ScMedia\Http\Router;
use ScMedia\Services\AuthService;

final class AdminController extends BaseController {
  public static function register(Router $router, Container $container): void {
    $self = new self($container);
    $router->add('GET', '/api/admin/users', fn() => $self->listUsers());
    $router->add('POST', '/api/admin/users/{id}/roles', fn($params) => $self->setRoles($params));
    $router->add('POST', '/api/admin/users/{id}/disable', fn($params) => $self->disableUser($params));
    $router->add('POST', '/api/admin/users/{id}/reset-2fa', fn($params) => $self->resetMfa($params));
    $router->add('GET', '/api/admin/roles', fn() => $self->listRoles());
    $router->add('POST', '/api/admin/audit', fn() => $self->audit());
  }

  private function listUsers(): void {
    /** @var AuthService $auth */
    $auth = $this->auth();
    $auth->requireAuth('admin');
    $items = $auth->listUsers();
    Response::json(['ok' => true, 'data' => ['items' => $items]]);
  }

  private function setRoles(array $params): void {
    /** @var AuthService $auth */
    $auth = $this->auth();
    $actor = $auth->requireAuth('admin');
    $userId = (int)($params['id'] ?? 0);
    $body = read_json_body();
    $roles = is_array($body['roles'] ?? null) ? $body['roles'] : [];
    $res = $auth->setUserRoles((int)($actor['id'] ?? 0), $userId, $roles);
    if (empty($res['ok'])) {
      Response::json(['ok' => false, 'error' => ['code' => 'ROLES_FAILED', 'message' => $res['error'] ?? 'failed']], 400);
      return;
    }
    Response::json(['ok' => true]);
  }

  private function disableUser(array $params): void {
    /** @var AuthService $auth */
    $auth = $this->auth();
    $actor = $auth->requireAuth('admin');
    $userId = (int)($params['id'] ?? 0);
    $body = read_json_body();
    $disabled = (bool)($body['disabled'] ?? true);
    $res = $auth->disableUser((int)($actor['id'] ?? 0), $userId, $disabled);
    if (empty($res['ok'])) {
      Response::json(['ok' => false, 'error' => ['code' => 'USER_DISABLE_FAILED', 'message' => $res['error'] ?? 'failed']], 400);
      return;
    }
    Response::json(['ok' => true]);
  }

  private function resetMfa(array $params): void {
    /** @var AuthService $auth */
    $auth = $this->auth();
    $actor = $auth->requireAuth('admin');
    $userId = (int)($params['id'] ?? 0);
    $res = $auth->resetUserMfa((int)($actor['id'] ?? 0), $userId);
    if (empty($res['ok'])) {
      Response::json(['ok' => false, 'error' => ['code' => 'MFA_RESET_FAILED', 'message' => $res['error'] ?? 'failed']], 400);
      return;
    }
    Response::json(['ok' => true]);
  }

  private function listRoles(): void {
    /** @var AuthService $auth */
    $auth = $this->auth();
    $auth->requireAuth('admin');
    $items = $auth->listRoles();
    Response::json(['ok' => true, 'data' => ['items' => $items]]);
  }

  private function audit(): void {
    /** @var AuthService $auth */
    $auth = $this->auth();
    $auth->requireAuth('admin');
    [$page, $perPage, $sort, $dir, $filters, $params] = table_body_params(50, 200);
    $from = '';
    $to = '';
    $action = '';
    $rangeValue = filter_value($filters, 'created_at');
    $rangeOp = filter_op($filters, 'created_at');
    if ($rangeOp === 'between' && is_array($rangeValue)) {
      $from = (string)($rangeValue[0] ?? '');
      $to = (string)($rangeValue[1] ?? '');
    }
    $actionValue = filter_value($filters, 'action');
    if (is_string($actionValue)) {
      $action = $actionValue;
    }
    $res = $auth->listAuditFiltered($page, $perPage, $from, $to, $action);
    Response::json(['ok' => true, 'data' => [
      'items' => $res['items'],
      'total' => $res['total'],
      'page' => $page,
      'per_page' => $perPage,
    ]]);
  }
}
