<?php

namespace Fifa\ConnectId\Sdk\Util\ArrayUtils\DuplicatesFilter;

use Fifa\ConnectId\Sdk\Api\Model\HashedNameType;
use Fifa\ConnectId\Sdk\Util\ArrayUtils\ArrayParser;
use Fifa\ConnectId\Sdk\Util\ArrayUtils\DuplicatesFilterInterface;

/**
 * Class HashedNameTypeDuplicatesFilter
 * @package Fifa\ConnectId\Sdk\Util\ArrayUtils\DuplicatesFilter
 */
class HashedNameTypeDuplicatesFilter implements DuplicatesFilterInterface
{
    /**
     * Method filters the duplicates and returns the results as an array
     *
     * @param array $hashedNames
     * @return array
     */
    public function filterDuplicates(array $hashedNames): array
    {
        $filtered = array();
        $hashedNames = ArrayParser::create($hashedNames)->checkContainsOnlyInstancesOf(HashedNameType::class)->getData();

        // sort hashes by highest proximity score - then we will save duplicated hash with higher score as their will be added to $filtered first
        usort($hashedNames, function (HashedNameType $h1, HashedNameType $h2) {
            if ($h1->getProximityScore() == $h2->getProximityScore()) {
                return 0;
            }

            return ($h1->getProximityScore() < $h2->getProximityScore()) ? 1 : -1;
        });

        foreach ($hashedNames as $hashedNameType) {
            if (!$this->containsHash($filtered, $hashedNameType)) {
                $filtered[] = $hashedNameType;
            }
        }

        return $filtered;
    }

    /**
     * @param HashedNameType[] $hashedNames
     * @param HashedNameType $hashedNameType
     * @return bool
     */
    private function containsHash(array $hashedNames, HashedNameType $hashedNameType): bool
    {
        foreach ($hashedNames as $hashedName) {
            if ($hashedName->getHash() == $hashedNameType->getHash()) {
                return true;
            }
        }

        return false;
    }
}