<?php

namespace AppBundle\Export;

use AppBundle\Entity\DemandePEE;
use AppBundle\Entity\OperationPEE;
use AppBundle\Enum\DemandePEEState;
use AppBundle\Enum\DemandePEEType;
use AppBundle\Enum\DemandeCODEType;
use Symfony\Component\HttpFoundation\StreamedResponse;
use AppBundle\Enum\UserHonorific;
use AppBundle\Enum\UserJobTeacher;

/**
 *
 * @author Bastien Gatellier <contact@bgatellier.fr>
 */
class OperationPeeExporter extends AbstractExcelExporter
{
    /**
     *
     * @param  array $applications Array of arrays (and not array of DemandePEE!)
     * @param  string $filename
     * @return StreamedResponse
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function exportApplications(array $applications, string $filename): StreamedResponse
    {
       


        ini_set("max_execution_time", 60000);
        ini_set("memory_limit", "256M");
        ignore_user_abort(1);

        $headers = [
            $this->trans('form.lastname.label'),
            $this->trans('form.firstname.label'),
            $this->trans('form.email.label'),
            $this->trans('form.metier.label'),
            $this->trans('form.phone.landline.label'),
            $this->trans('form.phone.mobile.label'),
            $this->trans('form.establishment_name.label'),
            $this->trans('form.academy.label'),
            $this->trans('form.city.label'),
            $this->trans('form.shoeSize.label'),
            $this->trans('form.acceptPhotos.label'),
            $this->trans('form.expectation.label'),
            $this->trans('form.external_inscription.label')
        ];

        $rows = [];
        foreach ($applications as $application) {
           if ($application['type'] != "")
                {
                    $applicationType = $this->constTranslator->trans(DemandePEEType::class, $application['type']);
                    $applicationType =  strip_tags(array_shift($applicationType));
                } else {
                    $applicationType = "";
                }

            //$honorifics = $this->constTranslator->trans(UserHonorific::class, $application['cuser']['honorific']);

           

            $teacherJob = ($application['cuser']['job'] == "" || $application['cuser']['job'] == "other") ? $application['cuser']['jobOther'] : array_shift($this->constTranslator->trans(UserJobTeacher::class, $application['cuser']['job']));

            $rows[] = [
                $application['cuser']['lastname'],
                $application['cuser']['firstname'],
                $application['cuser']['email'],
                $teacherJob,
                $application['cuser']['phone'],
                $application['cuser']['mobile'],
                $application['cuser']['establishment'] ?? $application['cuser']['establishmentName'],
                $application['cuser']['academy'],
                $application['cuser']['establishmentCity'],
                $application['cuser']['shoeSize'],
                $application['cuser']['photograph'],
                $application['cuser']['expectations'],
                $applicationType
            ];
        }
        $this->createSpreadsheet($headers, $rows, $filename);

        $this->saveTo('uploads/export/');

        return $this->createStreamedResponse();
    }

    /**
     * @param DemandePEE[] $applications
     * @param string $filename
     * @return StreamedResponse
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function exportApplicationsStatistics(array $applications, string $filename): StreamedResponse
    {
        ini_set("max_execution_time", 60000);
        ini_set("memory_limit", "256M");
        ignore_user_abort(1);

        $applicationsQty = count($applications);
        $rows = []; // Rows that will be written in the file

        // Récupération du nombre de demandes par utilisateur, puis du maximum de demande / utilisateur
        $applicationsQtyPerUser = [];
        foreach ($applications as $application) {
            $userId = $application->getCuser()->getId();

            if (isset($applicationsQtyPerUser[$userId])) {
                $applicationsQtyPerUser[$userId]++;
            } else {
                $applicationsQtyPerUser[$userId] = 1;
            }
        }
        $applicationsQtyMax = max($applicationsQtyPerUser);
        
        // Création des en-têtes de colonne
        $headers = [
            'Professeur: nom',
            'Professeur: discipline',
            'Professeur: Email',
            'Établissement: nom',
            'Établissement: ' . lcfirst($this->trans('form.city.label')),
            'Établissement: ' . lcfirst($this->trans('form.academy.label')),
            'Établissement: Email Chef d\'établissement',
            'Nombre de visites',
        ];
        for ($i = 0; $i < $applicationsQtyMax; $i++) {
            $visitQty = $i + 1;

            $headers[] = "Visite $visitQty: entreprise";
            $headers[] = "Visite $visitQty: date de la visite";
            $headers[] = "Visite $visitQty: état de la demande";
            $headers[] = "Visite $visitQty: " . mb_strtolower($this->trans('form.externalRegistration.label'));
        }

        $row = [];

        // Création du contenu (les demandes doivent être regroupées par utilisateur)
        $userIdPrevious = null;
        foreach ($applications as $key => $application) {
            $user = $application->getCuser();
            $userId = $user->getId();
            $operation = $application->getOperationpee();
            if($operation) {
                // Si l'ID de l'utilisateur change
                if ($userId != $userIdPrevious) {
                
                    $userHonorifics = $this->constTranslator->trans(UserHonorific::class, $user->getHonorific());

                    $teacher = array_shift($userHonorifics);
                    if ($teacher) {
                        $teacher .= ' ';
                    }
                    
                    $teacher .= $user->getFullName();
            

                    
                    $teacherJob = ($user->getJob() == "" || $user->getJobOther() == "other") ? $user->getJobOther() : array_shift($this->constTranslator->trans(UserJobTeacher::class, $user->getJob()));



                    $row = [
                        $teacher,
                        $teacherJob,
                        $user->getEmail(),
                        $user->getEstablishmentName(),
                        $user->getEstablishmentCity(),
                        $user->getAcademy(),
                        ($user->getBossEmail() ?? $user->getEstablishmentEmail()),
                        $applicationsQtyPerUser[$userId],
                    ];
                }
                
                if ($application->getType() != "")
                {
                    $applicationType = $this->constTranslator->trans(DemandePEEType::class, $application->getType());
                    $applicationType =  strip_tags(array_shift($applicationType));
                } else {
                    $applicationType = "";
                }
                
           

                $row[] = join(' ', [$operation->getCompany(), $operation->getSite()]);
                if (!is_null($operation->getDateVisite())) {
                    $dateVisite = $operation->getDateVisite()->format('d/m/Y');
                } else {
                    $dateVisite = "";
                }
                $row[] = $dateVisite;
                $row[] = $application->getState();
                $row[] = $applicationType;
                //$row[] = $application->getType();

                // Dump the row if:
                // - we reached the end of the list
                // - OR the next user is different from the current one
                if ($key === $applicationsQty - 1 || $userId !== $applications[$key +1]->getCuser()->getId()) {
                    $rows[] = $row; //
                }

                $userIdPrevious = $userId;
            }
        }

        $this->createSpreadsheet($headers, $rows, $filename);

        $this->saveTo('uploads/export/');

        return $this->createStreamedResponse();
       
    }

    /**
     * @param OperationPEE[] $operations
     * @param string $filename
     * @return StreamedResponse
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function exportOperations(array $operations, string $filename): StreamedResponse
    {
        ini_set("max_execution_time", 60000);
        ini_set("memory_limit", "256M");
        ignore_user_abort(1);

        $rows = []; // Rows that will be written in the file

        $headers = array(
            'État',
            'Date visite',
            'Entreprise',
            'Site',
            'Ville',
            'Académie',
            'Nombre personne max',
            'Nb inscrit',
            'Nb pré-inscrit',
            'Nb attente',
            'Nb désistement',
            'Taux de remplissage',
        );

        foreach ($operations as $operation) {
            // TODO: avoid doing 4 additional requests per loop
            $countRegistered = $this->countApplications($operation, DemandePEEState::REGISTERED);
            $countPreregistered = $this->countApplications($operation, DemandePEEState::PREREGISTERED);
            $countWaiting = $this->countApplications($operation, DemandePEEState::WAITING);
            $countWithdrawal = $this->countApplications($operation, DemandePEEState::WITHDRAWAL);

            $nb_participants_max = $operation->getNbPeople();

            $row = array(
                $this->trans('word.state.operationPEE.' . $operation->getState() . '.label', [], 'word'),
                '' != $operation->getDateVisite() ? $operation->getDateVisite()->format('d/m/Y') : null,
                $operation->getCompany(),
                $operation->getSite(),
                $operation->getCity(),
                $operation->getAcademy(),
                $operation->getNbPeople(),
                $countRegistered,
                $countPreregistered,
                $countWaiting,
                $countWithdrawal,
                $nb_participants_max > 0 ? round($countRegistered / $nb_participants_max * 100, 1) : 0,
            );

            $rows[] = $row;
        }

        $this->createSpreadsheet($headers, $rows, $filename);

        $this->saveTo('uploads/export/');

        return $this->createStreamedResponse();
    }

    /**
     * Get the number of applications in the given state, for a given operation.
     * @param OperationPEE $operation
     * @param string $state
     * @return int
     */
    private function countApplications(OperationPEE $operation, string $state)
    {
        $applications = $operation->getDemandepee()->filter(function(DemandePEE $application) use ($state) {
            return $state === $application->getState();
        });

        return count($applications);
    }
}
