<?php

namespace App\Entity;

use App\Repository\StatsRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: StatsRepository::class)]
class Stats
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255, type: Types::STRING, nullable: true)]
    private ?string $zone = null; // code insee de la zone

    #[ORM\Column(type: Types::INTEGER, nullable: true)]
    private ?int $completion_percent = null;

    /**
     * @var Collection<int, Place>
     */
    #[ORM\OneToMany(targetEntity: Place::class, mappedBy: 'stats', cascade: ['persist', 'remove'])]
    private Collection $places;

    // nombre de commerces dans la zone 
    #[ORM\Column(type: Types::INTEGER, nullable: true)]
    private ?int $places_count = null;

    // nombre de commerces avec horaires
    #[ORM\Column(type: Types::INTEGER, nullable: true)]
    private ?int $avec_horaires = null;

    // nombre de commerces avec adresse
    #[ORM\Column(type: Types::INTEGER, nullable: true)]
    private ?int $avec_adresse = null;

    // nombre de commerces avec site
    #[ORM\Column(type: Types::INTEGER, nullable: true)]
    private ?int $avec_site = null;

    // nombre de commerces avec accessibilité
    #[ORM\Column(type: Types::INTEGER, nullable: true)]
    private ?int $avec_accessibilite = null;

    // nombre de commerces avec note
    #[ORM\Column(type: Types::INTEGER, nullable: true)]
    private ?int $avec_note = null;

    #[ORM\Column(length: 255, nullable: true, options: ['charset' => 'utf8mb4'] )]
    private ?string $name = null;

    // nombre d'habitants dans la zone
    #[ORM\Column(type: Types::INTEGER, nullable: true)]
    private ?int $population = null;

    #[ORM\Column(type: Types::INTEGER, nullable: true)]
    private ?int $siren = null;

    #[ORM\Column(type: Types::INTEGER, nullable: true)]
    private ?int $codeEpci = null;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $codesPostaux = null;

    /**
     * @var Collection<int, StatsHistory>
     */
    #[ORM\OneToMany(targetEntity: StatsHistory::class, mappedBy: 'stats')]
    private Collection $statsHistories;

    #[ORM\Column(nullable: true)]
    private ?\DateTime $date_created = null;

    #[ORM\Column(nullable: true)]
    private ?\DateTime $date_modified = null;

    #[ORM\Column(nullable: true)]
    private ?int $avec_siret = null;

    #[ORM\Column(nullable: true)]
    private ?int $avec_name = null;

    #[ORM\Column(nullable: true)]
    private ?\DateTime $osm_data_date_min = null;

    #[ORM\Column(nullable: true)]
    private ?\DateTime $osm_data_date_avg = null;

    #[ORM\Column(nullable: true)]
    private ?\DateTime $osm_data_date_max = null;

    #[ORM\Column(type: Types::DECIMAL, precision: 15, scale: 2, nullable: true)]
    private ?string $budget_annuel = null;

    #[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 7, nullable: true)]
    private ?string $lat = null;

    #[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 7, nullable: true)]
    private ?string $lon = null;

    /**
     * @var Collection<int, CityFollowUp>
     */
    #[ORM\OneToMany(mappedBy: 'stats', targetEntity: CityFollowUp::class, cascade: ['persist', 'remove'])]
    private Collection $cityFollowUps;

    public function getCTCurlBase(): ?string
    {
        $base = 'https://complete-tes-commerces.fr/';
        $zone = $this->zone;

        $departement = substr($zone, 0, 2);
        $insee_code = $zone;
        $slug = strtolower(str_replace(' ', '-', $this->getName()));
        $url = $base . $departement . '/' . $insee_code . '-'.$slug.'/json/' . $slug ;

        return $url;
    }

    public function getLastStats(): string
    {
        return $this->getParametricJsonFromCTC('_last_stats');
    }

    public function getDailyStats(): string
    {
        return $this->getParametricJsonFromCTC('_dailystats');
    }
    
    public function getOSMClosedSirets(): string
    {
        return $this->getParametricJsonFromCTC('_osm_closed_siret');
    }

    public function getOSMDisusedShops(): string
    {
        return $this->getParametricJsonFromCTC('_osm_disused_shops');
    }

    public function getOSMNoSiteShops(): string
    {
        return $this->getParametricJsonFromCTC('_osm_no_site_shops');
    }

    public function getPanoFile(): string
    {
        return $this->getParametricJsonFromCTC('_pano_file');
    }

    public function getClosedPanoFile(): string
    {
        return $this->getParametricJsonFromCTC('_closed_pano_file');
    }

    public function getSireneMatches(): string
    {
        return $this->getParametricJsonFromCTC('_sirene_matches');
    }

 

    public function getParametricJsonFromCTC($suffixe): string
    {
        $url = $this->getCTCurlBase().$suffixe.'.json';
        
        return $url;
    }
    

    public function getAllCTCUrlsMap(): ?array
    {
        $functions = [
            'getLastStats',
            'getDailyStats',
            'getOSMClosedSirets',
            'getOSMDisusedShops',
            'getOSMNoSiteShops',
        ];

        $urls = [];
        foreach ($functions as $function) {
            $urls[$function] = $this->$function();
        }
        return $urls;
    }
    

    // calcule le pourcentage de complétion de la zone
    public function computeCompletionPercent(): ?int
    {

        $places_count = $this->places->count();
        // Si aucun commerce, on retourne 0
        if ($places_count === 0 || $places_count === null) {
            $this->setCompletionPercent(0);
            return 0;
        }

        // On réinitialise les compteurs
        $this->avec_horaires = 0;
        $this->avec_adresse = 0;
        $this->avec_site = 0;
        $this->avec_accessibilite = 0;
        $this->avec_note = 0;
        $this->avec_siret = 0;
        $this->avec_name = 0;
        
        $somme_completions = 0;
        

        // On boucle sur chaque place pour compter les attributs renseignés
        foreach ($this->places as $place) {
            $place_completions = 0;
            if ($place->hasAddress()) {
                $this->avec_adresse++;
                $place_completions++;
            }
            if ($place->hasWebsite()) {
                $this->avec_site++; 
                $place_completions++;
            }
            if ($place->hasWheelchair()) {
                $this->avec_accessibilite++;
                $place_completions++;
            }
            if ($place->hasOpeningHours()) {
                $this->avec_horaires++;
                $place_completions++;
            }
            if($place->getSiret()) {
                $this->avec_siret++;
                $place_completions++;
            }
            if($place->getName()) {
                $this->avec_name++;
                $place_completions++;
            }
            if($place->getNoteContent()) {
                $this->avec_note++;
                // on ne compte pas les notes comme indice de complétion
            }
            
            $somme_completions += $place_completions / 6;
        }

        $this->setPlacesCount($places_count);
        $this->setCompletionPercent(round($somme_completions / $places_count * 100));
        return $this->completion_percent;
    }



    public function __construct()
    {
        $this->places = new ArrayCollection();
        $this->statsHistories = new ArrayCollection();
        $this->cityFollowUps = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getZone(): ?string
    {
        return $this->zone;
    }

    public function setZone(string $zone): static
    {
        $this->zone = $zone;

        return $this;
    }

    public function getCompletionPercent(): ?int
    {
        return $this->completion_percent;
    }

    public function setCompletionPercent(int $completion_percent): static
    {
        $this->completion_percent = $completion_percent;

        return $this;
    }

    /**
     * @return Collection<int, Place>
     */
    public function getPlaces(): Collection
    {
        return $this->places;
    }

    public function addPlace(Place $place): static
    {
        if (!$this->places->contains($place)) {
            $this->places->add($place);
            $place->setStats($this);
        }

        return $this;
    }

    public function removePlace(Place $place): static
    {
        if ($this->places->removeElement($place)) {
            // set the owning side to null (unless already changed)
            if ($place->getStats() === $this) {
                $place->setStats(null);
            }
        }

        return $this;
    }

    public function getPlacesCount(): ?int
    {
        return $this->places_count;
    }

    public function setPlacesCount(int $places_count): static
    {
        $this->places_count = $places_count;

        return $this;
    }

    public function getAvecHoraires(): ?int
    {
        return $this->avec_horaires;
    }

    public function setAvecHoraires(int $avec_horaires): static
    {
        $this->avec_horaires = $avec_horaires;

        return $this;
    }

    public function getAvecAdresse(): ?int
    {
        return $this->avec_adresse;
    }

    public function setAvecAdresse(int $avec_adresse): static
    {
        $this->avec_adresse = $avec_adresse;

        return $this;
    }
    
    public function getAvecSite(): ?int
    {
        return $this->avec_site;
    }

    public function setAvecSite(int $avec_site): static
    {
        $this->avec_site = $avec_site;

        return $this;
    }
    
    public function getAvecAccessibilite(): ?int
    {
        return $this->avec_accessibilite;
    }

    public function setAvecAccessibilite(int $avec_accessibilite): static
    {
        $this->avec_accessibilite = $avec_accessibilite;

        return $this;
    }

    public function getAvecNote(): ?int
    {
        return $this->avec_note;
    }

    public function setAvecNote(int $avec_note): static
    {
        $this->avec_note = $avec_note;

        return $this;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(?string $name): static
    {
        $this->name = $name;

        return $this;
    }

    public function getPopulation(): ?int
    {
        return $this->population;
    }

    public function setPopulation(?int $population): static
    {
        $this->population = $population;
        return $this;
    }

    public function getSiren(): ?int
    {
        return $this->siren;
    }

    public function setSiren(?int $siren): static
    {
        $this->siren = $siren;

        return $this;
    }

    public function getCodeEpci(): ?int
    {
        return $this->codeEpci;
    }

    public function setCodeEpci(?int $codeEpci): static
    {
        $this->codeEpci = $codeEpci;

        return $this;
    }

    public function getCodesPostaux(): ?string
    {
        return $this->codesPostaux;
    }

    public function setCodesPostaux(?string $codesPostaux): static
    {
        $this->codesPostaux = $codesPostaux;

        return $this;
    }

    /**
     * @return Collection<int, StatsHistory>
     */
    public function getStatsHistories(): Collection
    {
        return $this->statsHistories;
    }

    public function addStatsHistory(StatsHistory $statsHistory): static
    {
        if (!$this->statsHistories->contains($statsHistory)) {
            $this->statsHistories->add($statsHistory);
            $statsHistory->setStats($this);
        }

        return $this;
    }

    public function removeStatsHistory(StatsHistory $statsHistory): static
    {
        if ($this->statsHistories->removeElement($statsHistory)) {
            // set the owning side to null (unless already changed)
            if ($statsHistory->getStats() === $this) {
                $statsHistory->setStats(null);
            }
        }

        return $this;
    }

    public function getDateCreated(): ?\DateTime
    {
        return $this->date_created;
    }

    public function setDateCreated(?\DateTime $date_created): static
    {
        $this->date_created = $date_created;

        return $this;
    }

    public function getDateModified(): ?\DateTime
    {
        return $this->date_modified;
    }

    public function setDateModified(?\DateTime $date_modified): static
    {
        $this->date_modified = $date_modified;

        return $this;
    }

    public function getAvecSiret(): ?int
    {
        return $this->avec_siret;
    }

    public function setAvecSiret(?int $avec_siret): static
    {
        $this->avec_siret = $avec_siret;

        return $this;
    }

    public function getAvecName(): ?int
    {
        return $this->avec_name;
    }

    public function setAvecName(?int $avec_name): static
    {
        $this->avec_name = $avec_name;

        return $this;
    }

    public function getOsmDataDateMin(): ?\DateTime
    {
        return $this->osm_data_date_min;
    }

    public function setOsmDataDateMin(?\DateTime $osm_data_date_min): static
    {
        $this->osm_data_date_min = $osm_data_date_min;

        return $this;
    }

    public function getOsmDataDateAvg(): ?\DateTime
    {
        return $this->osm_data_date_avg;
    }

    public function setOsmDataDateAvg(?\DateTime $osm_data_date_avg): static
    {
        $this->osm_data_date_avg = $osm_data_date_avg;

        return $this;
    }

    public function getOsmDataDateMax(): ?\DateTime
    {
        return $this->osm_data_date_max;
    }

    public function setOsmDataDateMax(?\DateTime $osm_data_date_max): static
    {
        $this->osm_data_date_max = $osm_data_date_max;

        return $this;
    }

    public function getBudgetAnnuel(): ?string
    {
        return $this->budget_annuel;
    }

    public function setBudgetAnnuel(?string $budget_annuel): static
    {
        $this->budget_annuel = $budget_annuel;

        return $this;
    }

    /**
     * @return Collection<int, CityFollowUp>
     */
    public function getCityFollowUps(): Collection
    {
        return $this->cityFollowUps;
    }

    public function addCityFollowUp(CityFollowUp $cityFollowUp): static
    {
        if (!$this->cityFollowUps->contains($cityFollowUp)) {
            $this->cityFollowUps->add($cityFollowUp);
            $cityFollowUp->setStats($this);
        }
        return $this;
    }

    public function removeCityFollowUp(CityFollowUp $cityFollowUp): static
    {
        if ($this->cityFollowUps->removeElement($cityFollowUp)) {
            if ($cityFollowUp->getStats() === $this) {
                $cityFollowUp->setStats(null);
            }
        }
        return $this;
    }

    public function getLat(): ?string
    {
        return $this->lat;
    }

    public function setLat(?string $lat): static
    {
        $this->lat = $lat;
        return $this;
    }

    public function getLon(): ?string
    {
        return $this->lon;
    }

    public function setLon(?string $lon): static
    {
        $this->lon = $lon;
        return $this;
    }
 

}   
