<?php
/**
 * Middleware Class
 *
 * @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\Exceptions\BadRequestException;
use BplanBase\Globals\Models\Tenant;
use BplanBase\Globals\Models\User;
use BplanBase\Globals\MultiTenancy\CoreApiTenantInitializer;
use BplanBase\Globals\MultiTenancy\CoreWebTenantInitializer;
use BplanBase\Globals\Repositories\Core\TenantRepository;
use BplanBase\Globals\Repositories\UserRepository;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;


/**
 * Middleware Class
 *
 * @version     2.0.0 / 2026-03-24
 * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
 */
class InitApiEnv
{


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


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


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


    /**
     * @var     string
     */
    private $_clientId;


    /**
     * @var     string
     */
    private $_configTenantUid;


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


    /**
     * Die ID des Tenants zur UID aus dem Request-Header
     *
     * @var     string
     */
    protected $_tenantId;


    /**
     * Die UID des Tenants aus dem Request-Header
     *
     * @var     string
     */
    protected $_tenantUid;


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


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


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


    /**
     *
     * @return 	    void
     *
     * @version     1.0.0 / 2025-
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    private function _init()
    {
        $this->_Request = request();

        $this->_configTenantUid = $this->_tenantUid = config('globals.global-tenant');

        $this->_processHeaders();
        $this->_initUser();

        // $routePrefix = $this->_Request->route()?->getPrefix();

        // if (str_starts_with($routePrefix, 'api/data')) {
        //     $this->_processDataRequest($this->_Request);

        // } elseif (str_starts_with($routePrefix, 'api/terminal')) {
        //     $this->_processTerminalRequest($this->_Request);
        // }
    } // _init()


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

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


    /**
     * Initialisiert den User und legt Parameter in der Registry ab
     *
     * Es wird die ID des Users zur User-Uid aus dem Request-Header ermittelt.
     *
     * @todo        Im Fehlerfall muss eine passende Exception geworfen werden, damit eine korrekte
     *              Response ausgeliefert werden kann.
     *
     * @return      void
     *
     * @version     1.2.0 / 2026-02-17
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    private function _initUser(): void
    {
/*
    @todo   Diese Funktionalität muss noch fertiggestellt werden.
            Aktuell wird einfach nur die UID des Users aus dem Header verwendet.

    @todo   Der folgende Methodenaufruf kann NULL liefern, wenn eine ungültige oder auch gelöschte
            UserUID im Header angegeben ist.
            Diesen Fall abfangen.
*/
        $this->_User = UserRepository::getByName('system');

    } // _initUser()


    /**
     *
     * @param [type] $request
     * @param Closure $next
     * @return void
     */
    protected function _processDataRequest($request)
    {
        $user = auth('sanctum')->user(); // oder andere Guard

        if (!$user) {
            return response()->json(['error' => 'Unauthenticated.'], 401);
        }

        // Optional: Berechtigungen, Tenants usw. laden
        app()->instance(User::class, $user);
        // z.B. TenantContextService::initializeForUser($user);

    } // _processDataRequest()


    /**
     *
     * @return      $this
     *
     * @version     1.10.0 / 2026-02-17
     * @author      Wassilios Meletiadis Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    private function _processHeaders(): self
    {
        $this->_tenantUid = $this->_Request->header('Api-Tenant-UUID');
        $this->_clientId = $this->_Request->header('Api-Client-ID', config('globals.api.default-client'));

        $transactionKey = $this->_Request->header('Api-Transaction-Key', Str::uuid());

        \Registry::put('core.ApiTransactionKey', $transactionKey);

        // $headerTenantUid = $this->_Request->header('Api-Tenant-UUID');
        // $headerUserUid = $this->_Request->header('Api-User-UIUD');

        // $Tenant = TenantRepository::getByUuid($this->_tenantUid);
        // $this->_tenantId = $Tenant->id;



        // $UserID = UserRepository::getByName('System')->id;

        // $this->_initTenants($headerTenantUid, $this->_userId);

        return $this;

    } // _processHeaders()


    /**
     *
     * @param [type] $request
     * @param Closure $next
     * @return void
     */
    protected function _processTerminalRequest($request)
    {
        /*
            Arbeitsweise:
            Wenn es einen Config-Tenant gibt, dann ist der Header irrelevant. Es wird immer dieser Tenant verwendet.
        */

        if ($this->_tenantUid !== null && ($Tenant = Tenant::where('uuid', '=', $this->_tenantUid)->first())) {
            $user = $tenant->dummyUser(); // z. B. $tenant->systemUser()

        } else {
            $user = User::where('email', 'dummy-terminal@example.com')->first(); // Globaler Fallback
        }

        app()->instance(User::class, $user); // Kontext für weitere Services

    } // _processTerminalRequest()


    /**
     * Handle an incoming request.
     *
     * @param       Request $Request
     *
     * @param       Closure $Next
     *
     * @return      Response
     *
     * @version     1.0.0 / 2025-04-15
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public function handle(Request $Request, Closure $Next): Response
    {
        if (request()->is('api/*')) {
            $this->_init();

            $this->_initializeTenant();

            $this->_initUser();

            // dump(Tenant::current());
        }
        return $Next($Request);

    } // handle()


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


} // class InitApiEnv {}
