<?php

declare(strict_types=1);

namespace BotGuard\Controllers\Auth;

use BotGuard\Core\Auth;
use BotGuard\Core\Controller;
use BotGuard\Core\Csrf;
use BotGuard\Core\Request;
use BotGuard\Core\Response;
use BotGuard\Core\Session;
use BotGuard\Core\View;
use BotGuard\Models\AuditLog;
use BotGuard\Models\User;

/**
 * Handles dashboard/admin sign-in and sign-out.
 */
final class LoginController extends Controller
{
    public function __construct(
        View $view,
        Session $session,
        Csrf $csrf,
        Request $request,
        private Auth $auth,
        private User $users,
        private AuditLog $audit,
    ) {
        parent::__construct($view, $session, $csrf, $request);
    }

    public function show(Request $request): Response
    {
        if ($this->auth->check()) {
            return Response::redirect('/dashboard');
        }

        return $this->render('auth.login', ['title' => 'Sign in']);
    }

    public function login(Request $request): Response
    {
        $validator = $this->validate([
            'email'    => 'required|email',
            'password' => 'required',
        ]);

        if ($validator->fails()) {
            return $this->redirect('/login', 'error', $validator->firstError());
        }

        $email = (string) $request->input('email');
        $password = (string) $request->input('password');

        if (! $this->auth->attempt($email, $password)) {
            $this->audit->record(null, 'login.failed', $request->ip(), ['email' => $email]);

            return $this->redirect('/login', 'error', 'Invalid credentials.');
        }

        $userId = $this->auth->id();
        if ($userId !== null) {
            $this->users->touchLogin($userId);
            $this->audit->record($userId, 'login.success', $request->ip());
        }

        $intended = $this->session->pull('__intended_url', '/dashboard');

        return Response::redirect(is_string($intended) ? $intended : '/dashboard');
    }

    public function logout(Request $request): Response
    {
        $this->audit->record($this->auth->id(), 'logout', $request->ip());
        $this->auth->logout();
        $this->session->regenerate();

        return $this->redirect('/login', 'success', 'You have been signed out.');
    }
}
