<?php

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

namespace Dotclear\Core\Backend\Filter;

use Dotclear\App;
use Dotclear\Helper\Html\Form\Optgroup;
use Dotclear\Helper\Html\Form\Option;
use Dotclear\Helper\Stack\Filter;

/**
 * @brief   Admin list generic filters library.
 *
 * @since   2.20
 */
class FiltersLibrary
{
    /**
     * Common default input field.
     *
     * @param   string      $id     The filter ID
     * @param   string      $title  The filter title
     * @param   ?string     $param  The param ID
     *
     * @return  Filter  The Filter instance
     */
    public static function getInputFilter(string $id, string $title, ?string $param = null): Filter
    {
        return (new Filter($id))
            ->param($param ?: $id)
            ->form('input')
            ->title($title);
    }

    /**
     * Common default select field.
     *
     * @param   string                                                      $id         The filter ID
     * @param   string                                                      $title      The filter title
     * @param   array<string, string>|array<array-key, Optgroup|Option>     $options    The filter options (select)
     * @param   ?string                                                     $param      The param ID
     *
     * @return  ?Filter  The Filter instance if possible
     */
    public static function getSelectFilter(string $id, string $title, array $options, ?string $param = null): ?Filter
    {
        if ($options === []) {
            return null;
        }

        return (new Filter($id))
            ->param($param ?: $id)
            ->title($title)
            ->options($options);
    }

    /**
     * Common page filter (no field).
     *
     * @param   string  $id     The filter ID
     *
     * @return  Filter  The Filter instance
     */
    public static function getPageFilter(string $id = 'page'): Filter
    {
        return (new Filter($id))
            ->value(empty($_GET[$id]) || !is_numeric($_GET[$id]) ? 1 : max(1, (int) $_GET[$id]))
            ->param('limit', fn ($f): array => is_array($f)
                && isset($f[0])
                && is_numeric($f[0])
                && isset($f['nb'])
                && is_numeric($f['nb']) ? [(((int) $f[0] - 1) * (int) $f['nb']), (int) $f['nb']] : []);
    }

    /**
     * Common search field.
     *
     * @return  Filter  The Filter instance
     */
    public static function getSearchFilter(): Filter
    {
        return (new Filter('q'))
            ->param('q', fn ($f): string => is_array($f) && isset($f['q']) && is_string($f['q']) ? $f['q'] : '')
            ->form('input')
            ->title(__('Search:'))
            ->prime(true);
    }

    /**
     * Current blog filter (no field).
     *
     * This forces sql request to have where clause with current blog id.
     * Use your_filters->remove('current_blog')  to remove limitation.
     *
     * @param   string  $id     The filter ID
     *
     * @return  Filter  The Filter instance
     */
    public static function getCurrentBlogFilter(string $id = 'current_blog'): Filter
    {
        return (new Filter($id))
            ->value(App::db()->con()->escapeStr(App::blog()->id()))
            ->param('where', fn ($f): string => " AND P.blog_id = '" . App::db()->con()->escapeStr(App::blog()->id()) . "' ");
    }
}
