<?php
/**
 * The withdrawal request record type.
 *
 * @package SkyServers\Retragere
 */

declare(strict_types=1);

namespace SkyServers\Retragere\Wp;

use WP_Query;

/**
 * Private post type with its own admin screens. Never public facing: the
 * records hold personal data and are evidence, not content.
 */
final class PostType
{
    public const NAME = 'ss_retragere';

    public const STATUS_NOUA       = 'ss_noua';
    public const STATUS_APROBATA   = 'ss_aprobata';
    public const STATUS_RESPINSA   = 'ss_respinsa';
    public const STATUS_RAMBURSATA = 'ss_rambursata';

    public static function register(): void
    {
        register_post_type(
            self::NAME,
            [
                'labels'              => [
                    'name'          => __('Contract withdrawals', 'skyservers-retragere-contract'),
                    'singular_name' => __('Withdrawal request', 'skyservers-retragere-contract'),
                    'menu_name'     => __('Withdrawals', 'skyservers-retragere-contract'),
                ],
                'public'              => false,
                'show_ui'             => true,
                'show_in_menu'        => true,
                'show_in_rest'        => false,
                'menu_icon'           => 'dashicons-undo',
                'menu_position'       => 56,
                'supports'            => ['title'],
                'capability_type'     => 'post',
                'capabilities'        => [
                    'create_posts' => 'do_not_allow',
                ],
                'map_meta_cap'        => true,
                'has_archive'         => false,
                'rewrite'             => false,
                'exclude_from_search' => true,
                'delete_with_user'    => false,
            ]
        );

        foreach (self::statusLabels() as $status => $label) {
            register_post_status(
                $status,
                [
                    'label'                     => $label,
                    'public'                    => false,
                    'internal'                  => false,
                    'exclude_from_search'       => true,
                    'show_in_admin_all_list'    => true,
                    'show_in_admin_status_list' => true,
                    'label_count'               => self::statusCountLabels()[$status],
                ]
            );
        }
    }

    /**
     * The "all" view builds its status list from public and private statuses.
     * Ours are neither, so without this the list stays empty while the counter
     * above it reports the real number.
     *
     * @param mixed $query
     */
    public static function filterAdminQuery($query): void
    {
        if (!is_admin() || !$query instanceof WP_Query || !$query->is_main_query()) {
            return;
        }

        if (self::NAME !== $query->get('post_type')) {
            return;
        }

        $requested = $query->get('post_status');

        if ('' === $requested || 'all' === $requested || [] === $requested) {
            $query->set('post_status', array_keys(self::statusLabels()));
        }
    }

    /**
     * @return array<string,string>
     */
    /**
     * Counts for the filter row above the list.
     *
     * Spelled out per status rather than assembled from statusLabels(): the
     * string extractor cannot follow a concatenation, so a built-up label ships
     * untranslatable no matter how the pieces were translated.
     *
     * @return array<string,array<string,mixed>>
     */
    private static function statusCountLabels(): array
    {
        return [
            /* translators: %s: number of requests in this state. */
            self::STATUS_NOUA       => _n_noop(
                'New <span class="count">(%s)</span>',
                'New <span class="count">(%s)</span>',
                'skyservers-retragere-contract'
            ),
            /* translators: %s: number of requests in this state. */
            self::STATUS_APROBATA   => _n_noop(
                'Approved <span class="count">(%s)</span>',
                'Approved <span class="count">(%s)</span>',
                'skyservers-retragere-contract'
            ),
            /* translators: %s: number of requests in this state. */
            self::STATUS_RESPINSA   => _n_noop(
                'Refused <span class="count">(%s)</span>',
                'Refused <span class="count">(%s)</span>',
                'skyservers-retragere-contract'
            ),
            /* translators: %s: number of requests in this state. */
            self::STATUS_RAMBURSATA => _n_noop(
                'Refunded <span class="count">(%s)</span>',
                'Refunded <span class="count">(%s)</span>',
                'skyservers-retragere-contract'
            ),
        ];
    }

    public static function statusLabels(): array
    {
        return [
            self::STATUS_NOUA       => __('New', 'skyservers-retragere-contract'),
            self::STATUS_APROBATA   => __('Approved', 'skyservers-retragere-contract'),
            self::STATUS_RESPINSA   => __('Refused', 'skyservers-retragere-contract'),
            self::STATUS_RAMBURSATA => __('Refunded', 'skyservers-retragere-contract'),
        ];
    }
}
