<?php

declare(strict_types=1);

namespace Builder\Core\Foundation\Middleware;

use Builder\Core\Foundation\Contracts\BuilderAccessible;
use Builder\Core\Foundation\Navigation\NavigationBuilder;
use Builder\Core\Foundation\Registry;
use Builder\Core\Models\Language;
use Illuminate\Http\Request;
use Inertia\Middleware;
use Override;

final class HandleInertiaRequests extends Middleware
{
    protected $rootView = 'builder::app';

    public function __construct(
        private readonly Registry $registry,
        private readonly NavigationBuilder $navigationBuilder,
    ) {}

    /** @return array<string, mixed> */
    #[Override]
    public function share(Request $request): array
    {
        $guard = BuilderAuth::guard();
        $user = $request->user($guard);

        $permissions = [];
        if ($user instanceof BuilderAccessible) {
            $permissions = $user->builderPermissions();
        }

        return array_merge(parent::share($request), [
            'navigation' => $this->navigationBuilder->build($permissions),
            'auth' => [
                'user' => $user ? [
                    'name' => $user->getAttribute('name'),
                    'email' => $user->getAttribute('email'),
                    'locale' => $user->locale ?? null,
                ] : null,
                'permissions' => $permissions,
                'logoutUrl' => route('builder.logout'),
                'socialProviders' => fn (): array => collect($this->registry->getAuthProviders())
                    ->map(function (string $class): array {
                        $provider = new $class;

                        return [
                            'identifier' => $provider->identifier(),
                            'label' => $provider->label(),
                            'url' => route($provider->redirectRoute()),
                            'icon' => $provider->icon(),
                        ];
                    })
                    ->values()
                    ->all(),
            ],
            'flash' => [
                'success' => fn () => $request->session()->get('success'),
                'error' => fn () => $request->session()->get('error'),
                'toast' => fn () => $request->session()->get('toast'),
            ],
            'translations' => function (): array {
                $result = ['builder' => trans('builder::builder')];
                foreach ($this->registry->translationNamespaces() as $key => $transKey) {
                    $result[$key] = trans($transKey);
                }

                return $result;
            },
            'hasMedia' => app()->bound('builder.media'),
            'publicUrl' => (string) config('builder.public_url') ?: config('app.url', ''),
            'seoSettings' => app()->bound('builder.seo')
                ? rescue(function (): array {
                    /** @var object{site_name: ?string, separator: ?string, favicon_url: ?string} $seoSettings */
                    $seoSettings = app('Builder\Seo\Settings\SeoSettings');

                    $rawSep = $seoSettings->separator;

                    return [
                        'site_name' => $seoSettings->site_name,
                        'separator' => $rawSep !== null ? ' '.trim($rawSep).' ' : ' | ',
                        'favicon_url' => $seoSettings->favicon_url,
                    ];
                })
                : null,
            'languages' => fn (): array => Language::allLocales()->map(fn (Language $l): array => [
                'code' => $l->code,
                'name' => $l->name,
                'is_active' => $l->is_active,
                'is_default' => $l->is_default,
            ])->all(),
        ]);
    }
}
