<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\WopiBundle\Service;

use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\Multipart\FormDataPart;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * Handles the conversion of documents to PDF using the Collabora Online server.
 */
class WopiConverter
{
    private readonly string $collaboraDomain;

    private const LOG_PREFIX = '[WopiConverterPDF] ';

    public function __construct(
        private readonly HttpClientInterface $httpClient,
        private readonly LoggerInterface $logger,
        ParameterBagInterface $parameters,
    ) {
        $this->collaboraDomain = $parameters->get('wopi')['server'];
    }

    public function convert(string $lang, string $content, string $contentType, $convertTo = 'pdf'): string
    {
        try {
            $url = sprintf('%s/cool/convert-to/%s', $this->collaboraDomain, $convertTo);

            $form = new FormDataPart([
                'data' => new DataPart($content, uniqid('temp-file-'), contentType: $contentType),
            ]);
            $response = $this->httpClient->request('POST', $url, [
                'headers' => $form->getPreparedHeaders()->toArray(),
                'query' => ['lang' => $lang],
                'body' => $form->bodyToString(),
                'timeout' => 10,
            ]);

            if (200 === $response->getStatusCode()) {
                $this->logger->info(self::LOG_PREFIX.'document converted successfully', ['size' => strlen($content)]);
            }

            return $response->getContent();
        } catch (ClientExceptionInterface $e) {
            throw new \LogicException('no correct request to collabora online', previous: $e);
        } catch (RedirectionExceptionInterface $e) {
            throw new \RuntimeException('no redirection expected', previous: $e);
        } catch (ServerExceptionInterface|TransportExceptionInterface $e) {
            throw new \RuntimeException('error while converting document', previous: $e);
        }
    }
}
