<?php

namespace App\Service;

use App\Entity\GitRepository;
use App\Entity\ImageRepository;
use App\Controller\OgRepository\Git\GetCollectionAction;
use App\Controller\OgRepository\Git\CreateRepositoryAction;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class ExternalGitRepositoryService
{
    public function __construct(
        private HttpClientInterface $httpClient,
        private GetCollectionAction $getCollectionAction,
        private CreateRepositoryAction $createRepositoryAction
    ) {}

    /**
     * Obtiene todos los repositorios de un servidor externo
     */
    public function getRepositories(ImageRepository $imageRepository): array
    {
        try {
            $response = $this->getCollectionAction->__invoke($imageRepository);
            $content = json_decode($response->getContent(), true);
            
            if ($response->getStatusCode() !== Response::HTTP_OK) {
                throw new BadRequestHttpException('Error obteniendo repositorios del servidor externo');
            }

            // El GetCollectionAction devuelve directamente el contenido de la API externa
            if (!isset($content['repositories'])) {
                return [];
            }

            return $content['repositories'];
        } catch (\Exception $e) {
            throw new BadRequestHttpException('Error obteniendo repositorios: ' . $e->getMessage());
        }
    }

    /**
     * Obtiene un repositorio específico por nombre
     */
    public function getRepository(string $name, ImageRepository $imageRepository): ?array
    {
        $repositories = $this->getRepositories($imageRepository);
        
        foreach ($repositories as $repo) {
            // La API externa devuelve los nombres como strings simples
            if ($repo === $name) {
                return ['name' => $repo];
            }
        }

        return null;
    }

    /**
     * Crea un repositorio en el servidor externo
     */
    public function createRepository(GitRepository $gitRepository): array
    {
        try {
            $response = $this->createRepositoryAction->__invoke($gitRepository);
            
            if ($response->getStatusCode() !== Response::HTTP_OK) {
                throw new BadRequestHttpException('Error creando repositorio en el servidor externo');
            }

            // El CreateRepositoryAction devuelve un array vacío en caso de éxito
            return json_decode($response->getContent(), true) ?: [];
        } catch (\Exception $e) {
            throw new BadRequestHttpException('Error creando repositorio: ' . $e->getMessage());
        }
    }

    /**
     * Actualiza un repositorio en el servidor externo
     */
    public function updateRepository(GitRepository $gitRepository): array
    {
        $response = $this->httpClient->request('PUT', 
            "http://{$gitRepository->getRepository()->getIp()}:8006/ogrepository/v1/git/repositories/{$gitRepository->getName()}",
            [
                'json' => [
                    'name' => $gitRepository->getName(),
                    'description' => $gitRepository->getDescription(),
                ]
            ]
        );

        if ($response->getStatusCode() !== Response::HTTP_OK) {
            throw new BadRequestHttpException('Error actualizando repositorio en el servidor externo');
        }

        return $response->toArray();
    }

    /**
     * Elimina un repositorio del servidor externo
     */
    public function deleteRepository(string $name, ImageRepository $imageRepository): void
    {
        $response = $this->httpClient->request('DELETE', 
            "http://{$imageRepository->getIp()}:8006/ogrepository/v1/git/repositories/{$name}"
        );

        if ($response->getStatusCode() !== Response::HTTP_OK) {
            throw new BadRequestHttpException('Error eliminando repositorio del servidor externo');
        }
    }

    /**
     * Convierte datos de la API externa a una entidad GitRepository
     */
    public function createEntityFromExternalData($externalData, ImageRepository $imageRepository): GitRepository
    {
        $gitRepository = new GitRepository();
        
        // La API externa devuelve los nombres como strings simples
        if (is_string($externalData)) {
            $gitRepository->setName($externalData);
        } elseif (is_array($externalData) && isset($externalData['name'])) {
            $gitRepository->setName($externalData['name']);
            $gitRepository->setDescription($externalData['description'] ?? null);
        } else {
            throw new \InvalidArgumentException('Los datos externos deben ser string o array con nombre');
        }
        
        $gitRepository->setRepository($imageRepository);
        
        return $gitRepository;
    }
} 