<?php

namespace Config;

use CodeIgniter\Config\Filters as BaseFilters;
use CodeIgniter\Filters\Cors;
use CodeIgniter\Filters\CSRF;
use CodeIgniter\Filters\DebugToolbar;
use CodeIgniter\Filters\ForceHTTPS;
use CodeIgniter\Filters\Honeypot;
use CodeIgniter\Filters\InvalidChars;
use CodeIgniter\Filters\PageCache;
use CodeIgniter\Filters\PerformanceMetrics;
use CodeIgniter\Filters\SecureHeaders;
use App\Filters\TenantResolver;
use App\Filters\Auth;
use App\Filters\RoleAccess;
use App\Filters\AdminAuth;
use App\Filters\ThrottleFilter;
use App\Filters\OrganizerAuth;

class Filters extends BaseFilters
{
    /**
     * Configures aliases for Filter classes to
     * make reading things nicer and simpler.
     *
     * @var array<string, class-string|list<class-string>>
     *
     * [filter_name => classname]
     * or [filter_name => [classname1, classname2, ...]]
     */
    public array $aliases = [
        'csrf'          => CSRF::class,
        'toolbar'       => DebugToolbar::class,
        'honeypot'      => Honeypot::class,
        'invalidchars'  => InvalidChars::class,
        'secureheaders' => SecureHeaders::class,
        'cors'          => Cors::class,
        'forcehttps'    => ForceHTTPS::class,
        'pagecache'     => PageCache::class,
        'performance'   => PerformanceMetrics::class,
        'tenant'        => TenantResolver::class,
        'auth'          => Auth::class,
        'role'          => RoleAccess::class,
        'adminAuth'     => AdminAuth::class,
        'throttle'      => ThrottleFilter::class,
        'organizerAuth' => OrganizerAuth::class,
    ];

    /**
     * List of special required filters.
     *
     * The filters listed here are special. They are applied before and after
     * other kinds of filters, and always applied even if a route does not exist.
     *
     * Filters set by default provide framework functionality. If removed,
     * those functions will no longer work.
     *
     * @see https://codeigniter.com/user_guide/incoming/filters.html#provided-filters
     *
     * @var array{before: list<string>, after: list<string>}
     */
    public array $required = [
        'before' => [
            'forcehttps', // Force Global Secure Requests
            'pagecache',  // Web Page Caching
        ],
        'after' => [
            'pagecache',   // Web Page Caching
            'performance', // Performance Metrics
            'toolbar',     // Debug Toolbar
        ],
    ];

    /**
     * List of filter aliases that are always
     * applied before and after every request.
     *
     * @var array{
     *     before: array<string, array{except: list<string>|string}>|list<string>,
     *     after: array<string, array{except: list<string>|string}>|list<string>
     * }
     */
    public array $globals = [
        'before' => [
            // webhooks/* are excluded from both: they're called machine-to-
            // machine by Hubtel with no session/subdomain and no CSRF token,
            // and resolve their own tenant explicitly from a URL segment
            // (see PaymentWebhookController) rather than subdomain/session.
            // admin/* is excluded from 'tenant' only (not csrf): the super-
            // admin control plane has no tenant at all — it operates across
            // every hotel from the control DB — so resolving one here would
            // be wrong even as a fallback. It keeps its own AdminAuth filter
            // instead (applied per route-group, see Routes.php).
            'tenant' => ['except' => ['webhooks/*', 'admin/*']], // must run first: every route below needs the tenant DB resolved
            // 'honeypot',
            // widget/* also excluded: it's genuinely embedded cross-origin
            // (an <iframe> on the hotel's own external website), and this
            // app's CSRF cookie is SameSite=Lax (app/Config/Cookie.php) —
            // not sent on cross-site iframe sub-resource requests, and
            // blocked outright by Safari's third-party storage partitioning.
            // The check would fail for real, non-malicious visitors, not
            // just attackers. There's no authenticated session to forge
            // actions against here anyway; the real abuse controls are the
            // 'throttle' filter plus full server-side re-validation of
            // availability/price on every POST (see WidgetBookingController)
            // — a forged/replayed POST can create at worst one more unpaid
            // pending_deposit booking, and no money moves without the guest
            // completing Hubtel's own hosted checkout.
            'csrf' => ['except' => ['webhooks/*', 'widget/*']],
            // 'invalidchars',
        ],
        'after' => [
            // 'honeypot',
            // 'secureheaders',
        ],
    ];

    /**
     * List of filter aliases that works on a
     * particular HTTP method (GET, POST, etc.).
     *
     * Example:
     * 'POST' => ['foo', 'bar']
     *
     * If you use this, you should disable auto-routing because auto-routing
     * permits any HTTP method to access a controller. Accessing the controller
     * with a method you don't expect could bypass the filter.
     *
     * @var array<string, list<string>>
     */
    public array $methods = [];

    /**
     * List of filter aliases that should run on any
     * before or after URI patterns.
     *
     * Example:
     * 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']]
     *
     * @var array<string, array<string, list<string>>>
     */
    public array $filters = [];
}
