<?php
namespace App\Action\User;

use App\Action\Common;
use App\Entity\User;
use App\Model\Users;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\JsonResponse;
use Zend\Hydrator\DelegatingHydrator;

/**
 * Class Register
 * @package App\Action\User
 */
class Register extends Common {
    /**
     * @param ServerRequestInterface $request
     * @param ResponseInterface $response
     * @param callable|null $next
     * @return null|ResponseInterface|JsonResponse
     */
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
    {

        $loginData = $data = [
            'website' => $request->getParsedBody()['site'],
            'fullname' => $request->getParsedBody()['name'],
            'email' => $request->getParsedBody()['email'],
            'password' => $request->getParsedBody()['password'],
        ];

        /** @var Users $userModel */
        $userModel = $this->container->get(Users::class);
        /** @var DelegatingHydrator $hydrator */
        $hydrator = $this->container->get(DelegatingHydrator::class);

        /** @var User $user */
        $user = $userModel->findOne(['email' => $data['email']]);

        $result = false;
        $response = null;
        if ($user) {
            //throw  new \Exception('User with email <' . $data['email'] . '> already exists');
            $msg['text'] = sprintf(_t('User with email &lt;%s&gt; already exists'), $data['email']);
        }
        try {
            $data['password'] = $userModel->hashPassword($data['password']);

            $user = $hydrator->hydrate($data, new User());

            $validator = new \App\Validator\User($hydrator);
            if ($validator->isValid($user)) {
                $result = $userModel->save($user);
                if ($result) {
                    //send activation email after success registration
                    $sendActivationMail = $this->container->get(Mail::class);
                    $response =  $this->authenticate($loginData, $request);
                    $request = $request->withAttribute('action', Mail::SEND_ACTIVATION);
                    $sendActivationMail($request, $response);
                } else {
                    $msg['text'] = _t('Database error');
                }
            } else {
                $msg['validation'] = $validator->getMessages();
                //throw  new \Exception(implode(PHP_EOL, $validator->getMessages()));
            }

        } catch (\Exception $e) {
            $msg['text'] = $e->getMessage();
            $msg['code'] = $e->getCode();
            if (!empty($e->getPrevious())) {
                $msg['prev_msg'] = $e->getPrevious()->getMessage();
                $msg['code'] = $e->getPrevious()->getCode();
            }
            $result = false;
        }

        if (!$response) {
            $response = new JsonResponse(['result' => (bool) $result, 'msg' => $msg]);
        }
        return  $response;
    }

}