<?php
/**
 * Middleware Class
 *
 * @todo        Gegebenenfalls muss noch eine Prüfung implementiert werden, um sicherzustellen,
 *              dass der aktuelle Mandant auf das Modul zugreifen darf.
 *
 * @version     1.0.$Revision:$
 * @version     SVN: $Id:$
 * @package     bplan-base/globals
 * @subpackage  Middlewares
 * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
 * @copyright   Copyright (C) 2025, 2026 bplan-solutions GmbH & Co. KG <https://www.bplan-solutions.de/>
 * /Δ\
 */

namespace BplanBase\Globals\Http\Middleware;


use BplanBase\Globals\Models\Tenant;
use BplanBase\Globals\Models\User;
use BplanBase\Globals\Multitenancy\CoreWebTenantInitializer;
use BplanBase\Globals\Repositories\ModuleRepository;
use Closure;
use Illuminate\Http\Request;


/**
 * Middleware Class
 *
 * @version     2.3.0 / 2026-05-15
 * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
 */
class InitWebEnv
{


/* +++ TRAITS +++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */


/* +++ CLASS CONSTANTS +++ ++++++++++++++++++++++++++++++++++++++++++++++++++ */


/* +++ OBJECT MEMBERS +++ +++++++++++++++++++++++++++++++++++++++++++++++++++ */


    /**
     * @var Request
     */
    protected Request $_Request;


    /**
     * @var User
     */
    protected User $_User;


/* +++ CLASS MEMBERS +++ ++++++++++++++++++++++++++++++++++++++++++++++++++++ */


/* +++ OBJECT METHODS +++ +++++++++++++++++++++++++++++++++++++++++++++++++++ */


    /**
     *
     * @return      void
     *
     * @version     1.2.0 / 2026-03-16
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _determineModule(): void
    {
        /*
        **  Get the route prefix from the request object. */
        $routePrefix = $this->_Request->route()->getPrefix();

        if (empty($routePrefix)) {
            /*
            **  Reset module information in the registry. */
            \Registry::forget('env', true);
            \Registry::put('env.currentModule', null);

        } else {
            /*
            **  Determine the module via the route prefix. */
            $Module = ModuleRepository::getByRoutePrefix($routePrefix);

            if ($Module === null) {
                /*
                **  Reset module information in the registry, if no proper module is found. */
                \Registry::forget('env', true);
                \Registry::put('env.currentModule', null);

            } else {
                /*
                **  Put the module information into the registry. */
                \Registry::put('env.currentModule', $Module->route_prefix);
                \Registry::put('env.module', $Module);
                \Registry::put('env.moduleName', $Module->package_name);
            }
        }
    } // _determineModule()


    /**
     *
     * @return      User
     *
     * @version     1.0.0 / 2026-02-17
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _getCurrentUser(): User
    {
        $User = auth()->user();

        if ($User !== null) {
            return $User;
        }
        return User::whereName('guest')->withoutTenancy()->first();

    } // _getCurrentUser()


    /**
     *
     * @param       Request $Request
     *
     * @return      void
     *
     * @version     1.1.0 / 2026-02-17
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _init(Request $Request)
    {
        $this->_Request = $Request;
        $this->_User = $this->_getCurrentUser();

    } // _init()


    /**
     *
     * @return      void
     *
     * @version     1.0.0 / 2026-02-17
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _initializeLocale(): void
    {
        $appLocale = $this->_Request->cookie('app_locale') ?: config('app.locale');

        app()->setLocale($appLocale);

        \Registry::put('appLocale', $appLocale);

    } // _initializeLocale()


    /**
     *
     * @return      void
     *
     * @version     1.0.1 / 2026-05-15
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _initializeTenant(): void
    {
        $finderClass = class_basename(config('multitenancy.tenant_finder'));

        if ($finderClass === 'CoreTenantFinder') {
            (new CoreWebTenantInitializer($this->_Request, $this->_User))->initialize();
        }
    } // _initializeTenant()


    /**
     *
     * @todo        Wird aktuell nicht verwendet. Es werden einfach immer nur Exceptions geworfen.
     *
     * @param       string $route
     *
     * @param       array $query
     *
     * @param       null|string $status
     *
     * @version     1.1.0 / 2026-02-17
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    private function _performRedirect(string $route, array $query = [], null|string $status = null)
    {
        if ($route === 'login') {
            if ($status === null) {
                $status = __('globals::global.error.auto-logout');
            }
            return redirect('login')->with('status', $status);

        } elseif ($route === 'logout') {
            if ($status === null) {
                $status = __('globals::global.error.auto-logout');
            }
            auth()->guard('web')->logout();

            return $this->_performRedirect('login', $query, $status);
        }
        return redirect()->route($route, $query);

    } // _performRedirect()


    /**
     * Handle an incoming request.
     *
     * @param       Request $Request
     *
     * @param       Closure $next
     *
     * @return      void
     *
     * @version     1.6.0 / 2026-02-17
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public function handle(Request $Request, Closure $next)
    {
        $this->_init($Request);

        $this->_initializeLocale();
        $this->_initializeTenant();
        $this->_determineModule();

        return $next($Request);

    } // handle()


/* +++ CLASS METHODS +++ ++++++++++++++++++++++++++++++++++++++++++++++++++++ */


} // class InitWebEnv {}
