<?php

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

namespace Dotclear\Plugin\blogroll;

use Dotclear\App;
use Dotclear\Database\MetaRecord;
use Dotclear\Helper\Html\Form\Checkbox;
use Dotclear\Helper\Html\Form\Div;
use Dotclear\Helper\Html\Form\Form;
use Dotclear\Helper\Html\Form\Hidden;
use Dotclear\Helper\Html\Form\Input;
use Dotclear\Helper\Html\Form\Label;
use Dotclear\Helper\Html\Form\Link;
use Dotclear\Helper\Html\Form\Note;
use Dotclear\Helper\Html\Form\Para;
use Dotclear\Helper\Html\Form\Radio;
use Dotclear\Helper\Html\Form\Select;
use Dotclear\Helper\Html\Form\Span;
use Dotclear\Helper\Html\Form\Submit;
use Dotclear\Helper\Html\Form\Table;
use Dotclear\Helper\Html\Form\Td;
use Dotclear\Helper\Html\Form\Text;
use Dotclear\Helper\Html\Form\Th;
use Dotclear\Helper\Html\Form\Tr;
use Dotclear\Helper\Html\Form\Url;
use Dotclear\Helper\Html\Html;
use Dotclear\Helper\Process\TraitProcess;
use Dotclear\Plugin\blogroll\Status\Link as StatusLink;
use Exception;

/**
 * @brief   The module manage blogroll process.
 * @ingroup blogroll
 */
class ManageEdit
{
    use TraitProcess;

    protected static string $id;

    protected static MetaRecord $rs;

    protected static string $link_title;

    protected static string $link_href;

    protected static string $link_desc;

    protected static string $link_lang;

    protected static string $link_xfn;

    protected static int $link_status;

    public static function init(): bool
    {
        self::status(My::checkContext(My::MANAGE) && !empty($_REQUEST['edit']) && !empty($_REQUEST['id']));

        if (self::status()) {
            self::$id = Html::escapeHTML(is_numeric($_REQUEST['id']) ? (string) $_REQUEST['id'] : '0');

            try {
                $blogroll = new Blogroll(App::blog());
                self::$rs = $blogroll->getLink(self::$id);
            } catch (Exception $e) {
                App::error()->add($e->getMessage());
            }

            if (!App::error()->flag() && !self::$rs->isEmpty()) {
                self::$link_title  = self::$rs->strField('link_title');
                self::$link_href   = self::$rs->strField('link_href');
                self::$link_desc   = self::$rs->strField('link_desc');
                self::$link_lang   = self::$rs->strField('link_lang');
                self::$link_xfn    = self::$rs->strField('link_xfn');
                self::$link_status = self::$rs->intField('link_status');
            } else {
                self::$link_title  = '';
                self::$link_href   = '';
                self::$link_desc   = '';
                self::$link_lang   = '';
                self::$link_xfn    = '';
                self::$link_status = StatusLink::ONLINE;
                App::error()->add(__('No such link or title.'));
            }
        }

        return self::status();
    }

    public static function process(): bool
    {
        $blogroll = new Blogroll(App::blog());

        // Ensure ID is numeric-string
        self::$id = is_numeric(self::$id) ? self::$id : '0';

        if (!self::$rs->boolField('is_cat') && !empty($_POST['edit_link'])) {
            // Update a link

            self::$link_title  = is_string($link_title = $_POST['link_title']) ? $link_title : '';
            self::$link_href   = is_string($link_href = $_POST['link_href']) ? $link_href : '';
            self::$link_desc   = is_string($link_desc = $_POST['link_desc']) ? $link_desc : '';
            self::$link_lang   = is_string($link_lang = $_POST['link_lang']) ? $link_lang : '';
            self::$link_status = is_numeric($link_status = $_POST['link_status']) ? (int) $link_status : StatusLink::ONLINE;

            self::$link_xfn = '';

            if (!empty($_POST['identity']) && is_string($_POST['identity'])) {
                self::$link_xfn .= $_POST['identity'];
            } else {
                if (!empty($_POST['friendship']) && is_string($_POST['friendship'])) {
                    self::$link_xfn .= ' ' . $_POST['friendship'];
                }

                if (!empty($_POST['physical'])) {
                    self::$link_xfn .= ' met';
                }

                if (!empty($_POST['professional']) && is_array($_POST['professional'])) {
                    $list = array_filter($_POST['professional'], fn ($value): bool => is_string($value) && $value !== '');
                    self::$link_xfn .= ' ' . implode(' ', $list);
                }

                if (!empty($_POST['geographical']) && is_string($_POST['geographical'])) {
                    self::$link_xfn .= ' ' . $_POST['geographical'];
                }

                if (!empty($_POST['family']) && is_string($_POST['family'])) {
                    self::$link_xfn .= ' ' . $_POST['family'];
                }

                if (!empty($_POST['romantic']) && is_array($_POST['romantic'])) {
                    $list = array_filter($_POST['romantic'], fn ($value): bool => is_string($value) && $value !== '');
                    self::$link_xfn .= ' ' . implode(' ', $list);
                }
            }

            try {
                $blogroll->updateLink(
                    self::$id,
                    self::$link_title,
                    self::$link_href,
                    self::$link_desc,
                    self::$link_lang,
                    trim(self::$link_xfn),
                    self::$link_status,
                );
                App::backend()->notices()->addSuccessNotice(__('Link has been successfully updated.'));
                My::redirect([
                    'edit' => 1,    // Used by Manage
                    'id'   => self::$id,
                ]);
            } catch (Exception $e) {
                App::error()->add($e->getMessage());
            }
        }

        if (self::$rs->boolField('is_cat') && !empty($_POST['edit_cat'])) {
            // Update a category

            self::$link_desc = is_string($link_desc = $_POST['link_desc']) ? $link_desc : '';

            try {
                $blogroll->updateCategory(self::$id, self::$link_desc);
                App::backend()->notices()->addSuccessNotice(__('Category has been successfully updated.'));
                My::redirect([
                    'edit' => 1,    // Used by Manage
                    'id'   => self::$id,
                ]);
            } catch (Exception $e) {
                App::error()->add($e->getMessage());
            }
        }

        return true;
    }

