<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Services\AuthService;

class AuthController extends Controller
{
    private AuthService $auth;

    public function __construct()
    {
        $this->auth = new AuthService();
    }

    public function register(): string
    {
        require_guest();

        return $this->view('auth/register', [
            'title' => 'Criar conta',
        ]);
    }

    public function store(Request $request): void
    {
        require_guest();
        $this->guardCsrf($request);

        $result = $this->auth->register($request->all());

        if (!$result['ok']) {
            keep_old($request->all());
            flash('error', implode(' ', $result['errors']));
            app()->response()->back();
        }

        clear_old();
        flash('success', 'Conta criada com sucesso. Pode iniciar sessao.');
        app()->response()->redirect('/login');
    }

    public function login(): string
    {
        require_guest();

        return $this->view('auth/login', [
            'title' => 'Entrar',
        ]);
    }

    public function authenticate(Request $request): void
    {
        require_guest();
        $this->guardCsrf($request);

        $result = $this->auth->login(
            (string) $request->post('email', ''),
            (string) $request->post('password', '')
        );

        if (!$result['ok']) {
            keep_old($request->all());
            flash('error', $result['error']);
            app()->response()->back();
        }

        clear_old();
        flash('success', 'Bem-vindo de volta.');
        app()->response()->redirect('/dashboard');
    }

    public function logout(Request $request): void
    {
        require_auth();
        $this->guardCsrf($request);

        $this->auth->logout();
        flash('success', 'Sessao terminada.');
        app()->response()->redirect('/');
    }

    public function forgotPassword(): string
    {
        require_guest();

        return $this->view('auth/forgot-password', [
            'title' => 'Recuperar senha',
        ]);
    }

    public function sendReset(Request $request): void
    {
        require_guest();
        $this->guardCsrf($request);

        $result = $this->auth->requestPasswordReset((string) $request->post('email', ''));

        if (!empty($result['token'])) {
            flash('success', 'Token gerado para ambiente local: ' . $result['token']);
        } else {
            flash('success', 'Se o email existir, enviaremos instrucoes de recuperacao.');
        }

        app()->response()->redirect('/reset-password');
    }

    public function resetPassword(): string
    {
        require_guest();

        return $this->view('auth/reset-password', [
            'title' => 'Nova senha',
        ]);
    }

    public function updatePassword(Request $request): void
    {
        require_guest();
        $this->guardCsrf($request);

        $result = $this->auth->resetPassword(
            (string) $request->post('email', ''),
            (string) $request->post('token', ''),
            (string) $request->post('password', '')
        );

        if (!$result['ok']) {
            flash('error', $result['error']);
            app()->response()->back();
        }

        flash('success', 'Senha actualizada. Pode iniciar sessao.');
        app()->response()->redirect('/login');
    }

    private function guardCsrf(Request $request): void
    {
        if (!verify_csrf((string) $request->post('_csrf_token', ''))) {
            flash('error', 'Sessao expirada. Tente novamente.');
            app()->response()->back();
        }
    }
}
