<?php

namespace App\Controller\OgRepository\Image;

use App\Controller\OgRepository\AbstractOgRepositoryController;
use App\Dto\Input\ConvertImageRepositoryInput;
use App\Dto\Input\ImportImageRepositoryInput;
use App\Entity\Image;
use App\Entity\ImageImageRepository;
use App\Entity\ImageRepository;
use App\Model\CommandTypes;
use App\Model\ImageStatus;
use App\Model\TraceStatus;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;

#[AsController]
class ConvertAction extends AbstractOgRepositoryController
{
    /**
     * @throws TransportExceptionInterface
     * @throws ServerExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ClientExceptionInterface
     */
    public function __invoke(ConvertImageRepositoryInput $input, ImageRepository $repository): JsonResponse
    {
        $fileSystem = $input->filesystem;
        $image = pathinfo($input->name, PATHINFO_FILENAME);

        $imageEntity = $this->entityManager->getRepository(Image::class)->findOneBy(['name' => $image]);

        if (!$imageEntity){
            $imageEntity = new Image();
            $imageEntity->setName($image);
            $imageEntity->setType('monolithic');
            $imageEntity->setRemotePc(false);
            $imageEntity->setIsGlobal(false);

            $this->entityManager->persist($imageEntity);
        }

        $imageImageRepositoryEntity = $this->entityManager->getRepository(ImageImageRepository::class)->findOneBy(['image' => $imageEntity, 'repository' => $repository]);

        if ($imageImageRepositoryEntity){
            throw new BadRequestHttpException('This image already exists in this repository');
        }

        $imageImageRepositoryEntity = new ImageImageRepository();
        $imageImageRepositoryEntity->setName($imageEntity->getName().'_v'.$imageImageRepositoryEntity->getVersion() + 1);
        $imageImageRepositoryEntity->setStatus(ImageStatus::PENDING);
        $imageImageRepositoryEntity->setImage($imageEntity);
        $imageImageRepositoryEntity->setRepository($repository);
        $imageImageRepositoryEntity->setVersion(1);

        $this->entityManager->persist($imageImageRepositoryEntity);

        $this->logger->info('Converting image', ['image' => $image]);

        $params = [
            'json' => [
                'filesystem' => $fileSystem,
                'virtual_image' => $input->name
            ]
        ];

        $content = $this->createRequest('POST', 'http://'.$repository->getIp().':8006/ogrepository/v1/images/virtual', $params);

        if (isset($content['error']) && $content['code'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
            throw new BadRequestHttpException('An error occurred while converting the image: ' . $content['error'] . ' - ' . $content['details']);
        }
        $this->entityManager->flush();

        $inputData = [
            'imageName' => $image,
            'imageImageRepositoryUuid' => $imageImageRepositoryEntity->getUuid(),
        ];

        $this->createService->__invoke(null, CommandTypes::CONVERT_IMAGE, TraceStatus::IN_PROGRESS, $content['job_id'], $inputData);

        return new JsonResponse(data: [], status: Response::HTTP_OK);
    }
}