<?php

namespace CouponsPlus\App\Handlers;

use CouponsPlus\Original\Events\Handler\EventHandler;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;
use WP_User_Query;

class UsersSearchAPIHandler extends EventHandler
{
    protected $numberOfArguments = 1;
    protected $priority = 10;

    public function execute()
    {
        register_rest_route('coupons-plus/v1', '/users/search', [
            'methods' => WP_REST_Server::READABLE,
            'callback' => [$this, 'search_users'],
            'permission_callback' => [$this, 'check_permissions'],
            'args' => [
                'search' => [
                    'type' => 'string',
                    'required' => true,
                    'sanitize_callback' => 'sanitize_text_field',
                ],
                'per_page' => [
                    'type' => 'integer',
                    'required' => false,
                    'default' => 20,
                ],
            ],
        ]);
    }

    public function search_users(WP_REST_Request $request): WP_REST_Response
    {
        $term = trim((string) $request->get_param('search'));

        if ($term === '') {
            return new WP_REST_Response([], 200);
        }

        $limit = (int) $request->get_param('per_page');
        if ($limit < 1) {
            $limit = 20;
        }
        if ($limit > 50) {
            $limit = 50;
        }

        $wildcardSearch = sprintf('*%s*', $term);
        $queryArgs = [
            'number' => $limit,
            'fields' => ['ID', 'display_name', 'user_nicename', 'user_email'],
        ];

        $byDisplayName = new WP_User_Query(array_merge($queryArgs, [
            'search' => $wildcardSearch,
            'search_columns' => ['display_name'],
        ]));

        $byNickname = new WP_User_Query(array_merge($queryArgs, [
            'meta_query' => [
                [
                    'key' => 'nickname',
                    'value' => $term,
                    'compare' => 'LIKE',
                ],
            ],
        ]));

        $byEmail = new WP_User_Query(array_merge($queryArgs, [
            'search' => $wildcardSearch,
            'search_columns' => ['user_email'],
        ]));

        $resultsById = [];
        foreach ([$byDisplayName, $byNickname, $byEmail] as $query) {
            foreach ((array) $query->get_results() as $user) {
                $resultsById[$user->ID] = $user;
            }
        }

        $mapped = array_values(array_map(function ($user): array {
            $nickname = get_user_meta((int) $user->ID, 'nickname', true);
            $name = (string) $user->display_name;
            $email = (string) $user->user_email;
            $label = sprintf(
                '%s (%s, %s)',
                $name,
                $nickname ?: __('No nickname', 'coupons-plus-for-woocommerce'),
                $email
            );

            return [
                'id' => (int) $user->ID,
                'name' => $name,
                'nickname' => (string) $nickname,
                'email' => $email,
                'label' => $label,
            ];
        }, $resultsById));

        usort($mapped, function (array $left, array $right): int {
            return strcmp($left['name'], $right['name']);
        });

        if (count($mapped) > $limit) {
            $mapped = array_slice($mapped, 0, $limit);
        }

        return new WP_REST_Response($mapped, 200);
    }

    public function check_permissions(): bool
    {
        return is_user_logged_in();
    }
}
