<?php

namespace App\Service;

use App\Entity\Project;
use App\Entity\Task;
use GeoJson\GeoJson;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Workflow\WorkflowInterface;

class GeoJsonManager
{
    public function __construct(
        private UrlGeneratorInterface $router,
        private WorkflowInterface $taskLifecycleStateMachine,
    ) {
    }

    // Enrichit le geojson d’une tâche avec des propriétés calcuées
    private function getFullGeoJson(Task $task)
    {
        if (!$task->hasGeojson()) {
            return null;
        }

        try {
            $data = json_decode($task->getGeojson(), true);
        } catch (\Exception $exception) {
            return null;
        }

        if (!isset($data['features']) or empty($data['features'])) {
            return null;
        }

        foreach ($data['features'] as $index => $feature) {
            $feature['properties'] = array_merge(!isset($feature['properties']) ? [] : $feature['properties'], [
                'name' => $task->getName(),
                'url' => $this->router->generate('app_task_show', ['slug' => $task->getSlug()], UrlGeneratorInterface::ABSOLUTE_URL),
                'color' => $this->taskLifecycleStateMachine->getMetadataStore()->getPlaceMetadata($task->getStatus())['color'],
            ]);
            $data['features'][$index] = $feature;
        }

        return $data;
    }

    // Produit le geojson d’un projet ou d’une tâche de façon transparente pour simplifier
    public function generateGeoJson($entity)
    {
        $geoJsons = [];

        if ($entity instanceof Task) {
            $task = $entity;
            $geoJson = $this->getFullGeojson($task);
            if (!is_null($geoJson)) {
                $geoJsons[] = GeoJson::jsonUnserialize($geoJson);
            }
        } elseif ($entity instanceof Project) {
            $project = $entity;
            foreach ($project->getTasks() as $task) {
                $geoJson = $this->getFullGeojson($task);
                if (!is_null($geoJson)) {
                    $geoJsons[] = GeoJson::jsonUnserialize($geoJson);
                }
            }
        }

        return $geoJsons;
    }
}
