<?php

declare(strict_types=1);

namespace PhpWA\Client;

use InvalidArgumentException;
use PhpWA\Protocol\Jid\Jid;

final class DeviceDiscoveryResult
{
    /** @var list<string> */ private $devices;
    /** @var array<string,string> */ private $phoneToLid;

    /** @param list<string> $devices @param array<string,string> $phoneToLid */
    public function __construct(array $devices, array $phoneToLid = [])
    {
        if (count($devices) > 10000 || count($phoneToLid) > 10000) {
            throw new InvalidArgumentException('Device discovery result exceeds its limit.');
        }
        $unique = [];
        foreach ($devices as $device) {
            $jid = is_string($device) ? Jid::parse($device) : null;
            if (!$jid instanceof Jid || (!$jid->isPhoneNumber() && !$jid->isLid()
                && !$jid->isHostedPhoneNumber() && !$jid->isHostedLid())) {
                throw new InvalidArgumentException('Device discovery contains an invalid device JID.');
            }
            $unique[(string) $jid] = true;
        }
        $mappings = [];
        foreach ($phoneToLid as $phone => $lid) {
            $phoneJid = is_string($phone) ? Jid::parse($phone) : null;
            $lidJid = is_string($lid) ? Jid::parse($lid) : null;
            if (!$phoneJid instanceof Jid || (!$phoneJid->isPhoneNumber() && !$phoneJid->isHostedPhoneNumber())
                || !$lidJid instanceof Jid || (!$lidJid->isLid() && !$lidJid->isHostedLid())
                || preg_match('/^[1-9][0-9]{0,19}$/D', $phoneJid->user()) !== 1
                || preg_match('/^[1-9][0-9]{0,19}$/D', $lidJid->user()) !== 1
                || $phoneJid->device() !== null || $lidJid->device() !== null) {
                throw new InvalidArgumentException('Device discovery contains an invalid phone-to-LID mapping.');
            }
            $mappings[(string) $phoneJid] = (string) $lidJid;
        }
        $this->devices = array_keys($unique);
        $this->phoneToLid = $mappings;
    }

    /** @return list<string> */ public function devices(): array { return $this->devices; }
    /** @return array<string,string> */ public function phoneToLid(): array { return $this->phoneToLid; }
}
