<?php

namespace apexl\Io\modules\display\components;

use apexl\Io\includes\Entity;
use apexl\Io\includes\RouteManager;
use apexl\Io\modules\component\Collections\ComponentCollection;
use apexl\Io\modules\component\Collections\ComponentPropertyCollection;
use apexl\Io\modules\component\Component\Component;
use apexl\Io\modules\component\Factories\ComponentPropertyFactory;
use apexl\Io\modules\component\Factories\GenericComponentFactory;
use Arrayy\Type\StringCollection;

/**
 * @deprecated Builder-pattern component incompatible with the readonly Component contract — mutating methods (setEntity()/addLinkParam()) fatal at runtime on write-once properties. Superseded by tabulator-based components: io-tabulator (Tabulator / EntityTabulator / AggregateTabulator); user/role admin screens via apexl/io-user-tabulator. Do not use in new code; removal planned once the legacy io-user userDisplay routes are gone.
 */
readonly class ButtonBar extends Component
{
    // Untyped properties / property defaults are illegal on readonly classes
    // (pre-existing parse error). $row is never used anywhere in this class
    // (dead), so `mixed` is the only inferable type. NOTE: addLinkParam()
    // appends to $linkParams post-construction, which is incompatible with
    // readonly write-once semantics — flagged for design review; only the
    // parse error is fixed here.
    protected mixed $row;
    protected array $linkParams;
    // These three were previously written without being declared; dynamic
    // properties are forbidden on readonly classes, so the writes below (and
    // in setEntity()) would fatal at runtime without these declarations.
    protected ColWrapper $colWrapper;
    protected RowWrapper $rowWrapper;
    protected Entity $entity;

    public function __construct(
        private readonly GenericComponentFactory $componentFactory,
        ComponentPropertyFactory $propertyFactory,
        ComponentPropertyCollection $props,
        ComponentCollection $components,
        StringCollection $classes,
        ?string $componentId = null,
        ?Entity $entity = null
    ) {
        parent::__construct($propertyFactory, $props, $components, $classes, $componentId);
        $this->linkParams = [];
        $this->addClass('button-link');

        $this->colWrapper = $this->componentFactory->make(ColWrapper::class);
        $this->rowWrapper = $this->componentFactory->make(RowWrapper::class)->addComponent($this->colWrapper);
        $this->addComponent($this->rowWrapper);
    }

    public function setEntity(Entity $entity, $pageType = 'View'): ButtonBar
    {
        $this->entity = $entity;
        if ($entity->{$entity->primaryKey}) {
            $this->addLinkParam($entity->primaryKey, $entity->{$entity->primaryKey});
        }
        match ($pageType) {
            'List' => $this->listViewPageButtons(),
            'View' => $this->addViewPageButtons(),
            'Edit' => $this->addEditPageButtons(),
            'Create' => $this->addCreatePageButtons(),
            default => $this,
        };

        return $this;
    }

    public function addLinkParam(string $name, string $value)
    {
        $this->linkParams[$name] = $value;
    }

    public function listViewPageButtons(): ButtonBar
    {
        $create = $this->entity->getEntityName() . '.display.post';
        $this->addCreateButton($create);

        return $this;
    }

    /**
     * @param $routeName
     */
    public function addCreateButton($routeName): ButtonBar
    {
        $this->addButton($routeName, 'Create', 'plus', $this->getAccessFromRoute($routeName));

        return $this;
    }

    /**
     * @param $routeName
     */
    public function addButton(
        $routeName,
        string $buttonText = '',
        string $icon = '',
        bool $disabled = false,
        bool $danger = false,
        string $asynch = null
    ): ButtonBar {
        $button = $this->componentFactory->make(SimpleButton::class)
            ->addRoute($this->routeManager->getRoutePattern($routeName, $this->linkParams, false))
            ->addText($buttonText);
        if ($icon !== '' && $icon !== '0') {
            $button->setProperty('icon', $icon);
        }
        if ($danger) {
            $button->addClass('btn btn-danger mx-2');
        } else {
            $button->addClass('btn mx-2 bg-transparent');
        }

        if ($disabled) {
            $button->addRoute('#');
            $button->addClass('btn-disabled');
            $button->disabled($disabled);
        }
        if ($asynch && in_array($asynch, ['GET', 'POST', 'PUT', 'DELETE'])) {
            $button->setProperty('asynch', $asynch);
        }
        $this->colWrapper->addComponent($button);

        return $this;
    }

    public function addText($text): ButtonBar
    {
        $this->setProperty('text', $text);

        return $this;
    }

    public function addRoute($route): ButtonBar
    {
        $this->setProperty('route', $route);

        return $this;
    }

    /**
     * @param $routeName
     */
    public function getAccessFromRoute($routeName): bool
    {
        $route = RouteManager::getRoute($routeName);
        if (($route ?? false) && $permission = $route->getPermission()) {
            //we need to pass the opposite here as disabled is false if access it true.
            return !$this->currentUser->isAllowed($permission);
        }

        //no permission? just return true.
        return (bool) $route; //no route? return false.
    }

    public function addViewPageButtons(): ButtonBar
    {
        $viewAll = $this->entity->getEntityName() . '.display.all';
        $edit = $this->entity->getEntityName() . '.display.put';
        $delete = $this->entity->getEntityName() . '.display.delete';
        $this->addViewAllButton($viewAll);
        $this->addEditButton($edit);
        $this->addDeleteButton($delete);

        return $this;
    }

    /**
     * @param $routeName
     */
    public function addViewAllButton($routeName): ButtonBar
    {
        $this->addButton($routeName, 'View All', 'list', $this->getAccessFromRoute($routeName));

        return $this;
    }

    /**
     * @param $routeName
     */
    public function addEditButton($routeName): ButtonBar
    {
        $this->addButton($routeName, 'Edit', 'edit', $this->getAccessFromRoute($routeName));

        return $this;
    }

    /**
     * @param $routeName
     */
    public function addDeleteButton($routeName): ButtonBar
    {
        $this->addButton($routeName, 'Delete', 'trash', $this->getAccessFromRoute($routeName), true);

        return $this;
    }

    public function addEditPageButtons(): ButtonBar
    {
        $viewAll = $this->entity->getEntityName() . '.display.all';
        $view = $this->entity->getEntityName() . '.display.get';
        $delete = $this->entity->getEntityName() . '.display.delete';
        $this->addViewButton($view);
        $this->addViewAllButton($viewAll);
        $this->addDeleteButton($delete);

        return $this;
    }

    /**
     * @param $routeName
     */
    public function addViewButton($routeName): ButtonBar
    {
        $this->addButton($routeName, 'View', 'eye', $this->getAccessFromRoute($routeName));

        return $this;
    }

    public function addCreatePageButtons(): ButtonBar
    {
        $viewAll = $this->entity->getEntityName() . '.display.all';
        $this->addViewAllButton($viewAll);

        return $this;
    }

    public function addForm(string $formId, string $routeName, $args)
    {
        $this->colWrapper->addComponent(
            (new FormComponent())->setId('SIMRefresh')->src(
                $this->routeManager->getRoutePattern('simcardDisplay.form.sims.refresh', $args)
            )
        );
    }

    public function addCallbackButton(string $name, string $routeName, $params)
    {
        //$this->colWrapper->addComponent(
        // (new inputField($name, 'button'))->setLabel(null)->setCallback(Routes::getRoutePattern($routeName, $params), 'put')->setValue(true)->addClass('btn mx-2 bg-transparent')
        //);
    }
}
