<?php

use MintyPHP\Http\ApiAuth;
use MintyPHP\Http\ApiBootstrap;
use MintyPHP\Http\ApiResponse;
use MintyPHP\Service\Access\AuthorizationDecision;
use MintyPHP\Service\Access\UserAuthorizationPolicy;
use MintyPHP\Service\Tenant\TenantService;
use MintyPHP\Service\User\UserAccountService;
use MintyPHP\Service\User\UserApiWriteInputMapper;

ApiBootstrap::init();
$request = requestInput();
$authorizationService = app(\MintyPHP\Service\Access\AuthorizationService::class);
$userAccountService = app(UserAccountService::class);
$apiDeny = static function (AuthorizationDecision $decision): void {
    if ($decision->isAllowed()) {
        return;
    }

    $status = $decision->status();
    $error = $decision->error() !== '' ? $decision->error() : 'forbidden';

    if ($status === 401) {
        ApiResponse::unauthorized();
    }
    if ($status === 404) {
        ApiResponse::notFound($error);
    }
    if ($status === 403) {
        ApiResponse::forbidden($error);
    }

    ApiResponse::error($error, $status > 0 ? $status : 403);
};
$method = $request->method();

if ($method === 'GET') {
    $decision = $authorizationService->authorize(UserAuthorizationPolicy::ABILITY_API_USERS_INDEX_GET, [
        'actor_user_id' => ApiAuth::userId(),
    ]);
    $apiDeny($decision);

    $limit = max(1, min(100, $request->queryInt('limit', 25)));
    $offset = max(0, $request->queryInt('offset', 0));
    $allowedOrders = ['id', 'uuid', 'first_name', 'last_name', 'display_name', 'email', 'created', 'modified', 'active', 'last_login_at'];
    $orderParam = $request->queryString('order');
    $order = in_array($orderParam, $allowedOrders, true) ? $orderParam : 'last_name';
    $dirParam = strtolower($request->queryString('dir'));
    $dir = in_array($dirParam, ['asc', 'desc'], true) ? $dirParam : 'asc';
    $activeParam = $request->query('active');
    if ($activeParam !== null) {
        $activeParam = in_array($activeParam, ['0', '1', 'true', 'false'], true) ? $activeParam : null;
    }
    $options = [
        'limit' => $limit,
        'offset' => $offset,
        'search' => $request->queryString('search'),
        'order' => $order,
        'dir' => $dir,
        'active' => $activeParam,
        'tenantUserId' => ApiAuth::userId(),
    ];
    $scopedTenantId = ApiAuth::scopedTenantId();
    if ($scopedTenantId) {
        $tenant = app(TenantService::class)->findById($scopedTenantId);
        $tenantUuid = trim((string) ($tenant['uuid'] ?? ''));
        if ($tenantUuid === '') {
            ApiResponse::notFound();
        }
        $options['tenant'] = $tenantUuid;
    }
    $result = $userAccountService->listPaged($options);

    $rows = [];
    foreach ($result['rows'] as $row) {
        $rows[] = [
            'uuid' => $row['uuid'] ?? '',
            'first_name' => $row['first_name'] ?? '',
            'last_name' => $row['last_name'] ?? '',
            'display_name' => $row['display_name'] ?? '',
            'email' => $row['email'] ?? '',
            'job_title' => $row['job_title'] ?? '',
            'phone' => $row['phone'] ?? '',
            'mobile' => $row['mobile'] ?? '',
            'active' => (bool) ($row['active'] ?? 1),
            'created' => $row['created'] ?? '',
            'tenants' => $row['tenant_labels'] ?? [],
            'departments' => $row['department_labels'] ?? [],
            'roles' => $row['role_labels'] ?? [],
        ];
    }

    ApiResponse::success([
        'data' => $rows,
        'total' => $result['total'] ?? 0,
        'limit' => $limit,
        'offset' => $offset,
    ]);
}

if ($method === 'POST') {
    $input = $request->bodyAll();
    $normalizeResult = app(UserApiWriteInputMapper::class)->normalize($input);
    if ($normalizeResult['ok'] !== true) {
        $errors = $normalizeResult['errors'] ?? [];
        ApiResponse::validationFromFormErrors(formErrorsFrom($errors ?: ['input' => ['invalid_value']]));
    }
    $input = $normalizeResult['input'] ?? $input;

    $decision = $authorizationService->authorize(UserAuthorizationPolicy::ABILITY_API_USERS_INDEX_POST, [
        'actor_user_id' => ApiAuth::userId(),
        'scoped_tenant_id' => ApiAuth::scopedTenantId(),
        'input' => $input,
    ]);
    $apiDeny($decision);
    $authorizedInput = $decision->attribute('input', null);
    if (is_array($authorizedInput)) {
        $input = $authorizedInput;
    }

    $result = $userAccountService->createFromAdmin($input, ApiAuth::userId());
    ApiResponse::fromServiceResult($result, 201);
}

ApiResponse::methodNotAllowed();
