<?php

namespace App\Service;

use Symfony\Contracts\HttpClient\HttpClientInterface;
use Doctrine\ORM\EntityManagerInterface;

class BudgetService
{
    public function __construct(
        private HttpClientInterface $client
    ) {
    }

    /**
     * Récupère le budget annuel d'une commune via l'API des finances publiques
     */
    public function getBudgetAnnuel(string $codeInsee): ?float
    {
        try {
            // Pour le moment, on utilise des données de test
            // TODO: Implémenter l'API réelle des finances publiques
            return $this->getBudgetAnnuelTest($codeInsee);
            
        } catch (\Exception $e) {
            // En cas d'erreur, on essaie une API alternative
            return $this->getBudgetAnnuelAlternative($codeInsee);
        }
    }

    /**
     * Méthode de test avec des données fictives basées sur la population
     */
    private function getBudgetAnnuelTest(string $codeInsee): ?float
    {
        // Récupérer la population via l'API geo.gouv.fr
        try {
            $apiUrl = 'https://geo.api.gouv.fr/communes/' . $codeInsee;
            $response = $this->client->request('GET', $apiUrl, [
                'timeout' => 10,
                'headers' => [
                    'Accept' => 'application/json',
                ]
            ]);

            if ($response->getStatusCode() !== 200) {
                return null;
            }

            $data = json_decode($response->getContent(), true);
            
            if (!$data || !isset($data['population'])) {
                return null;
            }

            $population = (int)$data['population'];
            
            // Calculer un budget fictif basé sur la population
            // Budget moyen par habitant en France : ~1500€
            $budgetParHabitant = 1500 + (rand(-200, 300)); // Variation aléatoire
            $budgetTotal = $population * $budgetParHabitant;
            
            return $budgetTotal;

        } catch (\Exception $e) {
            return null;
        }
    }

    /**
     * Méthode alternative utilisant l'API data.gouv.fr pour les données budgétaires
     */
    private function getBudgetAnnuelAlternative(string $codeInsee): ?float
    {
        try {
            // API data.gouv.fr pour les comptes des communes
            $url = "https://www.data.gouv.fr/api/1/datasets/comptes-individuels-des-communes-fichier-global/";
            
            // Note: Cette API nécessite un traitement plus complexe car elle retourne un fichier CSV
            // Pour simplifier, on retourne null et on pourra implémenter plus tard
            return null;

        } catch (\Exception $e) {
            return null;
        }
    }

    /**
     * Calcule le budget par habitant
     */
    public function getBudgetParHabitant(float $budgetAnnuel, int $population): ?float
    {
        if ($population <= 0) {
            return null;
        }
        
        return $budgetAnnuel / $population;
    }

    /**
     * Calcule l'écart à la moyenne du budget par habitant
     */
    public function getEcartMoyenneBudgetParHabitant(float $budgetParHabitant, float $moyenneBudgetParHabitant): float
    {
        if ($moyenneBudgetParHabitant <= 0) {
            return 0;
        }
        
        return (($budgetParHabitant - $moyenneBudgetParHabitant) / $moyenneBudgetParHabitant) * 100;
    }

    /**
     * Remplit les budgets manquants pour toutes les villes (Stats)
     */
    public function fillMissingBudgetsForAllStats(EntityManagerInterface $em): void
    {
        $statsRepo = $em->getRepository(\App\Entity\Stats::class);
        $query = $statsRepo->createQueryBuilder('s')->getQuery();
        $allStats = $query->toIterable();
        $budgetsMisAJour = 0;
        foreach ($allStats as $stat) {
            if (!$stat->getBudgetAnnuel() && $stat->getZone()) {
                $budget = $this->getBudgetAnnuel($stat->getZone());
                if ($budget !== null) {
                    $stat->setBudgetAnnuel((string)$budget);
                    $em->persist($stat);
                    $budgetsMisAJour++;
                    continue;
                }
            }
        }
        if ($budgetsMisAJour > 0) {
            $em->flush();
        }
    }
} 