    public static function render(): void
    {
        $blogroll = new Blogroll(App::blog());

        // Languages combo
        $links      = $blogroll->getLangs(['order' => 'asc']);
        $lang_combo = App::backend()->combos()->getLangsCombo($links, true, true);

        $head = App::backend()->page()->jsConfirmClose('blogroll_cat', 'blogroll_link');

        // Status combo
        $status_combo = (new StatusLink())->combo();

        // Ensure ID is numeric-string
        self::$id = is_numeric(self::$id) ? self::$id : '0';

        $is_cat = self::$rs->boolField('is_cat');

        $link_title  = self::$link_title;
        $link_href   = self::$link_href;
        $link_desc   = self::$link_desc;
        $link_lang   = self::$link_lang;
        $link_xfn    = trim(self::$link_xfn);
        $link_status = self::$link_status;

        $img_status = (new StatusLink())->image($link_status)->render();

        $user_lang = is_string($user_lang = App::auth()->getInfo('user_lang')) ? $user_lang : '';

        App::backend()->page()->openModule(My::name(), $head);

        echo
        App::backend()->page()->breadcrumb(
            [
                Html::escapeHTML(App::blog()->name())   => '',
                My::name()                              => App::backend()->getPageURL(),
                ($is_cat ? __('Category') : __('Link')) => '',
            ]
        ) .
        App::backend()->notices()->getNotices();

        echo
            (new Para())->items([
                (new Link())->class('back')->href(App::backend()->getPageURL())->text(__('Return to blogroll')),
            ])
        ->render();

        if ($is_cat) {
            echo (new Form('blogroll_cat'))
                ->class('fieldset')
                ->method('post')
                ->action(App::backend()->getPageURL())
                ->fields([
                    (new Text('h3', __('Edit category'))),
                    (new Note())
                        ->class('form-note')
                        ->text(sprintf(__('Fields preceded by %s are mandatory.'), (new Span('*'))->class('required')->render())),
                    (new Para())->items([
                        (new Input('link_desc'))
                            ->size(30)
                            ->maxlength(255)
                            ->value(Html::escapeHTML($link_desc))
                            ->required(true)
                            ->placeholder(__('Title'))
                            ->lang($user_lang)
                            ->spellcheck(true)
                            ->label(
                                (new Label(
                                    (new Span('*'))->render() . __('Title:'),
                                    Label::INSIDE_TEXT_BEFORE
                                ))
                            )
                            ->title(__('Required field')),
                    ]),
                    (new Para())->class('link-status')->items([
                        (new Select('link_status'))
                        ->items($status_combo)
                        ->default($link_status)
                        ->label(new Label(__('Category status') . ' ' . $img_status, Label::OUTSIDE_LABEL_BEFORE)),
                    ]),
                    (new Para())->items([
                        ...My::hiddenFields(),
                        (new Hidden('edit', '1')),    // Used by Manage
                        (new Hidden('id', self::$id)),
                        (new Submit(['edit_cat'], __('Save'))),
                    ]),
                ])
            ->render();
        } else {
            // Extract xfn items
            $xfn = explode(' ', $link_xfn);

            echo (new Form('blogroll_link'))
                ->class('fieldset')
                ->method('post')
                ->action(App::backend()->getPageURL())
                ->fields([
                    (new Text('h3', __('Edit link'))),
                    (new Note())
                        ->class('form-note')
                        ->text(sprintf(__('Fields preceded by %s are mandatory.'), (new Span('*'))->class('required')->render())),
                    (new Div())->class('two-cols')->items([
                        (new Div())->class('col30')->items([
                            (new Para())->items([
                                (new Label((new Span('*'))->render() . __('Title:'), Label::OUTSIDE_LABEL_BEFORE))
                                    ->class('required')
                                    ->for('link_title'),
                                (new Input('link_title'))
                                    ->size(30)
                                    ->maxlength(255)
                                    ->value(Html::escapeHTML($link_title))
                                    ->required(true)
                                    ->placeholder(__('Title'))
                                    ->lang($user_lang)
                                    ->spellcheck(true)
                                    ->title(__('Required field')),
                            ]),
                            (new Para())->items([
                                (new Label((new Span('*'))->render() . __('URL:'), Label::OUTSIDE_LABEL_BEFORE))
                                    ->class('required')
                                    ->for('link_href'),
                                (new Url('link_href'))
                                    ->size(30)
                                    ->maxlength(255)
                                    ->value(Html::escapeHTML($link_href))
                                    ->required(true)
                                    ->placeholder(__('URL'))
                                    ->title(__('Required field')),
                            ]),
                            (new Para())->items([
                                (new Label(__('Description:'), Label::OUTSIDE_LABEL_BEFORE))
                                    ->for('link_desc'),
                                (new Input('link_desc'))
                                    ->size(30)
                                    ->maxlength(255)
                                    ->value(Html::escapeHTML($link_desc))
                                    ->lang($user_lang)
                                    ->spellcheck(true),
                            ]),
                            (new Para())->items([
                                (new Label(__('Language:'), Label::OUTSIDE_LABEL_BEFORE))
                                    ->for('link_lang'),
                                (new Select('link_lang'))
                                    ->items($lang_combo)
                                    ->default($link_lang),
                            ]),
                            (new Para())->class('link-status')->items([
                                (new Select('link_status'))
                                    ->items($status_combo)
                                    ->default($link_status)
                                    ->label(new Label(__('Link status') . ' ' . $img_status, Label::OUTSIDE_LABEL_BEFORE)),
                            ]),
                        ]),

                        // XFN nightmare
                        (new Div())->class('col70')->items([
                            (new Text('h4', __('XFN information'))),
                            (new Note())
                                ->class('form-note')
                                ->text(sprintf(
                                    __('More information on <a href="%s">Wikipedia</a> website'),
                                    'https://en.wikipedia.org/wiki/XHTML_Friends_Network'
                                )),
                            (new Div())->class('table-outer')->items([
                                (new Table())->class('noborder')->items([
                                    (new Tr())->class('line')->items([
                                        (new Th())->text(__('_xfn_Me'))->scope('row'),
                                        (new Td())->items([
                                            (new Checkbox(['identity'], ($link_xfn === 'me')))
                                                ->value('me')
                                                ->label((new Label(__('_xfn_Another link for myself'), Label::INSIDE_TEXT_AFTER))),
                                        ]),
                                    ]),
                                    (new tr())->class('line')->items([
                                        (new Th())->text(__('_xfn_Friendship'))->scope('row'),
                                        (new Td())->items([
                                            (new Radio(['friendship'], in_array('contact', $xfn)))
                                                ->value('contact')
                                                ->label((new Label(__('_xfn_Contact'), Label::INSIDE_TEXT_AFTER))),
                                            (new Radio(['friendship'], in_array('acquaintance', $xfn)))
                                                ->value('acquaintance')
                                                ->label((new Label(__('_xfn_Acquaintance'), Label::INSIDE_TEXT_AFTER))),
                                            (new Radio(['friendship'], in_array('friend', $xfn)))
                                                ->value('friend')
                                                ->label((new Label(__('_xfn_Friend'), Label::INSIDE_TEXT_AFTER))),
                                            (new Radio(
                                                ['friendship'],
                                                !in_array('contact', $xfn) && !in_array('acquaintance', $xfn) && !in_array('friend', $xfn)
                                            ))
                                                ->value('')
                                                ->label((new Label(__('None'), Label::INSIDE_TEXT_AFTER))),
                                        ]),
                                    ]),
                                    (new Tr())->class('line')->items([
                                        (new Th())->text(__('_xfn_Physical'))->scope('row'),
                                        (new Td())->items([
                                            (new Checkbox(['physical'], in_array('met', $xfn)))
                                                ->value('met')
                                                ->label((new Label(__('_xfn_Met'), Label::INSIDE_TEXT_AFTER))),
                                        ]),
                                    ]),
                                    (new Tr())->class('line')->items([
                                        (new Th())->text(__('_xfn_Professional'))->scope('row'),
                                        (new Td())->items([
                                            (new Checkbox(['professional[]'], in_array('co-worker', $xfn)))
                                                ->value('co-worker')
                                                ->label((new Label(__('_xfn_Co-worker'), Label::INSIDE_TEXT_AFTER))),
                                            (new Checkbox(['professional[]'], in_array('colleague', $xfn)))
                                                ->value('colleague')
                                                ->label((new Label(__('_xfn_Colleague'), Label::INSIDE_TEXT_AFTER))),
                                        ]),
                                    ]),
                                    (new tr())->class('line')->items([
                                        (new Th())->text(__('_xfn_Geographical'))->scope('row'),
                                        (new Td())->items([
                                            (new Radio(['geographical'], in_array('co-resident', $xfn)))
                                                ->value('co-resident')
                                                ->label((new Label(__('_xfn_Co-resident'), Label::INSIDE_TEXT_AFTER))),
                                            (new Radio(['geographical'], in_array('neighbor', $xfn)))
                                                ->value('neighbor')
                                                ->label((new Label(__('_xfn_Neighbor'), Label::INSIDE_TEXT_AFTER))),
                                            (new Radio(
                                                ['geographical'],
                                                !in_array('co-resident', $xfn) && !in_array('neighbor', $xfn)
                                            ))
                                                ->value('')
                                                ->label((new Label(__('None'), Label::INSIDE_TEXT_AFTER))),
                                        ]),
                                    ]),
                                    (new tr())->class('line')->items([
                                        (new Th())->text(__('_xfn_Family'))->scope('row'),
                                        (new Td())->items([
                                            (new Radio(['family'], in_array('child', $xfn)))
                                                ->value('child')
                                                ->label((new Label(__('_xfn_Child'), Label::INSIDE_TEXT_AFTER))),
                                            (new Radio(['family'], in_array('parent', $xfn)))
                                                ->value('parent')
                                                ->label((new Label(__('_xfn_Parent'), Label::INSIDE_TEXT_AFTER))),
                                            (new Radio(['family'], in_array('sibling', $xfn)))
                                                ->value('sibling')
                                                ->label((new Label(__('_xfn_Sibling'), Label::INSIDE_TEXT_AFTER))),
                                            (new Radio(['family'], in_array('spouse', $xfn)))
                                                ->value('spouse')
                                                ->label((new Label(__('_xfn_Spouse'), Label::INSIDE_TEXT_AFTER))),
                                            (new Radio(['family'], in_array('kin', $xfn)))
                                                ->value('kin')
                                                ->label((new Label(__('_xfn_Kin'), Label::INSIDE_TEXT_AFTER))),
                                            (new Radio(
                                                ['family'],
                                                !in_array('child', $xfn) && !in_array('parent', $xfn) && !in_array('sibling', $xfn) && !in_array('spouse', $xfn) && !in_array('kin', $xfn)
                                            ))
                                                ->value('')
                                                ->label((new Label(__('None'), Label::INSIDE_TEXT_AFTER))),
                                        ]),
                                    ]),
                                    (new tr())->class('line')->items([
                                        (new Th())->text(__('_xfn_Romantic'))->scope('row'),
                                        (new Td())->items([
                                            (new Checkbox(['romantic[]'], in_array('muse', $xfn)))
                                                ->value('muse')
                                                ->label((new Label(__('_xfn_Muse'), Label::INSIDE_TEXT_AFTER))),
                                            (new Checkbox(['romantic[]'], in_array('crush', $xfn)))
                                                ->value('crush')
                                                ->label((new Label(__('_xfn_Crush'), Label::INSIDE_TEXT_AFTER))),
                                            (new Checkbox(['romantic[]'], in_array('date', $xfn)))
                                                ->value('date')
                                                ->label((new Label(__('_xfn_Date'), Label::INSIDE_TEXT_AFTER))),
                                            (new Checkbox(['romantic[]'], in_array('sweetheart', $xfn)))
                                                ->value('sweetheart')
                                                ->label((new Label(__('_xfn_Sweetheart'), Label::INSIDE_TEXT_AFTER))),
                                        ]),
                                    ]),
                                ]),
                            ]),
                        ]),
                    ]),
                    (new Para())
                        ->class('form-buttons')
                        ->items([
                            ...My::hiddenFields(),
                            (new Hidden('edit', '1')),    // Used by Manage
                            (new Hidden('id', self::$id)),
                            (new Submit(['edit_link'], __('Save'))),
                        ]),
                ])
            ->render();
        }

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