<?php

namespace MintyPHP\Http;

use MintyPHP\I18n;
use MintyPHP\Router;

/**
 * Handles public path detection and authentication guards.
 */
class AccessControl
{
    /** Prefixes that are always public */
    private const ALWAYS_PUBLIC_PREFIXES = [
        'branding/',
        'auth/tenant-avatar-file',
        'flash/',
        'auth/microsoft/',
        'api/',
    ];

    private array $configuredPublicPaths;

    public function __construct(?array $publicPaths = null)
    {
        $this->configuredPublicPaths = $publicPaths ?? (defined('APP_PUBLIC_PATHS') ? APP_PUBLIC_PATHS : []);
    }

    /**
     * Check if a path is publicly accessible (no authentication required).
     */
    public function isPublicPath(string $path): bool
    {
        $normalizedPath = $this->normalizePath($path);

        // Root path check
        if ($normalizedPath === '/') {
            return in_array('/', $this->configuredPublicPaths, true);
        }

        // Check configured public paths
        if (in_array($normalizedPath, $this->configuredPublicPaths, true)) {
            return true;
        }

        // Check always-public prefixes
        foreach (self::ALWAYS_PUBLIC_PREFIXES as $prefix) {
            if (str_starts_with($normalizedPath, $prefix)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Redirect to login if the path requires authentication and user is not logged in.
     *
     * @return bool True if access is allowed, false if redirected
     */
    /**
     * Redirect to login if the path requires authentication and user is not logged in.
     * Appends ?return_to= so the user is redirected back after login.
     *
     * @return bool True if access is allowed, false if redirected
     */
    public function requireAuthOrRedirect(string $path, bool $isLoggedIn): bool
    {
        if ($this->isPublicPath($path) || $isLoggedIn) {
            return true;
        }

        $locale = I18n::$locale ?? I18n::$defaultLocale;
        $loginPath = Request::withLocale('login', $locale);

        $requestUri = $_SERVER['REQUEST_URI'] ?? '';
        $intendedUrlService = app(IntendedUrlService::class);
        $loginTarget = $intendedUrlService->buildLoginRedirect($loginPath, $requestUri);

        Router::redirect($loginTarget);

        return false;
    }

    private function normalizePath(string $path): string
    {
        $normalized = trim($path, '/');
        return $normalized === '' ? '/' : $normalized;
    }
}
