<?php
/**
 * Nom du fichier: ActivityManager.php
 *
 * @author PEREDERII Antoine
 * @date 2023-11-25
 * @description Classe ActivityManager pour gérer les opérations liées aux activités avec l'upload de données de fichiers .fit.
 *
 * @package manager
 */
namespace Manager;

use adriangibbons\phpFITFileAnalysis;
use Exception;
use Model\Activity;
use Network\IAuthService;
use Stub\AuthService;

/**
 * @class ActivityManager
 * @brief Classe pour gérer les opérations liées aux activités.
 */
class ActivityManager
{
    /**
     * @var AuthService|IAuthService
     */
    private IAuthService $authService;

    /**
     * Constructeur de la classe ActivityManager.
     *
     * @param IAuthService $authService Le service d'authentification utilisé pour vérifier l'utilisateur actuel.
     */
    public function __construct(DataManager $dataManager,IAuthService $authService)
    {
        $this->authService = $authService;
    }

    /**
     * Enregistre les données d'un fichier FIT au format JSON.
     *
     * @param object $monFichierFit L'objet FIT File à partir duquel extraire les données.
     * @return bool Retourne true en cas de succès, sinon false.
     * @throws Exception En cas d'erreur lors de l'ouverture ou de l'enregistrement du fichier FIT.
     */
    public function saveFitFileToJSON($monFichierFit): bool
    {
        try {
            // Extraction des données du fichier FIT
            $fitData = [
                'timestamps'   => $monFichierFit->data_mesgs['record']['timestamp'],
                'latitudes'    => $monFichierFit->data_mesgs['record']['position_lat'],
                'longitudes'   => $monFichierFit->data_mesgs['record']['position_long'],
                'altitudes'    => $monFichierFit->data_mesgs['record']['altitude'],
                'heartRates'   => $monFichierFit->data_mesgs['record']['heart_rate'],
                'cadences'     => $monFichierFit->data_mesgs['record']['cadence'],
                'distances'    => $monFichierFit->data_mesgs['record']['distance'],
                'speeds'       => $monFichierFit->data_mesgs['record']['speed'],
                'powers'       => $monFichierFit->data_mesgs['record']['power'],
                'temperatures' => $monFichierFit->data_mesgs['record']['temperature'],
            ];

            // Conversion des données en format JSON
            $jsonFitData = json_encode($fitData, JSON_PRETTY_PRINT);

            // Enregistrement du fichier JSON
            file_put_contents('/Users/Perederii/SAE/git/Web/Sources/src/data/model/fitFileSaver/jsonFiles/ActivitySave.json', $jsonFitData);

            return true;
        } catch (\Exception $e) {
            echo $e;
        }

        return false;
    }

    /**
     * Télécharge un fichier FIT, extrait les données pertinentes et crée une nouvelle activité associée.
     *
     * @param string $type Le type d'activité.
     * @param int $effortRessenti L'effort ressenti pour l'activité.
     * @param string|resource $file_path_or_data Le chemin du fichier FIT ou les données brutes du fichier FIT.
     * @param array|null $options Les options de téléchargement du fichier FIT (facultatif).
     * @return bool Retourne true en cas de succès, sinon false.
     * @throws Exception En cas d'erreur lors du téléchargement, du traitement ou de l'enregistrement des données.
     */
    public function uploadFile($type, $effortRessenti, $file_path_or_data, ?array $options = null): bool
    {
        try {
            // Vérification des options par défaut
            if (empty($options)) {
                $options = [
                    'fix_data'                => ['all'],
                    'data_every_second'       => false,
                    'units'                   => 'metric',
                    'pace'                    => true,
                    'garmin_timestamps'       => false,
                    'overwrite_with_dev_data' => false
                ];
            }

            // Ouverture du fichier FIT
            if (!($monFichierFit = new phpFITFileAnalysis($file_path_or_data, $options))) {
                throw new Exception("Problème lors de l'ouverture du fichier FIT");
            }

            // Extraction du premier et du dernier timestamp
            $firstTimestamp = $monFichierFit->data_mesgs['record']['timestamp'][0];
            $lastTimestamp = end($monFichierFit->data_mesgs['record']['timestamp']);

            // Conversion des timestamps en objets DateTime
            $startDate = \DateTime::createFromFormat('Y-m-d', date('Y-m-d', $firstTimestamp));
            $startTime = \DateTime::createFromFormat('H:i:s', date('H:i:s', $firstTimestamp));
            $endTime = ($lastTimestamp) ? \DateTime::createFromFormat('H:i:s', date('H:i:s', $lastTimestamp)) : null;

            // Vérification des conversions en DateTime
            if (!$startDate || !$startTime || ($lastTimestamp && !$endTime)) {
                throw new \Exception("La conversion en DateTime a échoué.");
            }

            // Extraction des autres données nécessaires
            $heartRateList = $monFichierFit->data_mesgs['record']['heart_rate'];
            $variability = max($heartRateList) - min($heartRateList);
            $average = number_format(array_sum($heartRateList) / count($heartRateList), 2);
            $varianceV = array_sum(array_map(fn($x) => pow($x - $average, 2), $heartRateList)) / count($heartRateList);
            $variance = number_format($varianceV, 2);
            $standardDeviation = number_format(sqrt($variance), 2);
            $maximum = max($heartRateList);
            $minimum = min($heartRateList);

            $temperatureList = $monFichierFit->data_mesgs['record']['temperature'];
            $averageTemperature = (!empty($temperatureList)) ? number_format(array_sum($temperatureList) / count($temperatureList), 1) : -200;

            $isPaused = count($monFichierFit->isPaused()) > 0;

            // Création de l'objet Activity
            $newActivity = new Activity(
                $type,
                $startDate,
                $startTime,
                $endTime,
                $effortRessenti,
                $variability,
                $variance,
                $standardDeviation,
                $average,
                $maximum,
                $minimum,
                $averageTemperature,
                $isPaused
            );

            // Ajout de l'activité et enregistrement du fichier FIT en JSON
            if ($this->authService->getCurrentUser()->getRole()->addActivity($newActivity) && $this->saveFitFileToJSON($monFichierFit)) {
                return true;
            }
        } catch (\Exception $e) {
            echo $e;
        }

        return false;
    }
}
?>