<?php
namespace Core;

abstract class Controller {
    protected Request $request;
    protected Database $db;

    public function __construct() {
        $this->request = new Request();
        $this->db      = Database::getInstance();
    }

    protected function view(string $view, array $data = [], ?string $layout = 'main'): void {
        View::render($view, $data, $layout);
    }

    protected function redirect(string $path): void {
        $url = rtrim(BASE_URL, '/') . '/' . ltrim($path, '/');
        header('Location: ' . $url);
        exit;
    }

    protected function back(): void {
        $ref = $_SERVER['HTTP_REFERER'] ?? rtrim(BASE_URL, '/') . '/';
        header('Location: ' . $ref);
        exit;
    }

    protected function json(mixed $data, int $code = 200): void {
        http_response_code($code);
        header('Content-Type: application/json');
        echo json_encode($data);
        exit;
    }

    protected function requireAuth(): void {
        if (!Session::has('user')) {
            Session::flash('error', 'Please login to continue.');
            header('Location: ' . rtrim(BASE_URL, '/') . '/login');
            exit;
        }
        // Check inactivity timeout
        if (Session::checkInactivity()) {
            Session::flash('error', 'You were inactive for 15 minutes. Please login again.');
            header('Location: ' . rtrim(BASE_URL, '/') . '/login');
            exit;
        }
        $user = Session::get('user');
        if (!$user['is_active']) {
            Session::destroy();
            Session::flash('error', 'Your account has been deactivated.');
            header('Location: ' . rtrim(BASE_URL, '/') . '/login');
            exit;
        }
    }

    protected function requireRole(string ...$roles): void {
        $this->requireAuth();
        $user = Session::get('user');
        if (!in_array($user['role'], $roles)) {
            http_response_code(403);
            $this->view('errors/403', [], 'main');
            exit;
        }
    }

    protected function verifyCsrf(): void {
        if (!Session::verifyCsrf()) {
            http_response_code(419);
            Session::flash('error', 'Session expired. Please try again.');
            Session::flash('errors', ['email' => 'Session expired. Please try again.']);
            $this->redirect('login');
        }
    }

    protected function currentUser(): ?array { return Session::get('user'); }
    protected function schoolId(): int       { return (int)(Session::get('user')['school_id'] ?? 0); }

    protected function withErrors(array $errors, array $old = []): void {
        Session::flash('errors', $errors);
        Session::flash('old', $old);
    }

    protected function withSuccess(string $msg): void { Session::flash('success', $msg); }
    protected function withError(string $msg): void   { Session::flash('error', $msg); }

    protected function logActivity(string $action, string $model = '', int $modelId = 0, array $old = [], array $new = []): void {
        $user = $this->currentUser();
        $this->db->insert('activity_logs', [
            'user_id'    => $user['id'] ?? null,
            'school_id'  => $user['school_id'] ?? null,
            'action'     => $action,
            'model'      => $model,
            'model_id'   => $modelId ?: null,
            'old_values' => $old ? json_encode($old) : null,
            'new_values' => $new ? json_encode($new) : null,
            'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '',
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ]);
    }
}
