<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Export;

use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatableInterface;

/**
 * Interface for filters.
 *
 * Filter will filter result on the query initiated by Export. Most of the time,
 * it will add a `WHERE` clause on this query.
 *
 * Filters should not add column in `SELECT` clause.
 *
 * @template D of array
 */
interface FilterInterface extends ModifierInterface
{
    public const STRING_FORMAT = 'string';

    /**
     * Add a form to collect data from the user.
     */
    public function buildForm(FormBuilderInterface $builder): void;

    /**
     * Get the default data, that can be use as "data" for the form.
     *
     * In case of adding new parameters to a filter, you can implement a @see{DataTransformerFilterInterface} to
     * transforme the filters's data saved in an export to the desired state.
     *
     * @return D
     */
    public function getFormDefaultData(): array;

    /**
     * @param D $formData
     */
    public function normalizeFormData(array $formData): array;

    /**
     * @return D
     */
    public function denormalizeFormData(array $formData, int $fromVersion): array;

    public function getNormalizationVersion(): int;

    /**
     * Describe the filtering action.
     *
     * The description will be inserted in report to remains to the user the
     * filters applyied on this report.
     *
     * Should return a statement about the filtering action, like :
     * "filtering by date: from xxxx-xx-xx to xxxx-xx-xx" or
     * "filtering by nationality: only Germany, France"
     *
     * The format will be determined by the $format. Currently, only 'string' is
     * supported, later some 'html' will be added. The filter should always
     * implement the 'string' format and fallback to it if other format are used.
     *
     * If no i18n is necessary, or if the filter translate the string by himself,
     * this function should return a string. If the filter does not do any translation,
     * the return parameter should be an array, where
     *
     * - the first element is the string,
     * - and the second an array of parameters (may be an empty array)
     * - the 3rd the domain (optional)
     * - the 4th the locale (optional)
     *
     * Example: `array('my string with %parameter%', ['%parameter%' => 'good news'], 'mydomain', 'mylocale')`
     *
     * @param D $data
     *
     * @return array|string|TranslatableInterface a string with the data or, if translatable, an array where first element is string, second elements is an array of arguments
     */
    public function describeAction(array $data, ExportGenerationContext $context): array|string|TranslatableInterface;
}
