<?php

declare(strict_types=1);

/*
 * This file is part of the Sonata Project package.
 *
 * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace App\Exporter;

use App\Entity\Adherent;
use App\Entity\Prestataire;
use App\Utils\CotisationUtils;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Sonata\Exporter\Source\AbstractPropertySourceIterator;
use Sonata\Exporter\Source\SourceIteratorInterface;

/**
 * @final since sonata-project/exporter 2.4.
 */
class CustomDoctrineORMQuerySourceIterator extends AbstractPropertySourceIterator implements SourceIteratorInterface
{
    /**
     * @var Query
     */
    protected $query;
    protected $em;
    protected $cotisationUtils;

    /**
     * @param array<string> $fields Fields to export
     */
    public function __construct(CotisationUtils $cotisationUtils, EntityManagerInterface $em, Query $query, array $fields, string $dateTimeFormat = 'r')
    {
        $this->em = $em;
        $this->cotisationUtils = $cotisationUtils;
        $this->query = clone $query;
        $this->query->setParameters($query->getParameters());
        foreach ($query->getHints() as $name => $value) {
            $this->query->setHint($name, $value);
        }

        parent::__construct($fields, $dateTimeFormat);
    }

    public function current()
    {
        $current = $this->iterator->current();

        $data = $this->getCurrentData($current[0]);

        // Add for kohinos
        if (!empty($data['Id']) && !empty($data['Raison'])) {
            //presta
            $presta = $this->em->getRepository(Prestataire::class)->findOneById($data['Id']);
            $cotisEnd = $this->cotisationUtils->isCotisationValidForPresta($presta);
            $data['Cotisation à jour'] = $cotisEnd == false ? '' : ($cotisEnd->format('d/m/Y'));
            $firstCotis = $this->cotisationUtils->getFirstCotisationForPresta($presta);
            $data['Première Cotisation'] = $firstCotis == false ? '' : ($firstCotis->format('d/m/Y'));
        } else if (!empty($data['Id']) && !empty($data['Email'])) {
            //adherent
            $adherent = $this->em->getRepository(Adherent::class)->findOneById($data['Id']);
            $cotisEnd = $this->cotisationUtils->isCotisationValidForAdherent($adherent);
            $data['Cotisation à jour'] = $cotisEnd == false ? '' : ($cotisEnd->format('d/m/Y'));
            $firstCotis = $this->cotisationUtils->getFirstCotisationForAdherent($adherent);
            $data['Première Cotisation'] = $firstCotis == false ? '' : ($firstCotis->format('d/m/Y'));
            $adminRoles = '';
            if (!empty($adherent->getUser())) {
                foreach ($adherent->getUser()->getPossiblegroups() as $group) {
                    if (!empty($adminRoles)) {
                        $adminRoles .= ', ';
                    }
                    $adminRoles .= $group->getName();
                    if ($group->getName() == 'Comptoir') {
                        $adminRoles .= '(' . implode(',', $adherent->getUser()->getComptoirsgeres()->toArray()) . ')';
                    } else if ($group->getName() == 'Prestataire') {
                        $adminRoles .= '(' . implode(',', $adherent->getUser()->getPrestataires()->toArray()) . ')';
                    } else if ($group->getName() == 'Caissier') {
                        $adminRoles .= '(' . implode(',', $adherent->getUser()->getCaissiers()->toArray()) . ')';
                    } else if ($group->getName() == 'Gestionnaire de Groupe' || $group->getName() == 'Contact') {
                        $adminRoles .= '(' . implode(',', $adherent->getUser()->getGroupesgeres()->toArray()) . ')';
                    }
                }
            }
            $data["Droits d'administration"] = $adminRoles;
        }

        $this->query->getEntityManager()->clear();

        return $data;
    }

    final public function rewind(): void
    {
        $this->iterator = $this->query->iterate();
        $this->iterator->rewind();
    }
}
