<?php

declare(strict_types=1);

namespace Atk4\Ui\Demos;

use Atk4\Ui\App;
use Atk4\Ui\Columns;
use Atk4\Ui\Console;
use Atk4\Ui\Form;
use Atk4\Ui\Grid;
use Atk4\Ui\Header;
use Atk4\Ui\Message;
use Atk4\Ui\SessionTrait;
use Atk4\Ui\Table;
use Atk4\Ui\Wizard;

/** @var App $app */
require_once __DIR__ . '/../init-app.php';

$wizardClass = AnonymousClassNameCache::get_class(static fn () => new class extends Wizard {
    use SessionTrait;
});

$wizard = $wizardClass::addTo($app, ['urlTrigger' => 'demo_wizard']);
// First step will automatically be active when you open page first. It
// will contain the 'Next' button with a link.
$wizard->addStep('Welcome', static function (Wizard $wizard) {
    Message::addTo($wizard, ['Welcome to wizard demonstration'])->text
        ->addParagraph('Use button "Next" to advance')
        ->addParagraph('You can specify your existing database connection string which will be used
        to create a table for model of your choice');
});

// If you add a form on a step, then wizard will automatically submit that
// form on "Next" button click, performing validation and submission. You do not need
// to return any action from form's onSubmit callback. You may also use memorize()
// to store wizard-specific variables
$wizard->addStep(['Set DSN', 'icon' => 'configure', 'description' => 'Database Connection String'], static function (Wizard $wizard) {
    $form = Form::addTo($wizard);
    // IMPORTANT - needed for phpunit Wizard test
    $form->cb->setUrlTrigger('w_form_submit');

    $form->addControl('dsn', ['caption' => 'Connect DSN'], ['required' => true])->placeholder = 'mysql://user:pass@db-host.example.com/mydb';
    $form->onSubmit(static function (Form $form) use ($wizard) {
        $wizard->memorize('dsn', $form->entity->get('dsn'));

        return $wizard->jsNext();
    });
});

// Alternately, you may access buttonNext, buttonPrevious properties of a wizard
// and set a custom JS action or even set a different link. You can use recall()
// to access some values that were recorded on another steps.
$wizard->addStep(['Select Model', 'description' => '"Country" or "Stat"', 'icon' => 'table'], static function (Wizard $wizard) {
    if ($wizard->getApp()->hasRequestQueryParam('name')) {
        $wizard->memorize('model', $wizard->getApp()->getRequestQueryParam('name'));
        $wizard->getApp()->redirect($wizard->urlNext());
    }

    $columns = Columns::addTo($wizard);

    $grid = Grid::addTo($columns->addColumn(), ['paginator' => false, 'menu' => false]);
    Message::addTo($columns->addColumn(), ['Information', 'type' => 'info'])->text
        ->addParagraph('Selecting which model you would like to import into your DSN. If corresponding table already exist, we might add extra fields into it. No tables, columns or rows will be deleted.');

    $grid->setSource(['Country', 'Stat']);

    // should work after url() fix
    $grid->addDecorator('name', [Table\Column\Link::class, [], ['name']]);

    // $t->addDecorator('name', [Table\Column\Link::class, [$wizard->stepCallback->name => $wizard->currentStep], ['name']]);

    $wizard->buttonNext->addClass('disabled');
});

// Steps may contain interactive elements. You can disable navigational buttons
// and enable them as you see fit. Use handy JS method to trigger advancement to
// the next step.
$wizard->addStep(['Migration', 'description' => 'Create or update table', 'icon' => 'database'], static function (Wizard $wizard) {
    $console = Console::addTo($wizard);
    $wizard->buttonFinish->addClass('disabled');

    $console->set(static function (Console $console) use ($wizard) {
        $dsn = $wizard->recall('dsn');
        $model = $wizard->recall('model');

        $console->output('please wait');
        sleep(1);
        $console->output('connecting to "' . $dsn . '" (well not really, this is only a demo)');
        sleep(2);
        $console->output('initializing table for model "' . $model . '" (again - tricking you)');
        sleep(1);
        $console->output('DONE');

        $console->send($wizard->buttonFinish->js()->removeClass('disabled'));
    });
});

// Calling addFinish adds a step, which will not appear in the list of steps, but
// will be displayed when you click the "Finish". Finish will not add any buttons
// because you shouldn't be able to navigate wizard back without restarting it.
// Only one finish can be added.
$wizard->addFinish(static function (Wizard $wizard) {
    Header::addTo($wizard, ['You are DONE', 'class.huge centered' => true]);
});
