<?php

use MintyPHP\Http\ApiAuth;
use MintyPHP\Http\ApiBootstrap;
use MintyPHP\Http\ApiResponse;
use MintyPHP\Service\Access\AccessServicesFactory;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\CustomField\UserCustomFieldValueService;
use MintyPHP\Service\User\UserServicesFactory;

ApiBootstrap::init();
$userServicesFactory = new UserServicesFactory();
$userAccountService = $userServicesFactory->createUserAccountService();
$userAssignmentService = $userServicesFactory->createUserAssignmentService();
$userRoleRepository = $userServicesFactory->createUserRoleRepository();
$rolePermissionRepository = (new AccessServicesFactory())->createRolePermissionRepository();

$uuid = trim((string) ($id ?? ''));
if ($uuid === '') {
    ApiResponse::notFound();
}

$method = strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET');

if ($method === 'GET') {
    ApiResponse::requirePermission(PermissionService::USERS_VIEW);

    $user = $userAccountService->findByUuid($uuid);
    if (!$user) {
        ApiResponse::notFound();
    }

    $userId = (int) ($user['id'] ?? 0);
    ApiAuth::requireResourceAccess('users', $userId);
    $assignments = $userAssignmentService->buildAssignmentsForUser($userId);
    $primaryTenantId = (int) ($user['primary_tenant_id'] ?? 0);
    $primaryTenant = $userAssignmentService->findTenantSummaryInAssignments($assignments, $primaryTenantId);
    $publicAssignments = $userAssignmentService->mapAssignmentsToPublic($assignments);
    $publicCustomFields = UserCustomFieldValueService::buildPublicValuesByTenant(
        $userId,
        $assignments['tenants'] ?? [],
        ApiAuth::scopedTenantId()
    );
    $publicPermissions = [];
    if (ApiAuth::hasPermission(PermissionService::PERMISSIONS_VIEW)) {
        $roleIds = $userRoleRepository->listRoleIdsByUserId($userId);
        $publicPermissions = $rolePermissionRepository->listPermissionKeysByRoleIds($roleIds);
    }

    ApiResponse::success([
        'data' => [
            'uuid' => $user['uuid'] ?? '',
            'first_name' => $user['first_name'] ?? '',
            'last_name' => $user['last_name'] ?? '',
            'display_name' => $user['display_name'] ?? '',
            'email' => $user['email'] ?? '',
            'job_title' => $user['job_title'] ?? '',
            'phone' => $user['phone'] ?? '',
            'mobile' => $user['mobile'] ?? '',
            'short_dial' => $user['short_dial'] ?? '',
            'address' => $user['address'] ?? '',
            'postal_code' => $user['postal_code'] ?? '',
            'city' => $user['city'] ?? '',
            'country' => $user['country'] ?? '',
            'active' => (bool) ($user['active'] ?? 1),
            'created' => $user['created'] ?? '',
            'modified' => $user['modified'] ?? '',
            'primary_tenant' => $primaryTenant,
            'permissions' => $publicPermissions,
            'assignments' => $publicAssignments,
            'custom_fields' => $publicCustomFields,
        ],
    ]);
}

if ($method === 'PUT' || $method === 'PATCH') {
    ApiResponse::requirePermission(PermissionService::USERS_UPDATE);

    $user = $userAccountService->findByUuid($uuid);
    if (!$user) {
        ApiResponse::notFound();
    }

    $userId = (int) ($user['id'] ?? 0);
    ApiAuth::requireResourceAccess('users', $userId);

    $input = ApiResponse::readJsonBody();
    $scopedTenantId = ApiAuth::scopedTenantId();
    if ($scopedTenantId) {
        if (array_key_exists('tenant_ids', $input)) {
            $tenantIdsRaw = $input['tenant_ids'];
            if (!is_array($tenantIdsRaw)) {
                $tenantIdsRaw = [$tenantIdsRaw];
            }
            $tenantIds = array_values(array_unique(array_filter(array_map(
                static fn ($value): int => (int) $value,
                $tenantIdsRaw
            ), static fn (int $value): bool => $value > 0)));
            if ($tenantIds && array_diff($tenantIds, [$scopedTenantId])) {
                ApiResponse::forbidden('tenant_scoped_token_forbidden');
            }
        }
        if (array_key_exists('primary_tenant_id', $input)) {
            $primaryTenantId = (int) ($input['primary_tenant_id'] ?? 0);
            if ($primaryTenantId > 0 && $primaryTenantId !== $scopedTenantId) {
                ApiResponse::forbidden('tenant_scoped_token_forbidden');
            }
        }
    }
    $result = $userAccountService->updateFromAdmin($userId, $input, ApiAuth::userId());
    ApiResponse::fromServiceResult($result);
}

if ($method === 'DELETE') {
    ApiResponse::requirePermission(PermissionService::USERS_DELETE);

    $user = $userAccountService->findByUuid($uuid);
    if (!$user) {
        ApiResponse::notFound();
    }

    $userId = (int) ($user['id'] ?? 0);
    ApiAuth::requireResourceAccess('users', $userId);

    $result = $userAccountService->deleteByUuid($uuid, ApiAuth::userId());
    ApiResponse::fromServiceResult($result);
}

ApiResponse::methodNotAllowed();
