<?php

namespace App\Service;

use App\Entity\Manga;
use App\Interface\MetadataProviderInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Symfony\Component\String\Slugger\SluggerInterface;

class MangaUpdatesMetadataProvider implements MetadataProviderInterface
{
    private Client $client;

    public function __construct(private readonly SluggerInterface $slugger)
    {
        $this->client = new Client();
    }

    /**
     * @throws Exception
     */
    public function search(string $title): Collection
    {
        try {
            $response = $this->client->request('PUT', 'https://api.mangaupdates.com/v1/account/login', [
                'json' => [
                    'username' => 'Colgora',
                    'password' => '7TK5jv33NDn*SLV',
                ]
            ])
                ->withHeader('Content-Type', 'application/json');

            $jwt = json_decode($response->getBody()->getContents(), true)['context']['session_token'];

            $results = $this->client->request('POST', 'https://api.mangaupdates.com/v1/series/search', [
                'json' => [
                    'search' => $title,
                    'licensed' => 'yes',
                    'type' => ['Manga'],
                    'exclude_genre' => ['Doujinshi', 'Adult', 'Hentai', 'Ecchi', 'Yaoi', 'Yuri', 'Josei', 'Smut', 'Gender Bender'],
                    'orderby' => 'score',
                ]
            ])->withHeader('Authorization', 'Bearer ' . $jwt)
                ->withHeader('Content-Type', 'application/json')
                ->getBody()
                ->getContents();

            $mangas = [];
            foreach (json_decode($results, true)['results'] as $record) {
                $record = $record['record'];

                $genres = [];
                foreach ($record['genres'] as $genre) {
                    $genres[] = $genre['genre'];
                }

                $mangas[] = (new Manga())
                    ->setTitle($record['title'])
                    ->setSlug($this->slugger->slug($record['title'])->lower())
                    ->setDescription($record['description'])
                    ->setImageUrl($record['image']['url']['original'])
                    ->setGenres($genres)
                    ->setPublicationYear((int)$record['year'])
                    ->setRating((float)$record['bayesian_rating'])
                ;
            }

            return new ArrayCollection($mangas);
        } catch (GuzzleException $e) {
            throw new Exception($e->getMessage());
        }
    }
}
