<?php
/**
 *
 * @todo        Löschung (inklusive verknüpfter Daten) implementieren.
 *
 * @version     1.0.$Revision:$
 * @version     SVN: $Id:$
 * @package     bplan-base/globals
 * @subpackage  LivewireComponents
 * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
 * @copyright   Copyright (C) 2025, 2026 Wassilios Meletiadis <https://www.bplan-solutions.de/>
 * /Δ\
 */

namespace BplanBase\Globals\Livewire\Core\EntityType;


use BplanBase\Globals\Enums\CaseStyle;
use BplanBase\Globals\Enums\DeleteMode;
use BplanBase\Globals\Enums\Number;
use BplanBase\Globals\Helpers\ArrayHelper;
use BplanBase\Globals\Helpers\StringHelper;
use BplanBase\Globals\Livewire\Core\Global\BaseForm;
use BplanBase\Globals\Models\Tenant;
use BplanBase\Globals\Repositories\Core\EntityTypeFieldRepository;
use BplanBase\Globals\Repositories\EntityTypeRepository;
use BplanBase\Globals\Repositories\EntityTypeTenantRepository;
use BplanBase\Globals\Repositories\TenantLocaleRepository;
use BplanBase\Globals\Repositories\TenantRepository;
use BplanBase\Globals\Services\EntityTypeService;
use BplanBase\Globals\Services\EntityTypeTenantService;
use Exception;
use Illuminate\Support\Str;


/**
 *
 * @version     1.4.0 / 2026-05-17
 * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
 */
class Form extends BaseForm
{


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


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


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


    /**
     * @var     array $dataStorages
     */
    public $dataStorages;


    /**
     * @var     array $dataStorageTypes
     */
    public $dataStorageTypes;


    /**
     * @var     array $deleteModeOptions
     */
    public $deleteModeOptions;


    /**
     * @var     string $entity_type_id
     */
    public $entity_type_id;


    /**
     * @var     array $fields
     */
    public $fields = [];


    /**
     * @var     array $labels
     */
    public $labels;


    /**
     * @var     array $localeFields
     */
    public $localeFields = [];


    /**
     * @var         array   $main
     * @version     1.1.0 / 2026-05-17
     */
    public $main = [
        'abstract'         => false,
        'active'           => true,
        'custom_mask'       => '',
        'creatable'        => true,
        'delete_mode'      => DeleteMode::SoftDelete->value,
        'editable'         => true,
        'editType'         => '',
        'identifier'       => '',
        'historize'        => true,
        'html_mask'        => '',
        'main_type'        => '',
        'internal'         => false,
        'journalize'       => true,
        'labels'           => '',
        'require_release'  => false,
        'resource_name'    => '',
        'sub_type'         => '',
        'tenant_id'        => '',
        // 'text_mask'        => '',
        'visible'          => true,
    ];


    /**
     * @var     array $resourceContexts
     */
    public $resourceContexts = [
        'core' => 'core',
        'data' => 'data',
        //'internal' => 'internal', // nur für Entwickler
    ];


    /**
     * @var    array $tabs
     */
    public $tabs = [
        'base',
        'status',
        'translations',
        // 'appearance',
        'fields',
    ];


    /**
     * @var     array $tenant
     */
    public $tenant = [];


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


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


