<?php

declare(strict_types=1);

namespace apexl\Io\modules\user\Actions;

use apexl\Config\Exceptions\MissingConfigException;
use apexl\hashing\Hash;
use apexl\Io\exceptions\RouteNotFoundException;
use apexl\Io\includes\RouteManager;
use apexl\Io\modules\notifier\exceptions\notifierException;
use apexl\Io\modules\notifier\factories\NotifierFactory;
use apexl\Io\modules\user\entities\userEntity;
use apexl\Io\modules\user\Factories\ForgotPasswordLinkFactory;
use apexl\Io\modules\user\notifiers\ResetPasswordEmailNotifier;
use apexl\Io\services\HttpPaths;

final readonly class ForgotPasswordAction
{
    public function __construct(
        private HttpPaths $httpPaths,
        private NotifierFactory $notifierFactory,
        private ForgotPasswordLinkFactory $forgotPasswordLinkService,
        private RouteManager $routeManager,
        private Hash $hash,
    ) {}

    /**
     * @throws MissingConfigException
     * @throws RouteNotFoundException
     * @throws notifierException
     */
    public function handle(userEntity $user): void
    {
        $this->notifierFactory->make(ResetPasswordEmailNotifier::class, [
            'user' => $user,
            'link' => $this->link($user),
        ])->send();
    }

    /**
     * @throws MissingConfigException
     * @throws RouteNotFoundException
     */
    private function link(userEntity $user): string
    {
        //we do this so the hash can be passed back as a url param rather than a query string.
        $randomHash = str_replace('/', '@', $this->hash->generateRandomHash());
        //write the hash to the database
        $this->forgotPasswordLinkService->create($user->email, $randomHash);

        return $this->httpPaths->frontendUrl(
            $this->routeManager->getRoutePattern('user.display.reset-password', ['hash' => $randomHash])
        );
    }
}