<?php

declare(strict_types=1);

namespace ServerManager\Controllers;

use ServerManager\Core\App;
use ServerManager\Core\Session;
use ServerManager\Core\Validator;
use ServerManager\Models\User;
use ServerManager\Services\AuditService;

class AuthController
{
    private User $userModel;
    private AuditService $auditService;
    private \ServerManager\Core\View $view;

    public function __construct()
    {
        $this->userModel = new User();
        $this->auditService = new AuditService();
        $this->view = App::getInstance()->getView();
    }

    public function loginForm(): void
    {
        if (Session::has('user_id')) {
            $this->view->redirect('/dashboard');
        }

        $this->view->setLayout('auth');
        $this->view->display('auth.login', [
            'title' => 'Login - ServerManager',
        ]);
    }

    public function login(): void
    {
        $validator = new Validator();
        $rules = [
            'username' => 'required',
            'password' => 'required|min:6',
        ];

        if (!$validator->validate($_POST, $rules)) {
            $error = $validator->getFirstError();
            $this->auditService->logLogin($_POST['username'] ?? 'unknown', false, $error);
            Session::setFlash('error', $error);
            $this->view->redirect('/login');
        }

        $username = $_POST['username'];
        $password = $_POST['password'];

        $user = $this->userModel->authenticate($username, $password);

        if (!$user) {
            $this->auditService->logLogin($username, false, 'Invalid credentials');
            Session::setFlash('error', 'Invalid username or password.');
            $this->view->redirect('/login');
        }

        Session::regenerate(true);

        Session::set('user_id', $user['id']);
        Session::set('username', $user['username']);
        Session::set('user_role', $user['role']);
        Session::set('user_email', $user['email']);
        Session::set('login_time', time());

        $lifetime = App::getConfig()['session']['lifetime'] ?? 1440;
        Session::set('session_expiry', time() + $lifetime);

        $this->auditService->logLogin($username, true);

        $intended = Session::get('intended_url', '/dashboard');
        Session::remove('intended_url');

        $this->view->redirect($intended);
    }

    public function registerForm(): void
    {
        if (Session::has('user_id')) {
            $this->view->redirect('/dashboard');
        }

        $this->view->setLayout('auth');
        $this->view->display('auth.register', [
            'title' => 'Register - ServerManager',
        ]);
    }

    public function register(): void
    {
        $validator = new Validator();
        $rules = [
            'username' => 'required|min:3|max:50',
            'email' => 'required|email',
            'password' => 'required|min:8',
            'confirm_password' => 'required|match:password',
        ];

        if (!$validator->validate($_POST, $rules)) {
            Session::setFlash('error', $validator->getFirstError());
            $this->view->redirect('/register');
        }

        $username = $_POST['username'];
        $email = $_POST['email'];

        $existing = $this->userModel->findByUsername($username);
        if ($existing) {
            Session::setFlash('error', 'Username already exists.');
            $this->view->redirect('/register');
        }

        $existingEmail = $this->userModel->findByEmail($email);
        if ($existingEmail) {
            Session::setFlash('error', 'Email already registered.');
            $this->view->redirect('/register');
        }

        $id = $this->userModel->create([
            'username' => $username,
            'email' => $email,
            'password' => $_POST['password'],
            'role' => 'admin',
            'is_active' => 1,
        ]);

        $this->auditService->log('user_registered', 'user', $id, [
            'username' => $username,
            'role' => 'admin',
        ]);

        Session::setFlash('success', 'Account created. You can now log in.');
        $this->view->redirect('/login');
    }

    public function logout(): void
    {
        $this->auditService->log(
            'logout',
            'user',
            Session::get('user_id'),
            ['username' => Session::get('username')]
        );

        Session::destroy();
        $this->view->redirect('/login');
    }

    public function profile(): void
    {
        $userId = Session::get('user_id');
        $user = $this->userModel->findById($userId);

        if (!$user) {
            $this->view->error(404);
        }

        $this->view->display('auth.profile', [
            'title' => 'My Profile - ServerManager',
            'user' => $user,
        ]);
    }

    public function updateProfile(): void
    {
        $userId = Session::get('user_id');

        $validator = new Validator();
        $rules = [
            'email' => 'required|email',
            'current_password' => 'required',
            'new_password' => 'min:8',
            'confirm_password' => 'match:new_password',
        ];

        if (!$validator->validate($_POST, $rules)) {
            Session::setFlash('error', $validator->getFirstError());
            $this->view->redirect('/profile');
        }

        $user = $this->userModel->findById($userId);

        $security = new \ServerManager\Core\Security();
        if (!$security->verifyPassword($_POST['current_password'], $user['password_hash'])) {
            Session::setFlash('error', 'Current password is incorrect.');
            $this->view->redirect('/profile');
        }

        $updateData = ['email' => $_POST['email']];

        if (!empty($_POST['new_password'])) {
            $updateData['password'] = $_POST['new_password'];
        }

        $this->userModel->update($userId, $updateData);

        $this->auditService->logUserManagement($userId, 'profile_updated');

        Session::setFlash('success', 'Profile updated successfully.');
        $this->view->redirect('/profile');
    }
}
