<?php

declare(strict_types=1);

namespace ApiModel\Action;

use ApiModel\Service\AuthService;
use ApiModel\Service\MenuService;
use ApiModel\Shared\Dto\Auth\LoginInput;
use ApiModel\Shared\Support\AuthContext;
use ApiModel\Shared\I18n\Translator;
use ApiModel\Shared\Http\HttpUtil;
use ApiModel\Shared\Validation\CriticalInputValidator;
use Psr\Http\Message\ServerRequestInterface;

final class AuthAction
{
    public function __construct(
        private readonly AuthService $authService,
        private readonly MenuService $menuService,
    ) {}

    /** @return array<string,mixed> */
    public function login(ServerRequestInterface $request): array
    {
        $b = HttpUtil::parseJson($request);
        $lang = Translator::normalizeLang(is_string($b['lang'] ?? null) ? (string) $b['lang'] : $request->getHeaderLine('Accept-Language'));
        CriticalInputValidator::loginBody($b, $lang);
        $input = LoginInput::fromArray($b);

        return $this->withMenu($this->authService->login($input));
    }

    /** @return array<string,mixed> */
    public function refresh(ServerRequestInterface $request): array
    {
        $b = HttpUtil::parseJson($request);
        CriticalInputValidator::refreshBody($b);

        return $this->withMenu($this->authService->refresh(trim((string) $b['refresh_token'])));
    }

    /** @param array<string,mixed> $session */
    private function withMenu(array $session): array
    {
        $session['menu'] = $this->menuService->getMenuForUser(
            (string) $session['user']['id'],
            (string) ($session['user']['language'] ?? 'es'),
        );

        return $session;
    }

    /** @return array<string,mixed> */
    public function logout(ServerRequestInterface $request): array
    {
        $u = AuthContext::jwtUser($request);
        $b = HttpUtil::parseJson($request);
        CriticalInputValidator::logoutBody($b, $u['language']);
        $this->authService->logout($u['userId'], trim((string) $b['refresh_token']));

        return ['ok' => true];
    }

    /** @return array<string,mixed> */
    public function forgotPassword(ServerRequestInterface $request): array
    {
        $b = HttpUtil::parseJson($request);
        $lang = Translator::normalizeLang(
            is_string($b['lang'] ?? null) ? (string) $b['lang'] : $request->getHeaderLine('Accept-Language'),
        );
        CriticalInputValidator::forgotPasswordBody($b, $lang);

        return $this->authService->forgotPassword(trim((string) $b['email']), $lang);
    }

    /** @return array<string,mixed> */
    public function resetPassword(ServerRequestInterface $request): array
    {
        $b = HttpUtil::parseJson($request);
        $lang = Translator::normalizeLang(
            is_string($b['lang'] ?? null) ? (string) $b['lang'] : $request->getHeaderLine('Accept-Language'),
        );
        CriticalInputValidator::resetPasswordBody($b, $lang);
        $this->authService->resetPassword(
            trim((string) $b['email']),
            trim((string) $b['code']),
            (string) $b['new_password'],
        );

        return ['ok' => true];
    }
}
