<?php

namespace App\Providers\Filament;

use App\Filament\Central\Pages\Auth\Login;
use App\Filament\Central\Widgets\CentralTenantsOverview;
use App\Filament\Central\Widgets\ClockWidget;
use App\Filament\Central\Widgets\RecentTenantsWidget;
use App\Http\Middleware\EnsureCentralAdmin;
use App\Http\Middleware\IdentifyTenant;
use App\Support\Theme\ThemePalette;
use Filament\Auth\MultiFactor\App\AppAuthentication;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\AuthenticateSession;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages\Dashboard;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Assets\Css;
use Filament\Support\Assets\Js;
use Filament\Support\Colors\Color;
use Filament\View\PanelsRenderHook;
use Filament\Widgets\AccountWidget;
use Illuminate\Contracts\View\View;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;

/**
 * The master-control (landlord) panel: tenant CRUD, entitlements,
 * branch/till management, storage sources, impersonation. Bound to
 * config('tenancy.central_domain') (default admin.localhost) — MUST be
 * registered before TenantPanelProvider in bootstrap/providers.php so it
 * takes priority on that host (mirrors the source app's routes/central.php
 * being registered first in bootstrap/app.php). See docs/migration-plan.md §1.
 *
 * Guard: central (App\Models\Central\CentralAdmin) — completely separate
 * from tenant users; no RBAC layer on this side (any active central admin
 * can do anything here), matching the source app.
 */
class CentralPanelProvider extends PanelProvider
{
    public function panel(Panel $panel): Panel
    {
        return $panel
            ->id('central')
            // Path tenancy (docs/path-based-tenancy-plan.md Phase 2): the
            // master-control panel lives under the configured first segment
            // ("/admin/...") on the single host, so central and tenant routes
            // no longer share a URL namespace and the old domain-bound host
            // setup disappears. The 'filament.central.*' route-name lock in
            // IdentifyTenant's host detection compensated for that shared
            // namespace and is gone with it (path mode detects central by the
            // prefix instead — see IdentifyTenant::handlePathRouting()).
            ->path(config('tenancy.routing') === 'path' ? config('tenancy.central_prefix') : '')
            // Subdomain mode: bound to its own host, domain takes priority over
            // TenantPanelProvider (registered first in bootstrap/providers.php).
            ->domain(config('tenancy.routing') === 'path' ? null : config('tenancy.central_domain'))
            ->authGuard('central')
            ->login(Login::class)
            ->profile(isSimple: false)
            ->passwordReset()
            ->multiFactorAuthentication([
                AppAuthentication::make()->recoverable(),
            ])
            // The full named ramp catalogue mirrors TenantPanelProvider's
            // registration: the master-control side has no status badges of its
            // own, but tenants' seeded status colours must resolve identically
            // in any panel that renders them (theme preview, impersonation).
            ->colors([
                'primary' => Color::Slate,
                ...ThemePalette::filamentStatusColors(),
            ])
            ->brandName(config('app.name'))
            ->brandLogo(asset('images/vellix-point-logo.png'))
            ->favicon(asset('images/vellix-point-logo.png'))
            ->sidebarCollapsibleOnDesktop()
            ->sidebarFullyCollapsibleOnDesktop()
            // The tenant edit page's live previews were painted by ~1MB of
            // inline <style>/<script> blocks (the per-preset colour data and
            // the chrome restatement). In debug builds Livewire strips script
            // blocks with a lazy regex that blew pcre.backtrack_limit on that
            // payload and the whole page threw; the data is still embedded
            // (it is server-generated, per request), but the static parts —
            // the .fi-tp chrome CSS and the bridge logic — live here, so the
            // page ships a fraction of the inline bytes and they are cached
            // like any other asset. The bridge no-ops when the config block
            // is absent, so the JS is harmless on any other page.
            ->assets([
                Css::make('tenant-preview', resource_path('css/filament/central/tenant-preview.css')),
                Js::make('preview-bridge', resource_path('js/preview-bridge.js'))->defer(),
            ])
            // The topbar record-search box searched across resources, didn't
            // work reliably, and wasn't needed here — replaced below by a
            // menu-label search in the sidebar itself.
            ->globalSearch(false)
            ->viteTheme('resources/css/filament/app/theme.css')
            ->renderHook(PanelsRenderHook::TOPBAR_LOGO_BEFORE, fn (): View => view('filament.partials.sidebar-collapse-toggle'))
            ->renderHook(PanelsRenderHook::SIDEBAR_NAV_START, fn (): View => view('filament.partials.sidebar-nav-search'))
            // Rendered inside .fi-topbar-end just before the user menu, so the
            // right side reads: clock, profile.
            ->renderHook(PanelsRenderHook::GLOBAL_SEARCH_AFTER, fn (): View => view('filament.partials.clock'))
            ->renderHook(PanelsRenderHook::FOOTER, fn (): View => view('filament.partials.copyright-footer', [
                'company' => 'Vellix Global',
                'year' => now()->format('Y'),
            ]))
            ->discoverResources(in: app_path('Filament/Central/Resources'), for: 'App\Filament\Central\Resources')
            ->discoverPages(in: app_path('Filament/Central/Pages'), for: 'App\Filament\Central\Pages')
            ->pages([
                Dashboard::class,
            ])
            ->discoverWidgets(in: app_path('Filament/Central/Widgets'), for: 'App\Filament\Central\Widgets')
            ->widgets([
                ClockWidget::class,
                AccountWidget::class,
                CentralTenantsOverview::class,
                RecentTenantsWidget::class,
            ])
            ->middleware([
                EncryptCookies::class,
                AddQueuedCookiesToResponse::class,
                StartSession::class,
                AuthenticateSession::class,
                ShareErrorsFromSession::class,
                VerifyCsrfToken::class,
                SubstituteBindings::class,
                DisableBladeIconComponents::class,
                DispatchServingFilamentEvent::class,
                IdentifyTenant::class,
            ])
            ->authMiddleware([
                Authenticate::class,
                EnsureCentralAdmin::class,
            ]);
    }
}