    /**
     * Überprüft den Status des EntityTypes
     *
     * Es wird überprüft ob der EntityType zum aktuellen oder ob er zu einem anderen Tenant gehört.
     * Wenn es sich um den EntityType eines anderen Tenants handelt wird zusätzlich noch geprüft ob
     * er bereits verknüpft ist.
     *
     * @version     1.2.0 / 2026-02-17
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _checkState(): void
    {
        if ($this->exists === true) {
            $tenantId = (int) Tenant::current()->id;
            /*
            **  Entity-Types eines anderen Mandaten und "abstract" gekennzeichnete Typen
            **  sind immer im ReadOnly-Modus. */
            if ($this->main['abstract'] === true || $this->main['tenant_id'] !== $tenantId) {
                /*
                **  Bei fremden EntityTypes wird das Formular immer nur im Readonly-Modus angezeigt. */
                $this->readOnly = true;
            }
            /*
            **  Copy-Button anzeigen. */
            $this->additionalButtons[] = 'copy';
        }
    } // _checkState()


    /**
     *
     * @version     1.0.0 / 2025-05-25
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _initDeleteModeOptions(): void
    {
        $deleteModeOptions = config('dynamic-data-handling.delete-mode-options');

        $this->deleteModeOptions = array_combine($deleteModeOptions, $deleteModeOptions);

    } // _initDeleteModeOptions()


    /**
     *
     * @version     1.2.0 / 2026-02-17
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _initTenant(): void
    {
        if ($this->exists === true) {
            /*
            **  Hier muss mit ignoreRestriction = TRUE gearbeitet werden, weil der User unter
            **  umständen keinen Zugriff auf den Tenant des EntityTypes hat.
            **
            **  @todo   Gegebenenfalls sollte die Methode TenantRepository::getWebModel() dahingehend
            **          geändert werden, dass bei ignoreRestriction = TRUE trotzdem die Tenants
            **          mit einbezogen werden, allerdings dann nicht mit den Tenants des Users
            **          sondern mit den Tenants aus dem ganzen Verbund.
            **          Alternativ könnte auch eine weitere Methode im TenantRepository angelegt
            **          werden, die diese Funktionalität implementiert. */
            $Tenant = TenantRepository::getById($this->MainObject->tenant_id, ignoreRestriction: true);

            $this->tenant = [$this->MainObject->tenant_id => $Tenant->identifier];

        } else {
            $this->main['tenant_id'] = Tenant::current()->id;

            $Tenant = TenantRepository::getById($this->main['tenant_id']);

            $this->tenant = [$this->main['tenant_id'] => $Tenant->identifier];
        }
    } // _initTenant()


    /**
     *
     * @param       bool $saveWasCreate
     *
     * @version     1.0.0 / 2025-05-25
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _onAfterSave(bool $saveWasCreate): void
    {
        parent::_onAfterSave($saveWasCreate);

        if ($saveWasCreate === true) {
            $this->tabs['fields'] = [
                'active' => true,
                'identifier' => 'fields',
                'label' => __($this->localeFile.'.tab-name.fields'),
                'view' => 'fields',
            ];
        }
    } // _onAfterSave()


    /**
     *
     * @version     1.0.0 / 2025-05-25
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _onBeforeValidation(): void
    {
        parent::_onBeforeValidation();

        $this->_prepareTranslationsOnBeforeValidation('labels', $this->labels);

    } // _onBeforeValidation()


    /**
     * Öffnet ein Modal-Fenster mit der Aufforderung zur Bestätigung eines Kopiervorgangs
     *
     * @version     1.0.0 / 2025-05-25
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public function confirmCopy(): void
    {
        $this->showModal(self::MODAL_TYPE__CONFIRM, 'copy', __($this->localeFile.'.confirm.copy.message'), __($this->localeFile.'.confirm.copy.caption'));

    } // confirmCopy()


    /**
     * Erzeugt einen neuen EntityType auf Basis des aktuellen Typs
     *
     * @throws      QueryException
     *
     * @throws      Exception
     *
     * @version     1.0.0 / 2025-05-25
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public function copy(): void
    {
        $this->_hideNotification();

        $Service = new EntityTypeService();

        $Copy = $Service->copy($this->mainID);

        $redirectRoute = $this->getRedirectRoute('Create');
        $redirectParams = $this->getRedirectParameters('Create', $Copy->id);

        $redirectParams['tab'] = 'base';

        redirect()->route($redirectRoute, $redirectParams);

    } // copy()


    /**
     *
     * @version     1.1.0 / 2025-06-06
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public function mount(): void
    {
        parent::mount();

        $this->_initDeleteModeOptions();
        $this->_initTenant();
        $this->_initTranslations('labels');

        if ($this->exists === true) {
            $this->entity_type_id = $this->MainObject->id;

            $this->fields = EntityTypeFieldRepository::getAllByEntityType($this->entity_type_id, orderBy: 'identifier', withInactive: true)
                ->toArray();

            $this->_checkState();

        } else {
            $this->multiSaveButton = false;
            $this->redirectOnStandardSave = true;

            $this->tabs['fields']['active'] = false;
            $this->tabs['form-sections']['active'] = false;
        }
    } // mount()


    /**
     *
     * @version     1.0.0 / 2025-05-25
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public function updated($property): void
    {
        parent::updated($property);

        if ($property === 'main.main_type' || $property === 'main.sub_type') {
            if ($property === 'main.main_type') {
                $this->main['main_type'] = StringHelper::reformat($this->main['main_type'], CaseStyle: CaseStyle::Studly, Number: Number::Singular);
            } else {
                $this->main['sub_type'] = StringHelper::reformat($this->main['sub_type'], CaseStyle: CaseStyle::Studly, Number: Number::Singular);
            }
            $this->main['resource_name'] = StringHelper::reformat($this->main['main_type']
                .(empty($this->main['sub_type']) ? '' : '-'.$this->main['sub_type']), CaseStyle: CaseStyle::Slug, Number: Number::Plural);

            $this->main['identifier'] = $this->main['main_type'];

            if (!empty($this->main['sub_type'])) {
                $this->main['identifier'] .= '.'.$this->main['sub_type'];
            }
        }
    } // updated()


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


} // class Form extends BaseForm {}
