<?php

namespace App\Services\Meet;

use App\Models\ContactGroup;
use App\Models\Member;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;

class ContactService
{
    /**
     * @return Collection<int, array<string, mixed>>
     */
    public function searchOrgMembers(int $organizationId, string $ownerRef, string $query = '', int $limit = 20): Collection
    {
        $members = Member::owned($ownerRef)
            ->where('organization_id', $organizationId)
            ->when($query !== '', function ($q) use ($query) {
                $q->whereIn('user_ref', User::query()
                    ->where(function ($u) use ($query) {
                        $u->where('name', 'like', "%{$query}%")
                            ->orWhere('email', 'like', "%{$query}%");
                    })
                    ->pluck('public_id'));
            })
            ->limit($limit)
            ->get();

        return $members->map(function (Member $member) {
            $user = User::where('public_id', $member->user_ref)->first();

            return [
                'user_ref' => $member->user_ref,
                'email' => $user?->email,
                'name' => $user?->name ?? $member->user_ref,
                'role' => $member->role,
                'source' => 'org',
            ];
        })->filter(fn ($c) => filled($c['email']));
    }

    /**
     * @return Collection<int, array<string, mixed>>
     */
    public function search(int $organizationId, string $ownerRef, string $query = '', int $limit = 20): Collection
    {
        $org = $this->searchOrgMembers($organizationId, $ownerRef, $query, $limit);

        if ($org->count() >= $limit) {
            return $org;
        }

        $platform = $this->searchPlatformContacts($query, $limit - $org->count());
        $emails = $org->pluck('email')->filter()->all();

        return $org->merge($platform->reject(fn ($c) => in_array($c['email'], $emails, true)))->take($limit);
    }

    /**
     * @return Collection<int, array<string, mixed>>
     */
    public function fromGroup(ContactGroup $group): Collection
    {
        return $group->members->map(fn ($m) => [
            'email' => $m->email,
            'name' => $m->display_name,
            'user_ref' => $m->user_ref,
            'source' => 'group',
        ])->filter(fn ($c) => filled($c['email']));
    }

    /**
     * @return Collection<int, array<string, mixed>>
     */
    protected function searchPlatformContacts(string $query, int $limit): Collection
    {
        $url = rtrim((string) config('identity.api_url'), '/');
        $key = config('identity.api_key');

        if ($url === '' || $key === '' || $query === '') {
            return collect();
        }

        try {
            $response = Http::withToken($key)
                ->timeout(5)
                ->get("{$url}/team/search", ['q' => $query, 'limit' => $limit]);

            if (! $response->successful()) {
                return collect();
            }

            return collect($response->json('contacts', []))->map(fn ($c) => [
                'user_ref' => $c['public_id'] ?? null,
                'email' => $c['email'] ?? null,
                'name' => $c['name'] ?? null,
                'source' => 'platform',
            ])->filter(fn ($c) => filled($c['email']));
        } catch (\Throwable) {
            return collect();
        }
    }
}
