<?php

namespace EasyLinkAutomations\Auth\Platforms;

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

use EasyLinkAutomations\Auth\AuthType;
use EasyLinkAutomations\Auth\Contracts\OAuth2PlatformAuthInterface;

/**
 * Slack OAuth2 authentication.
 *
 * Supports full OAuth2 Authorization Code flow. The access token is sent
 * as a Bearer token in the Authorization header.
 */
final class SlackAuth implements OAuth2PlatformAuthInterface
{
    public static function getSlug(): string
    {
        return 'slack';
    }

    public static function getName(): string
    {
        return 'Slack';
    }

    public static function getAuthType(): string
    {
        return AuthType::OAUTH2;
    }

    public static function getFields(): array
    {
        return [
            'client_id' => [
                'label'       => 'Client ID',
                'type'        => 'text',
                'required'    => true,
                'placeholder' => 'Your Slack App Client ID',
            ],
            'client_secret' => [
                'label'       => 'Client Secret',
                'type'        => 'text',
                'password'    => true,
                'required'    => true,
                'placeholder' => 'Your Slack App Client Secret',
            ],
        ];
    }

    public static function getOAuth2Config(): array
    {
        // Bot token scopes — used for bot-level API calls
        // Note: search:read and users.profile:write are user-only scopes
        $botScopes = implode(' ', [
            'channels:history',
            'channels:manage',
            'channels:read',
            'chat:write',
            'files:read',
            'files:write',
            'groups:history',
            'groups:read',
            'im:history',
            'im:read',
            'mpim:history',
            'mpim:read',
            'reactions:read',
            'reactions:write',
            'usergroups:read',
            'usergroups:write',
            'users:read',
            'users.profile:read',
        ]);

        // User token scopes — for actions that require user-level access
        // (e.g. users.profile:write is only available as a user scope)
        $userScopes = implode(' ', [
            'channels:read',
            'channels:write',
            'channels:history',
            'chat:write',
            'files:read',
            'files:write',
            'groups:read',
            'groups:history',
            'im:read',
            'im:history',
            'mpim:read',
            'mpim:history',
            'reactions:read',
            'reactions:write',
            'stars:read',
            'stars:write',
            'usergroups:write',
            'usergroups:read',
            'users.profile:read',
            'users.profile:write',
            'users:read',
            'search:read',
        ]);

        return [
            'auth_url'    => 'https://slack.com/oauth/v2/authorize',
            'token_url'   => 'https://slack.com/api/oauth.v2.access',
            'scope'       => $botScopes,
            'auth_params' => [
                'user_scope' => $userScopes,
            ],
        ];
    }

    public static function getTestRequest(): ?array
    {
        return [
            'url'    => 'https://slack.com/api/auth.test',
            'method' => 'POST',
        ];
    }

    public static function authenticate(array $credentials): array
    {
        $token = $credentials['access_token'] ?? '';

        return ['Authorization' => 'Bearer ' . $token];
    }

    public static function toArray(): array
    {
        return [
            'slug'         => static::getSlug(),
            'name'         => static::getName(),
            'auth_type'    => static::getAuthType(),
            'fields'       => static::getFields(),
            'oauth2_config' => static::getOAuth2Config(),
        ];
    }
}
