<?php

declare(strict_types=1);

namespace Inpsyde\MultilingualPress\MediaLibrary\Settings;

use Inpsyde\MultilingualPress\Framework\Language\Language;

class RelatedSitesSetting implements MediaLibrarySetting
{
    public const FILTER_NAME_RENDER_TYPE = 'multilingualpress.MediaLibrary.related_site_setting_render_type';
    public const RENDER_TYPE_SELECT = 'select';
    public const RENDER_TYPE_CHECKBOX = 'checkbox';
    public const AVAILABLE_RENDER_TYPES = [self::RENDER_TYPE_SELECT, self::RENDER_TYPE_CHECKBOX];

    /**
     * @var string
     */
    protected $key;

    /**
     * @var string
     */
    protected $label;

    /**
     * @var array<int, Language>
     */
    protected $relatedSites;

    public function __construct(string $key, string $label, array $relatedSites)
    {
        $this->key = $key;
        $this->label = $label;
        $this->relatedSites = $relatedSites;
    }

    /**
     * @inheritDoc
     */
    public function key(): string
    {
        return $this->key;
    }

    /**
     * @inheritDoc
     */
    public function label(): string
    {
        return $this->label;
    }

    /**
     * @inheritDoc
     */
    public function render(array $args = []): void
    {
        $name = $args['name'] ?? $this->key();
        $renderType = $this->configureRenderType($args['render_type'] ?? '');
        $includeEmpty = $args['include_empty'] ?? false;
        $includeAll = $args['include_all'] ?? false;
        $description = $args['description'] ?? '';

        $renderType === self::RENDER_TYPE_SELECT
            ? $this->renderSelect($name, $includeEmpty, $includeAll, $description)
            : $this->renderCheckboxes($name);
    }

    /**
     * Configures the render type.
     *
     * @param string $renderType The render type.
     * @return string The configured render type('select' | 'checkbox').
     */
    protected function configureRenderType(string $renderType): string
    {
        if (in_array($renderType, self::AVAILABLE_RENDER_TYPES, true)) {
            return $renderType;
        }

        $renderType = count($this->relatedSites) > 10 ? self::RENDER_TYPE_SELECT : self::RENDER_TYPE_CHECKBOX;
        $renderType = apply_filters(self::FILTER_NAME_RENDER_TYPE, $renderType, self::AVAILABLE_RENDER_TYPES);

        return in_array($renderType, self::AVAILABLE_RENDER_TYPES, true) ? $renderType : self::RENDER_TYPE_CHECKBOX;
    }

    /**
     * Renders the checkboxes by given name.
     *
     * @param string $name The name.
     * @return void
     */
    protected function renderCheckboxes(string $name): void
    {
        ?>
        <p class="mlp-relationships-bulk-selection">
            <a class="mlp-site-bulk-relations" data-action="select" href="#">
                <?php esc_html_e('Select All', 'multilingualpress'); ?>
            </a>
            /
            <a class="mlp-site-bulk-relations" data-action="deselect" href="#">
                <?php esc_html_e('Deselect All', 'multilingualpress'); ?>
            </a>
        </p>
        <div class="mlp-relationships-languages <?= esc_attr($this->key());?>">
            <?php foreach ($this->relatedSites as $siteId => $language) :
                $id = "{$this->key}-{$siteId}";
                ?>
                <p>
                    <label for="<?= esc_attr($id) ?>">
                        <input
                            type="checkbox"
                            name="<?= esc_attr($name);?>[]"
                            value="<?= esc_attr($siteId) ?>"
                            id="<?= esc_attr($id) ?>"
                            >
                        <?= esc_html($language->name()) ?>
                    </label>
                </p>
            <?php endforeach; ?>
        </div>
        <?php
    }

    /**
     * Renders the select by given name.
     *
     * @param string $name The name.
     * @param bool $includeEmpty true if an empty option should be included, otherwise false.
     * @param bool $includeAll true if the "Select All" option should be included, otherwise false.
     * @param string $description The description.
     * @return void
     */
    protected function renderSelect(string $name, bool $includeEmpty, bool $includeAll, string $description): void
    {
        ?>
        <select
            name="<?= esc_attr($name);?>"
            class="<?= esc_attr($this->key());?>"
            >
            <?php if ($includeEmpty) : ?>
                <option value=""><?= esc_html__('Select an Option', 'multilingualpress')?></option>
            <?php endif;?>
            <?php if ($includeAll) : ?>
                <option value="all"><?= esc_html__('Select All', 'multilingualpress')?></option>
            <?php endif;?>
            <?php foreach ($this->relatedSites as $siteId => $language) :?>
                <option value="<?= esc_attr($siteId);?>"><?= esc_html($language->name())?></option>
            <?php endforeach;?>
        </select>
        <?php if ($description) : ?>
            <p><?= esc_html($description);?></p>
        <?php endif;?>
        <?php
    }
}
