<?php

namespace App\Packages\Phone\Service;

use App\Packages\User\Models\User;
use App\Packages\User\Repository\UserRepository;
use App\Packages\User\Transformer\UserTransformer;
use Illuminate\Support\Collection;
use libphonenumber\PhoneNumber;

/**
 * Class ContactSyncService
 * @package App\Packages\User\Transformer
 */
class ContactSyncService
{
    /** @var PhoneParseService */
    private $phoneParseService;

    public function __construct(PhoneParseService $phoneParseService)
    {
        $this->phoneParseService = $phoneParseService;
    }

    /**
     * @param $contactsToSync
     * @param User $watcherUser
     *
     * @return array
     */
    public function parseContactNumbers($contactsToSync, User $watcherUser)
    {
        $phoneTempStorage = [];
        foreach ($contactsToSync as $contact) {

            $swissNumberProto = $this->phoneParseService->parseNumber($contact['phone_full'], $watcherUser->phone_code);
            if ($swissNumberProto instanceof PhoneNumber) {

                $hash = phoneHash($swissNumberProto->getCountryCode(), $swissNumberProto->getNationalNumber());
                $phoneTempStorage[] = [
                    'phone_code' => $swissNumberProto->getCountryCode(),
                    'phone_number' => $swissNumberProto->getNationalNumber(),
                    'phone_hash' => $hash,
                    'name' => $contact['full_name'],
                ];
            } else {
                $hash = md5($contact['phone_full']);
                $phoneTempStorage[] = [
                    'phone_code' => $watcherUser->phone_code,
                    'phone_number' => $contact['phone_full'],
                    'phone_hash' => $hash,
                    'name' => $contact['full_name'],
                ];
            }
        }

        return $phoneTempStorage;
    }

    /**
     * @param $contactsToSync
     * @param User $watcherUser
     *
     * @return array
     */
    public function getSyncedContactUsers($contactsToSync, User $watcherUser)
    {
        $phoneTempStorage = $this->parseContactNumbers($contactsToSync, $watcherUser);

        $phoneHashes = array_pluck($phoneTempStorage, 'phone_hash');
        $databaseContacts = $this->getContactSyncList($watcherUser, $phoneHashes);
        $databaseContacts = $databaseContacts->mapWithKeys(function($contact) {
            return [$contact->phone_hash => $contact];
        });

        $list = [];
        foreach ($phoneTempStorage as $contactFromStorage) {

            $phoneHash = $contactFromStorage['phone_hash'];

            if (isset($databaseContacts[$phoneHash])) {
                $list[] = UserTransformer::objectContactFlyUserList(
                    $databaseContacts[$phoneHash], $contactFromStorage
                );
            } else {
                $list[] = UserTransformer::objectDummyUser($phoneHash, $contactFromStorage);
            }
        }

        return $list;
    }

    /**
     * @param User $listOwner
     * @param array $phoneHashList
     *
     * @return Collection
     */
    public function getContactSyncList(User $listOwner, $phoneHashList)
    {
        $contacts = UserRepository::init()->getContactsSyncOnTheFly($listOwner, $phoneHashList);

        return $contacts;
    }
}