<?php

namespace App\Monitor\Service;

use Aimeos\Map;
use App\Monitor\Framework\Entity\Monitor;
use App\Torrentio\Result\TorrentioResult;

class MonitorOptionEvaluator
{
    /**
     * @param Monitor $monitor
     * @param TorrentioResult[] $results
     * @return TorrentioResult|null
     * @throws \Throwable
     */
    public function evaluateOptions(Monitor $monitor, array $results): ?TorrentioResult
    {
        $sizeLow = 000;
        $sizeHigh = 4096;

        $bestMatches = [];
        $matches = [];

        $userPreferences = $monitor->getUser()->getUserPreferenceValues();

        foreach ($results as $result) {
            if (!in_array($userPreferences['language'], $result->languages)) {
                continue;
            }

            if ($result->resolution === $userPreferences['resolution']
                && $result->codec === $userPreferences['codec']
            ) {
                $bestMatches[] = $result;
            }

            if ($userPreferences['resolution'] === '2160p'
                && $userPreferences['codec'] === $result->codec
                && $result->resolution === '1080p'
            ) {
                $matches[] = $result;
            }

            if ($userPreferences['codec'] === 'h264'
                && $userPreferences['resolution'] === $result->resolution
                && $result->codec === 'h265'
            ) {
                $matches[] = $result;
            }

            if (($userPreferences['codec'] === null )
                && ($userPreferences['resolution'] === null )) {
                $matches[] = $result;
            }
        }

        $sizeMatches = [];

        foreach ($bestMatches as $result) {
            if (str_contains($result->size, 'GB')) {
                $size = (int) trim(str_replace('GB', '', $result->size)) * 1024;
            } else {
                $size = (int) trim(str_replace('MB', '', $result->size));
            }

            if ($size > $sizeLow && $size < $sizeHigh) {
                $sizeMatches[] = $result;
            }
        }

        if (!empty($sizeMatches)) {
            return Map::from($sizeMatches)->usort(fn($a, $b) => $a->seeders <=> $b->seeders)->last();
        }

        foreach ($matches as $result) {
            $size = 0;
            if (str_contains($result->size, 'GB')) {
                $size = (int) trim(str_replace('GB', '', $result->size)) * 1024;
            } else {
                $size = (int) trim(str_replace('MB', '', $result->size));
            }

            if ($size > $sizeLow && $size < $sizeHigh) {
                $sizeMatches[] = $result;
            }
        }

        if (!empty($sizeMatches)) {
            return Map::from($sizeMatches)->usort(fn($a, $b) => $a->seeders <=> $b->seeders)->last();
        }

        return null;
    }
}
