<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Filesystem\Filesystem;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Place;
use App\Entity\Stats;
use App\Service\BudgetService;

class FraicheurController extends AbstractController
{
    public function __construct(
        private EntityManagerInterface $entityManager,
        private BudgetService $budgetService
    ) {}

    #[Route('/admin/fraicheur/histogramme', name: 'admin_fraicheur_histogramme')]
    public function showFraicheurHistogramme(): Response
    {
        $jsonPath = $this->getParameter('kernel.project_dir') . '/var/fraicheur_osm.json';
        if (!file_exists($jsonPath)) {
            $this->calculateFraicheur();
        }
        return $this->render('admin/fraicheur_histogramme.html.twig');
    }

    #[Route('/admin/fraicheur/calculate', name: 'admin_fraicheur_calculate')]
    public function calculateFraicheur(): Response
    {
        $filesystem = new Filesystem();
        $jsonPath = $this->getParameter('kernel.project_dir') . '/var/fraicheur_osm.json';
        $now = new \DateTime();
        $placeRepo = $this->entityManager->getRepository(Place::class);
        $query = $placeRepo->createQueryBuilder('p')->getQuery();
        $places = $query->toIterable();
        $histogram = [];
        $total = 0;
        foreach ($places as $place) {
            $date = $place->getOsmDataDate();
            if ($date) {
                $key = $date->format('Y-m');
                if (!isset($histogram[$key])) {
                    $histogram[$key] = 0;
                }
                $histogram[$key]++;
                $total++;
            }
            $this->entityManager->detach($place);
        }
        ksort($histogram);
        $data = [
            'generated_at' => $now->format('c'),
            'total' => $total,
            'histogram' => $histogram
        ];
        $filesystem->dumpFile($jsonPath, json_encode($data, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));

        // --- Distribution villes selon lieux/habitants ---
        $distJsonPath = $this->getParameter('kernel.project_dir') . '/var/distribution_villes_lieux_par_habitant.json';
        $statsRepo = $this->entityManager->getRepository(Stats::class);
        $queryStats = $statsRepo->createQueryBuilder('s')->getQuery();
        $allStats = $queryStats->toIterable();
        $histogram_lieux_par_habitant = [];
        $histogram_habitants_par_lieu = [];
        $villesByBinLph = [];
        $villesByBinHpl = [];
        $totalVilles = 0;
        foreach ($allStats as $stat) {
            $places = $stat->getPlacesCount();
            $population = $stat->getPopulation();
            $name = $stat->getName();
            if ($places && $population && $population > 0 && $name) {
                // lieux par habitant (pas de 0.01)
                $ratio_lph = $places / $population;
                $bin_lph = number_format(floor($ratio_lph / 0.01) * 0.01, 2, '.', '');
                if (!isset($histogram_lieux_par_habitant[$bin_lph])) $histogram_lieux_par_habitant[$bin_lph] = 0;
                $histogram_lieux_par_habitant[$bin_lph]++;
                if (!isset($villesByBinLph[$bin_lph])) $villesByBinLph[$bin_lph] = [];
                $villesByBinLph[$bin_lph][] = $name;
                // habitants par lieu (pas de 10)
                $ratio_hpl = $population / $places;
                $bin_hpl = (string)(ceil($ratio_hpl / 10) * 10);
                if (!isset($histogram_habitants_par_lieu[$bin_hpl])) $histogram_habitants_par_lieu[$bin_hpl] = 0;
                $histogram_habitants_par_lieu[$bin_hpl]++;
                if (!isset($villesByBinHpl[$bin_hpl])) $villesByBinHpl[$bin_hpl] = [];
                $villesByBinHpl[$bin_hpl][] = $name;
                $totalVilles++;
            }
            $this->entityManager->detach($stat);
        }
        ksort($histogram_lieux_par_habitant);
        ksort($histogram_habitants_par_lieu);
        ksort($villesByBinLph);
        ksort($villesByBinHpl);
        $distData = [
            'generated_at' => $now->format('c'),
            'total_villes' => $totalVilles,
            'histogram_001' => $histogram_lieux_par_habitant,
            'histogram_10' => $histogram_habitants_par_lieu,
            'villes_by_bin_001' => $villesByBinLph,
            'villes_by_bin_10' => $villesByBinHpl
        ];
        $filesystem->dumpFile($distJsonPath, json_encode($distData, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));

        // --- Statistiques budgétaires ---
        // Remplir les budgets manquants avant le calcul
        $this->budgetService->fillMissingBudgetsForAllStats($this->entityManager);
        $this->calculateBudgetStats();

        return $this->redirectToRoute('admin_fraicheur_histogramme');
    }

