<?php

namespace BitApps\PiPro\src\Integrations\Discord;

use BitApps\Pi\Helpers\Utility;

if (!\defined('ABSPATH')) {
    exit;
}

final class DiscordMemberService
{
    private $http;

    private $baseUrl;

    public function __construct($httpClient, $baseUrl)
    {
        $this->http = $httpClient;
        $this->baseUrl = $baseUrl;
    }

    public function getMembers($guildId, $limit)
    {
        $response = $this->http->request(
            $this->baseUrl . "/guilds/{$guildId}/members?limit={$limit}",
            'GET',
            []
        );

        $payload = ['guild_id' => $guildId, 'limit' => $limit];

        $responseCode = $this->http->getResponseCode();
        $success = $responseCode >= 200 && $responseCode < 300;

        return Utility::formatResponseData(
            $responseCode,
            $payload,
            $response,
            $success ? 'Members fetched successfully' : $response->message
        );
    }

    public function addRoleToMember($guildId, $userId, $roleId)
    {
        $response = $this->http->request(
            $this->baseUrl . "/guilds/{$guildId}/members/{$userId}/roles/{$roleId}",
            'PUT',
            []
        );

        $payload = ['guild_id' => $guildId, 'user_id' => $userId, 'role_id' => $roleId];

        $responseCode = $this->http->getResponseCode();
        $success = $responseCode >= 200 && $responseCode < 300;

        return Utility::formatResponseData(
            $responseCode,
            $payload,
            $response,
            $success ? 'Role removed successfully' : $response->message
        );
    }

    public function removeRoleFromMember($guildId, $userId, $roleId)
    {
        $response = $this->http->request(
            $this->baseUrl . "/guilds/{$guildId}/members/{$userId}/roles/{$roleId}",
            'DELETE',
            []
        );

        $payload = ['guild_id' => $guildId, 'user_id' => $userId, 'role_id' => $roleId];

        $responseCode = $this->http->getResponseCode();
        $success = $responseCode >= 200 && $responseCode < 300;

        return Utility::formatResponseData(
            $responseCode,
            $payload,
            $response,
            $success ? 'Role added successfully' : $response->message
        );
    }

    public function findUser($guildId, $searchQuery)
    {
        $members = $this->http->request(
            $this->baseUrl . "/guilds/{$guildId}/members?limit=1000",
            'GET',
            []
        );

        $responseCode = $this->http->getResponseCode();
        $success = $responseCode >= 200 && $responseCode < 300;

        $searchQueryData = \is_string($searchQuery) ? json_decode($searchQuery, true) : $searchQuery;
        $payload = ['guild_id' => $guildId, 'search_query' => $searchQuery];
        if (\is_array($searchQueryData)) {
            $payload = array_merge($payload, $searchQueryData);
        }

        // Handle API error responses
        if (!\is_array($members)) {
            $errorMessage = (\is_object($members) && isset($members->message)) ? $members->message : 'Failed to fetch members';

            return Utility::formatResponseData($responseCode, $payload, [], $errorMessage);
        }

        $searchValue = \is_array($searchQueryData)
            ? ($searchQueryData['username'] ?? $searchQueryData['id'] ?? '')
            : $searchQuery;

        $results = array_filter(
            $members,
            function ($member) use ($searchValue) {
                $memberArray = \is_object($member) ? (array) $member : $member;

                if (!isset($memberArray['user'])) {
                    return false;
                }

                $user = \is_object($memberArray['user']) ? (array) $memberArray['user'] : $memberArray['user'];
                $matchesUsername = isset($user['username']) && stripos($user['username'], $searchValue) !== false;
                $matchesId = isset($user['id']) && $user['id'] === $searchValue;

                return $matchesUsername || $matchesId;
            }
        );

        $message = $success ? 'User search completed successfully' : 'Search completed with warnings';

        return Utility::formatResponseData($responseCode, $payload, array_values($results), $message);
    }
}
