<?php

namespace App\State\Processor;

use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use ApiPlatform\State\ProcessorInterface;
use ApiPlatform\Validator\ValidatorInterface;
use App\Controller\OgAgent\PartitionAssistantAction;
use App\Dto\Input\MenuInput;
use App\Dto\Input\PartitionInput;
use App\Dto\Input\PartitionPostInput;
use App\Dto\Input\UserGroupInput;
use App\Dto\Output\MenuOutput;
use App\Dto\Output\PartitionOutput;
use App\Dto\Output\UserGroupOutput;
use App\Repository\MenuRepository;
use App\Repository\PartitionRepository;
use App\Repository\UserGroupRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;

readonly class PartitionProcessor implements ProcessorInterface
{
    public function __construct(
        private PartitionRepository         $partitionRepository,
        private ValidatorInterface          $validator,
        private PartitionAssistantAction    $partitionAssistantAction
    )
    {
    }

    /**
     * @throws \Exception
     */
    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): JsonResponse
    {
        switch ($operation){
            case $operation instanceof Post:
            case $operation instanceof Put:
            case $operation instanceof Patch:
                return $this->processCreateOrUpdate($data, $operation, $uriVariables, $context);
            case $operation instanceof Delete:
                return $this->processDelete($data, $operation, $uriVariables, $context);
        }
    }

    /**
     * @throws \Exception
     */
    private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): JsonResponse
    {
        if (!($data instanceof PartitionPostInput)) {
            throw new \Exception(sprintf('data is not instance of %s', PartitionPostInput::class));
        }

        foreach ($data->partitions as $partition) {
            $entity = null;
            if (isset($partition->uuid)) {
                $entity = $this->partitionRepository->findOneByUuid($partition->uuid);

                if ($partition->removed && $entity) {
                    $this->partitionRepository->delete($entity);
                    continue;
                }
            }

            $entity = $partition->createOrUpdateEntity($entity);
            $this->validator->validate($entity);

            //$this->partitionRepository->save($entity);
        }

        $response = $this->partitionAssistantAction->__invoke($data);

        if ($response instanceof JsonResponse && $response->getStatusCode() === 200) {
            $jobContent = json_decode($response->getContent(), true, 512, JSON_UNESCAPED_SLASHES);
            $jsonString = json_encode($jobContent, JSON_UNESCAPED_SLASHES);
            return new JsonResponse($jsonString, Response::HTTP_OK, [], true);
        }

        return new JsonResponse(data: ['/clients/' . $image->getClient()->getUuid() => ['headers' => []]], status: Response::HTTP_OK);
    }

    private function processDelete($data, Operation $operation, array $uriVariables = [], array $context = []): null
    {
        $user = $this->partitionRepository->findOneByUuid($uriVariables['uuid']);
        $this->partitionRepository->delete($user);

        return null;
    }
}
