<?php


namespace App\Components\DataGrids;


use App\Model\Entities\GameData\Mmorpg\Faction;
use App\Model\Entities\GameData\Mmorpg\Race;
use App\Model\Facades\GameFacade;
use App\Model\Translator;
use Kdyby\Doctrine\QueryBuilder;
use Nette\Forms\Container;
use Nette\Utils\Html;
use Ublaboo\DataGrid\DataGrid;

class RacesDataGrid extends BaseMmoGameDataGrid
{
    public function __construct(Translator $translator, GameFacade $gameFacade)
    {
        parent::__construct($translator, $gameFacade);
        $this->enableAdder();
    }

    protected function setupDataSource() : QueryBuilder
    {
        return $this->gameFacade->getRaceReader()->getGridDataSource($this->game);
    }

    protected function setupColumns(DataGrid $grid)
    {
        $this->columnIdPreset($grid);
        $this->columnNamePreset($grid, true);
        foreach ($this->gameFacade->getFactionReader()->getFactions($this->game) as $faction) {
            $columnName = "faction{$faction->getId()}";
            $grid->addColumnText($columnName, $faction->getName())
                ->setAlign('center')
                ->setRenderer(function(Race $race) use ($faction) {
                    return $this->availabilityRenderer($race, $faction);
                });
        }
    }

    public function setupAdder(Container $container)
    {
        $container->addText('name', '')->setRequired();
        foreach ($this->gameFacade->getFactionReader()->getFactions($this->game) as $faction) {
            $columnName = "faction{$faction->getId()}";
            $container->addSelect($columnName, '', [false => 'Not available', true => 'Available']);
        }
    }

    protected function processAdder($values)
    {
        $availableToFactions = array();
        foreach ($this->gameFacade->getFactionReader()->getFactions($this->game) as $faction) {
            $columnName = "faction{$faction->getId()}";
            if ($values->$columnName) {
                $availableToFactions[] = $faction->getId();
            }
        }

        $this->gameFacade->getRaceWriter()->createRace($this->game, $values->name, $availableToFactions);
    }

    protected function editName(int $id, string $name)
    {
        $this->gameFacade->getRaceWriter()->editName($id, $name);
    }

    public function handleChangeAvailability($race, $faction, $available)
    {
        if ($available) {
            $this->gameFacade->getRaceWriter()->makeRaceAvailableToFaction($race, $faction);
        } else {
            $this->gameFacade->getRaceWriter()->makeRaceUnavailableToFaction($race, $faction);
        }
        $this->redrawRow($race);
    }

    protected function availabilityRenderer(Race $race, Faction $faction)
    {
        $dropdown = Html::el('div');
        $dropdown->class = 'dropdown';
            $button = Html::el('button');
            $button->addAttributes(['type' => 'button']);
            $button->data('toggle', 'dropdown');
            $button->class[] = 'dropdown-toggle btn btn-xs';
            $caret = Html::el('i');
            $caret->class[] = 'caret';
            if ($faction->getRaces()->contains($race)) {
                $button->class[] = 'btn-success';
                $button->setHtml("Available {$caret}");
            } else {
                $button->class[] = 'btn-danger';
                $button->setHtml("Not available {$caret}");
            }
        $dropdown->add($button);
            $ul = Html::el('ul');
            $ul->class = 'dropdown-menu';
                $li = Html::el('li');
                    $a = Html::el('a');
                    $a->class = 'ajax';
                    $a->href($this->link('changeAvailability!', ['race' => $race->getId(), 'faction' => $faction->getId(), 'available' => true]));
                    $a->setText('Available');
                $li->add($a);
            $ul->add($li);
                $li = Html::el('li');
                    $a = Html::el('a');
                    $a->class = 'ajax';
                    $a->href($this->link('changeAvailability!', ['race' => $race->getId(), 'faction' => $faction->getId(), 'available' => false]));
                    $a->setText('Not available');
                $li->add($a);
            $ul->add($li);
        $dropdown->add($ul);

        return $dropdown;
    }

}