<?php

namespace App\Services\Identity;

use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
use RuntimeException;

class IdentityTeamClient
{
    /**
     * @param  list<string>  $apps
     * @param  array<string, mixed>  $metadata
     *
     * @return array<string, mixed>
     */
    public function inviteAppMember(
        string $ownerPublicId,
        string $email,
        array $apps,
        array $metadata = [],
        string $role = 'member',
    ): array {
        $response = $this->request('post', '/identity/team/invite', [
            'owner' => $ownerPublicId,
            'email' => strtolower(trim($email)),
            'apps' => $apps,
            'role' => $role,
            'metadata' => $metadata,
        ]);

        return (array) $response->json('data', []);
    }

    /**
     * @return array{url: string, apps: list<string>, full_access: bool, show_hub: bool, show_billing: bool}
     */
    public function appAccess(string $userPublicId, string $intendedUrl = ''): array
    {
        $response = $this->request('get', '/identity/team/post-auth-redirect', array_filter([
            'user' => $userPublicId,
            'redirect' => $intendedUrl !== '' ? $intendedUrl : null,
        ]));

        $data = (array) $response->json('data', []);

        return [
            'url' => (string) ($data['url'] ?? $intendedUrl),
            'apps' => array_values(array_map('strval', (array) ($data['apps'] ?? []))),
            'full_access' => (bool) ($data['full_access'] ?? false),
            'show_hub' => (bool) ($data['show_hub'] ?? ($data['full_access'] ?? false)),
            'show_billing' => (bool) ($data['show_billing'] ?? ($data['full_access'] ?? false)),
        ];
    }

    public function postAuthRedirect(string $userPublicId, string $intendedUrl): string
    {
        return $this->appAccess($userPublicId, $intendedUrl)['url'];
    }

    /** @return list<string> */
    public function mailboxOptions(string $ownerPublicId): array
    {
        $response = $this->request('get', '/identity/team/mailbox-options', [
            'owner' => $ownerPublicId,
        ]);

        return array_values(array_map('strval', (array) $response->json('data', [])));
    }

    /** @return list<array<string, mixed>> */
    public function teamAccess(string $userPublicId): array
    {
        $response = $this->request('get', '/identity/team/access', [
            'user' => $userPublicId,
        ]);

        return (array) $response->json('data', []);
    }

    /**
     * @param  array{subject: string, message: string, priority?: string, tags?: list<string>}  $payload
     * @return array<string, mixed>
     */
    public function createSupportTicket(string $userPublicId, array $payload, string $app = 'care'): array
    {
        $response = $this->request('post', '/identity/support/tickets', array_filter([
            'user' => $userPublicId,
            'subject' => $payload['subject'] ?? '',
            'message' => $payload['message'] ?? '',
            'priority' => $payload['priority'] ?? 'normal',
            'app' => $app,
            'tags' => $payload['tags'] ?? ['staff_issue'],
        ], fn ($value) => $value !== null && $value !== ''));

        return (array) $response->json('data', []);
    }

    private function request(string $method, string $path, array $query = []): Response
    {
        $url = rtrim((string) config('identity.api_url'), '/').$path;
        $key = config('identity.api_key');

        if ($url === '' || ! is_string($key) || $key === '') {
            throw new RuntimeException('Identity API is not configured.');
        }

        $http = Http::withToken($key)->timeout(10);

        $response = $method === 'post'
            ? $http->post($url, $query)
            : $http->{$method}($url, $query);

        if (! $response->successful()) {
            throw new RuntimeException($response->json('message') ?: 'Identity API request failed.');
        }

        return $response;
    }
}
