<?php

require_once BASE_PATH . '/app/models/ActivityLog.php';
require_once BASE_PATH . '/app/models/SystemSetting.php';

abstract class AdminBaseController
{
    private ActivityLog $activityLog;
    private SystemSetting $systemSetting;

    public function __construct()
    {
        $this->activityLog = new ActivityLog();
        $this->systemSetting = new SystemSetting();
    }

    protected function requireAdmin(): void
    {
        if (!isset($_SESSION['user'])) {
            $_SESSION['redirect_after_login'] = $_SERVER['REQUEST_URI']
                ?? BASE_URL . '/?url=admin';
            header('Location: ' . BASE_URL . '/?url=login');
            exit;
        }

        if (($_SESSION['user']['role'] ?? null) !== 'admin') {
            http_response_code(403);
            require BASE_PATH . '/app/views/errors/403.php';
            exit;
        }
    }

    protected function requirePost(): void
    {
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
            http_response_code(405);
            exit('Method Not Allowed');
        }
    }

    protected function validateCsrf(): void
    {
        $token = $_POST['_token'] ?? '';
        $sessionToken = $_SESSION['csrf_token'] ?? '';

        if ($token === '' || $sessionToken === ''
            || !hash_equals($sessionToken, $token)) {
            http_response_code(403);
            exit('Yêu cầu không hợp lệ.');
        }
    }

    protected function mutateAndLog(
        callable $mutation,
        string $action,
        string $entityType,
        ?int $entityId,
        array $details,
        bool $securityAction = false
    ): void {
        $loggingEnabled = $this->systemSetting->getBoolean(
            'activity_logging_enabled',
            true
        );

        if (!$securityAction && !$loggingEnabled) {
            $mutation();
            return;
        }

        $this->activityLog->transaction(function () use (
            $mutation,
            $action,
            $entityType,
            $entityId,
            $details
        ): void {
            $mutation();
            $this->activityLog->create(
                (int) $_SESSION['user']['id'],
                $action,
                $entityType,
                $entityId,
                $details,
                $_SERVER['REMOTE_ADDR'] ?? null,
                $_SERVER['HTTP_USER_AGENT'] ?? null
            );
        });
    }

    protected function activityLog(): ActivityLog
    {
        return $this->activityLog;
    }

    protected function systemSetting(): SystemSetting
    {
        return $this->systemSetting;
    }

    protected function flashSuccess(string $message): void
    {
        $_SESSION['flash_success'] = $message;
    }

    protected function flashError(string $message): void
    {
        $_SESSION['flash_error'] = $message;
    }

    protected function redirect(string $route, array $query = []): never
    {
        $location = BASE_URL . '/?url=' . urlencode($route);
        if ($query !== []) {
            $location .= '&' . http_build_query($query);
        }

        header('Location: ' . $location);
        exit;
    }
}