    /**
     * Calcule les statistiques liées au budget des villes
     */
    private function calculateBudgetStats(): void
    {
        $filesystem = new Filesystem();
        $budgetJsonPath = $this->getParameter('kernel.project_dir') . '/var/budget_stats.json';
        $now = new \DateTime();
        
        $statsRepo = $this->entityManager->getRepository(Stats::class);
        $queryStats = $statsRepo->createQueryBuilder('s')->getQuery();
        $allStats = $queryStats->toIterable();
        
        $budgetParHabitant = [];
        $villesAvecBudget = [];
        $totalBudget = 0;
        $totalPopulation = 0;
        
        $budgetParLieu = [];
        $villesByBinBudgetParLieu = [];
        $histogramBudgetParLieu = [];
        // Collecter les données de budget par habitant et par lieu
        foreach ($allStats as $stat) {
            $budgetAnnuel = $stat->getBudgetAnnuel();
            $population = $stat->getPopulation();
            $placesCount = $stat->getPlacesCount();
            $name = $stat->getName();
            
            if ($budgetAnnuel && $population && $population > 0 && $name) {
                $budgetParHabitantValue = (float)$budgetAnnuel / $population;
                $budgetParHabitant[] = [
                    'ville' => $name,
                    'code_insee' => $stat->getZone(),
                    'budget_annuel' => (float)$budgetAnnuel,
                    'population' => $population,
                    'budget_par_habitant' => $budgetParHabitantValue
                ];
                $villesAvecBudget[] = $name;
                $totalBudget += (float)$budgetAnnuel;
                $totalPopulation += $population;
            }
            // Ajout budget par lieu
            if ($budgetAnnuel && $placesCount && $placesCount > 0 && $name) {
                $budgetParLieuValue = (float)$budgetAnnuel / $placesCount;
                $budgetParLieu[] = [
                    'ville' => $name,
                    'code_insee' => $stat->getZone(),
                    'budget_annuel' => (float)$budgetAnnuel,
                    'places_count' => $placesCount,
                    'budget_par_lieu' => $budgetParLieuValue
                ];
                $binBudgetParLieu = (string)(ceil($budgetParLieuValue / 5000) * 5000);
                if (!isset($histogramBudgetParLieu[$binBudgetParLieu])) $histogramBudgetParLieu[$binBudgetParLieu] = 0;
                $histogramBudgetParLieu[$binBudgetParLieu]++;
                if (!isset($villesByBinBudgetParLieu[$binBudgetParLieu])) $villesByBinBudgetParLieu[$binBudgetParLieu] = [];
                $villesByBinBudgetParLieu[$binBudgetParLieu][] = $name;
            }
            $this->entityManager->detach($stat);
        }
        
        // Calculer la moyenne du budget par habitant
        $moyenneBudgetParHabitant = $totalPopulation > 0 ? $totalBudget / $totalPopulation : 0;
        
        // Calculer l'écart à la moyenne pour chaque ville
        $ecartsMoyenne = [];
        foreach ($budgetParHabitant as $ville) {
            $ecart = $this->budgetService->getEcartMoyenneBudgetParHabitant(
                $ville['budget_par_habitant'], 
                $moyenneBudgetParHabitant
            );
            $ecartsMoyenne[] = [
                'ville' => $ville['ville'],
                'code_insee' => $ville['code_insee'],
                'budget_par_habitant' => $ville['budget_par_habitant'],
                'ecart_moyenne_pourcent' => $ecart
            ];
        }
        
        // Créer des histogrammes
        $histogramBudgetParHabitant = [];
        $histogramEcartMoyenne = [];
        $villesByBinBudget = [];
        $villesByBinEcart = [];
        
        foreach ($budgetParHabitant as $ville) {
            // Histogramme budget par habitant (pas de 50€)
            $binBudget = (string)(ceil($ville['budget_par_habitant'] / 50) * 50);
            if (!isset($histogramBudgetParHabitant[$binBudget])) {
                $histogramBudgetParHabitant[$binBudget] = 0;
            }
            $histogramBudgetParHabitant[$binBudget]++;
            if (!isset($villesByBinBudget[$binBudget])) {
                $villesByBinBudget[$binBudget] = [];
            }
            $villesByBinBudget[$binBudget][] = $ville['ville'];
        }
        
        foreach ($ecartsMoyenne as $ville) {
            // Histogramme écart à la moyenne (pas de 3%)
            $binEcart = (string)(ceil($ville['ecart_moyenne_pourcent'] / 3) * 3);
            if (!isset($histogramEcartMoyenne[$binEcart])) {
                $histogramEcartMoyenne[$binEcart] = 0;
            }
            $histogramEcartMoyenne[$binEcart]++;
            if (!isset($villesByBinEcart[$binEcart])) {
                $villesByBinEcart[$binEcart] = [];
            }
            $villesByBinEcart[$binEcart][] = $ville['ville'];
        }
        
        ksort($histogramBudgetParHabitant);
        ksort($histogramEcartMoyenne);
        ksort($villesByBinBudget);
        ksort($villesByBinEcart);
        
        // Remplir les bins vides pour l'histogramme budget par lieu (pas de 5000€)
        if (!empty($histogramBudgetParLieu)) {
            $minBin = min(array_map('intval', array_keys($histogramBudgetParLieu)));
            $maxBin = max(array_map('intval', array_keys($histogramBudgetParLieu)));
            for ($bin = $minBin; $bin <= $maxBin; $bin += 5000) {
                $binStr = (string)$bin;
                if (!isset($histogramBudgetParLieu[$binStr])) {
                    $histogramBudgetParLieu[$binStr] = 0;
                }
                if (!isset($villesByBinBudgetParLieu[$binStr])) {
                    $villesByBinBudgetParLieu[$binStr] = [];
                }
            }
            ksort($histogramBudgetParLieu);
            ksort($villesByBinBudgetParLieu);
        }
        
        ksort($histogramBudgetParLieu);
        ksort($villesByBinBudgetParLieu);
        $budgetData = [
            'generated_at' => $now->format('c'),
            'total_villes_avec_budget' => count($villesAvecBudget),
            'moyenne_budget_par_habitant' => $moyenneBudgetParHabitant,
            'total_budget' => $totalBudget,
            'total_population' => $totalPopulation,
            'villes_avec_budget' => $villesAvecBudget,
            'budget_par_habitant' => $budgetParHabitant,
            'budget_par_lieu' => $budgetParLieu,
            'ecarts_moyenne' => $ecartsMoyenne,
            'histogram_budget_par_habitant' => $histogramBudgetParHabitant,
            'histogram_ecart_moyenne' => $histogramEcartMoyenne,
            'villes_by_bin_budget' => $villesByBinBudget,
            'villes_by_bin_ecart' => $villesByBinEcart,
            'histogram_budget_par_lieu' => $histogramBudgetParLieu,
            'villes_by_bin_budget_par_lieu' => $villesByBinBudgetParLieu
        ];
        
        $filesystem->dumpFile($budgetJsonPath, json_encode($budgetData, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
    }

    #[Route('/admin/fraicheur/download', name: 'admin_fraicheur_download')]
    public function downloadFraicheur(): JsonResponse
    {
        $jsonPath = $this->getParameter('kernel.project_dir') . '/var/fraicheur_osm.json';
        if (!file_exists($jsonPath)) {
            return new JsonResponse(['error' => 'Fichier non généré'], 404);
        }
        $content = file_get_contents($jsonPath);
        $data = json_decode($content, true);
        return new JsonResponse($data);
    }

    #[Route('/admin/distribution_villes_lieux_par_habitant_download', name: 'admin_distribution_villes_lieux_par_habitant_download')]
    public function downloadDistributionVillesLieuxParHabitant(): JsonResponse
    {
        $jsonPath = $this->getParameter('kernel.project_dir') . '/var/distribution_villes_lieux_par_habitant.json';
        if (!file_exists($jsonPath)) {
            $this->calculateFraicheur();
        }
        $content = file_get_contents($jsonPath);
        $data = json_decode($content, true);
        return new JsonResponse($data);
    }

    #[Route('/admin/distribution_villes_lieux_par_habitant_villes', name: 'admin_distribution_villes_lieux_par_habitant_villes')]
    public function downloadDistributionVillesLieuxParHabitantVilles(): JsonResponse
    {
        $jsonPath = $this->getParameter('kernel.project_dir') . '/var/distribution_villes_lieux_par_habitant.json';
        if (!file_exists($jsonPath)) {
            $this->calculateFraicheur();
        }
        $content = file_get_contents($jsonPath);
        $data = json_decode($content, true);
        // On renvoie les deux listes de villes par bin
        return new JsonResponse([
            'villes_by_bin_001' => $data['villes_by_bin_001'] ?? [],
            'villes_by_bin_10' => $data['villes_by_bin_10'] ?? []
        ]);
    }

    #[Route('/admin/budget/download', name: 'admin_budget_download')]
    public function downloadBudget(): JsonResponse
    {
        $jsonPath = $this->getParameter('kernel.project_dir') . '/var/budget_stats.json';
        if (!file_exists($jsonPath)) {
            $this->calculateFraicheur();
        }
        $content = file_get_contents($jsonPath);
        $data = json_decode($content, true);
        return new JsonResponse($data);
    }

    #[Route('/admin/budget/villes', name: 'admin_budget_villes')]
    public function downloadBudgetVilles(): JsonResponse
    {
        $jsonPath = $this->getParameter('kernel.project_dir') . '/var/budget_stats.json';
        if (!file_exists($jsonPath)) {
            $this->calculateFraicheur();
        }
        $content = file_get_contents($jsonPath);
        $data = json_decode($content, true);
        return new JsonResponse([
            'villes_by_bin_budget' => $data['villes_by_bin_budget'] ?? [],
            'villes_by_bin_ecart' => $data['villes_by_bin_ecart'] ?? []
        ]);
    }
} 