<?php
/**
 * Repository Class
 *
 * @version     1.0.$Revision:$
 * @version     SVN: $Id:$
 * @package     bplan-base/globals
 * @subpackage  Repositories
 * @author      Emilio Cannarozzo <emilio.cannarozzo@bplan-solutions.de>
 * @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\Repositories\Core;


use BplanBase\Globals\Models\TenantLocale;
use BplanBase\Globals\Repositories\TenantRepository as BaseRepository;
use BplanBase\Globals\Scopes\TenantScope;
use Illuminate\Database\Eloquent\Collection;


/**
 * Repository Class
 *
 * @version     3.1.0 / 2025-05-25
 * @author      Emilio Cannarozzo <emilio.cannarozzo@bplan-solutions.de>
 * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
 */
class TenantLocaleRepository extends BaseRepository
{


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


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


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


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


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


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


    /**
     * Liefert einen Array mit den Locales des Mandanten
     *
     * Die Methode sucht, ausgehend vom übergebenen Tenant, solange bis bei beim Tenant selbst oder
     * irgendeinem der Master-Tenants Locales gefunden wurden.
     * Der Ergebnis-Array verwendet den KeyIndex der Locales als Schlüssel.
     *
     * @param       string $tenantId
     *
     * @param       bool $withInactive
     *
     * @return      array
     *
     * @version     1.0.0 / 2025-05-20
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public static function determineTenantLocales(string $tenantId, bool $withInactive = false): array|null
    {
        static $cache = [];

        $cacheKey = md5(serialize(func_get_args()));

        if (isset($cache[$cacheKey])) {
            return $cache[$cacheKey];
        }
        $LocaleCollection = self::getTenantLocales($tenantId, $withInactive);

        if ($LocaleCollection->isEmpty() === false) {
            $locales = [];

            foreach ($LocaleCollection as $TenantLocale) {
                $index = $TenantLocale->key_index;
                $locale = $TenantLocale->locale;

                $locales[$index] = $locale;
            }
            return $cache[$cacheKey] = $locales;
        }
        $Tenant = TenantRepository::getById($tenantId, ignoreRestriction: true);

        if ($Tenant->master_id !== null) {
            return $cache[$cacheKey] = self::determineTenantLocales($Tenant->master_id, $withInactive);
        }
        return null;
        /*
            @todo   Exception werfen.
                    Dieser Fall dürfte eigentlich nie eintreten, weil zumindest der System-Tenant
                    immer Locales haben sollte. Wenn er doch eintritt, dann ist schon bei der
                    Einrichtung des Systems etwas schiefgelaufen.
        */

    } // determineTenantLocales()


    /**
     * Liefert den aktuell höchsten Wert für die SortSequence in einer Gruppe von Auswahlwerten
     *
     * @param       int|string $tenantId
     *              Optional kann die ID eines Mandanten übergeben werden. Wenn der Parameter nicht
     *              verwendet wurd, dann wird die ID des Mandanten verwendet, über den der Zugriff
     *              auf die Api erfolgte.
     *
     * @param       bool $getNext
     *              Wird dieser Parameter auf TRUE gesetzt, dann wird anstelle des aktuell höchsten
     *              Werts der nächsthöhere Wert geliefert wird. Dabei wird nicht einfach nur 1 zum
     *              ermittelten Wert addiert, sondern es wird auch dafür gesorgt, dass die
     *              Nachkommastelle 0 ist.
     *
     * @return      float
     *
     * @version     1.0.0 / 2025-05-20
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public static function getMaxKeyIndex(int|string $tenantId, bool $getNext = false): float
    {
        $max = (int) static::$_modelClass::select('id')
            ->where('tenant_id', '=', $tenantId)
            ->max('key_index');

        if ($getNext === true) {
            $max++;
        }
        return $max;

    } // getMaxKeyIndex()


    /**
     * Liefert eine Collection mit den Locales des Mandanten
     *
     * Die Collection ist so sortiert, dass die Haupt-Locale an erster Stelle steht.
     *
     * @param       null|string $tenantId
     *
     * @param       bool $withInactive
     *
     * @return      Collection
     *
     * @version     1.0.0 / 2025-05-20
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public static function getTenantLocales(null|string $tenantId = null, bool $withInactive = false): Collection
    {
        static $cache = [];

        $cacheKey = md5(serialize(func_get_args()));

        if (isset($cache[$cacheKey])) {
            return $cache[$cacheKey];
        }
        $Query = TenantLocale::where('tenant_id', '=', $tenantId)
            ->withoutGlobalScope(TenantScope::class);

        if ($withInactive === false) {
            $Query->where('active', '=', 1);
        }
        $Query->orderBy('key_index');
// $Query->dumpRawSql();
        return $cache[$cacheKey] = $Query->get();

    } // getTenantLocales()


} // class TenantLocaleRepository extends BaseRepository {}
