<?php

/**
 * @package     Dotclear
 *
 * @copyright   Olivier Meunier & Association Dotclear
 * @copyright   AGPL-3.0
 */
declare(strict_types=1);

namespace Dotclear\Plugin\pings;

use Dotclear\App;
use Dotclear\Helper\Html\Form\Button;
use Dotclear\Helper\Html\Form\Checkbox;
use Dotclear\Helper\Html\Form\Form;
use Dotclear\Helper\Html\Form\Img;
use Dotclear\Helper\Html\Form\Input;
use Dotclear\Helper\Html\Form\Label;
use Dotclear\Helper\Html\Form\Link;
use Dotclear\Helper\Html\Form\None;
use Dotclear\Helper\Html\Form\Note;
use Dotclear\Helper\Html\Form\Para;
use Dotclear\Helper\Html\Form\Set;
use Dotclear\Helper\Html\Form\Submit;
use Dotclear\Helper\Html\Form\Table;
use Dotclear\Helper\Html\Form\Tbody;
use Dotclear\Helper\Html\Form\Td;
use Dotclear\Helper\Html\Form\Text;
use Dotclear\Helper\Html\Form\Th;
use Dotclear\Helper\Html\Form\Thead;
use Dotclear\Helper\Html\Form\Tr;
use Dotclear\Helper\Html\Form\Url;
use Dotclear\Helper\Html\Html;
use Dotclear\Helper\Process\TraitProcess;
use Exception;

/**
 * @brief   The module backend manage process.
 * @ingroup pings
 */
class Manage
{
    use TraitProcess;

    // Local properties

    /**
     * List of ping URIs
     *
     * @var array<string, string> $pings_uris[name => uri]
     */
    private static array $pings_uris;

    public static function init(): bool
    {
        return self::status(My::checkContext(My::MANAGE));
    }

    public static function process(): bool
    {
        if (!self::status()) {
            return false;
        }

        // Pings URIs are managed globally (for all blogs)
        $pings_uris       = My::settings()->getGlobal('pings_uris');
        self::$pings_uris = [];
        if (is_array($pings_uris)) {
            foreach ($pings_uris as $name => $uri) {
                $name = is_string($name) ? $name : '';
                $uri  = is_string($uri) ? $uri : '';
                if ($name !== '' && $uri !== '') {
                    self::$pings_uris[$name] = $uri;
                }
            }
        }

        try {
            if (isset($_POST['pings_srv_name'])) {
                $pings_srv_name = is_array($_POST['pings_srv_name']) ? $_POST['pings_srv_name'] : [];
                $pings_srv_uri  = is_array($_POST['pings_srv_uri']) ? $_POST['pings_srv_uri'] : [];

                self::$pings_uris = [];

                foreach ($pings_srv_name as $index => $name) {
                    $index = is_numeric($index) ? (int) $index : -1;

                    $name = is_string($name) ? trim($name) : '';
                    $uri  = isset($pings_srv_uri[$index]) && is_string($uri = $pings_srv_uri[$index]) ? trim($uri) : '';

                    if ($name !== '' && $uri !== '') {
                        self::$pings_uris[$name] = $uri;
                    }
                }

                // Settings for all blogs
                My::settings()->put('pings_active', !empty($_POST['pings_active']), App::blogWorkspace()::NS_BOOL, global: true);
                My::settings()->put('pings_uris', self::$pings_uris, App::blogWorkspace()::NS_ARRAY, global: true);
                // Settings for current blog only
                My::settings()->put('pings_auto', !empty($_POST['pings_auto']), App::blogWorkspace()::NS_BOOL);

                App::backend()->notices()->addSuccessNotice(__('Settings have been successfully updated.'));
                My::redirect();
            }
        } catch (Exception $exception) {
            App::error()->add($exception->getMessage());
        }

        return true;
    }

    public static function render(): void
    {
        App::backend()->page()->openModule(My::name());

        echo
        App::backend()->page()->breadcrumb(
            [
                __('Plugins')             => '',
                __('Pings configuration') => '',
            ]
        );

        $rows  = [];
        $index = 0;
        foreach (self::$pings_uris as $name => $uri) {
            if (!empty($_GET['test'])) {
                try {
                    PingsAPI::doPings($uri, 'Example site', 'http://example.com');
                    $status = (new Img('images/check-on.svg'))->class(['mark', 'mark-check-on'])->alt('OK');
                } catch (Exception $e) {
                    $status = (new Set())
                        ->items([
                            (new Img('images/check-off.svg'))->class(['mark', 'mark-check-off'])->alt(__('Error')),
                            (new Text(null, ' ' . $e->getMessage())),
                        ]);
                }
            } else {
                $status = new None();
            }

            $rows[] = (new Tr())
                ->class('line')
                ->cols([
                    (new Td())
                        ->items([
                            (new Input(['pings_srv_name[]', 'pings_srv_name-' . $index]))
                                ->size(20)
                                ->maxlength(128)
                                ->value(Html::escapeHTML($name)),
                        ]),
                    (new Td())
                        ->items([
                            (new Url(['pings_srv_uri[]', 'pings_srv_uri-' . $index]))
                                ->size(40)
                                ->value(Html::escapeHTML($uri)),
                        ]),
                    (new Td())
                        ->items([$status]),
                ]);

            $index++;
        }

        $rows[] = (new Tr())
            ->class('line')
            ->cols([
                (new Td())
                    ->items([
                        (new Input(['pings_srv_name[]', 'pings_srv_name2']))
                            ->size(20)
                            ->maxlength(128),
                    ]),
                (new Td())
                    ->items([
                        (new Url(['pings_srv_uri[]', 'pings_srv_uri2']))
                            ->size(40),
                    ]),
                (new Td()),
            ]);

        $table = (new Table())
            ->thead((new Thead())
                ->rows([
                    (new Tr())->cols([
                        (new Th())->text(__('Service name:'))->class('minimal'),
                        (new Th())->text(__('Service URI:'))->class('minimal'),
                        (new Th())->text(empty($_GET['test']) ? '' : __('Status:')),
                    ]),
                ]))
            ->tbody((new Tbody())
                ->rows($rows));

        echo (new Form('pings-form'))
            ->method('post')
            ->action(App::backend()->getPageURL())
            ->fields([
                (new Para())
                    ->items([
                        (new Checkbox('pings_active', My::settings()->getBool('pings_active', false)))
                            ->value(1)
                            ->label(new Label(__('Activate pings extension'), Label::IL_FT)),
                    ]),
                (new Para())
                    ->items([
                        (new Checkbox('pings_auto', My::settings()->getBool('pings_auto', false)))
                            ->value(1)
                            ->label(new Label(__('Auto pings all services on first publication of entry (current blog only)'), Label::IL_FT)),
                    ]),
                (new Para())
                    ->items([
                        (new Link('test'))
                            ->class('button')
                            ->href(App::backend()->getPageURL() . '&amp;test=1')
                            ->text(__('Test ping services')),
                    ]),
                $table,
                (new Note())
                    ->class('form-note')
                    ->text(__('Empty one or both fields from a line to delete it.')),
                (new Para())
                    ->class('form-buttons')
                    ->items([
                        ...My::hiddenFields(),
                        (new Submit(['save'], __('Save'))),
                        (new Button(['back'], __('Back')))
                            ->class(['go-back', 'reset', 'hidden-if-no-js']),
                    ]),
            ])
        ->render();

        App::backend()->page()->helpBlock(My::id());

        App::backend()->page()->closeModule();
    }
}
