<?php

namespace App\Admin;

use App\Entity\Adherent;
use App\Entity\SolidoumeParameter;
use App\Entity\User;
use App\Utils\LogEntryTrait;
use Knp\Menu\ItemInterface;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\Form\Type\DateTimeRangePickerType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
use Symfony\Component\Validator\Constraints\LessThanOrEqual;
use Symfony\Component\Validator\Constraints\NotBlank;

/**
 * Administration des participations à Solidoume.
 *
 * KOHINOS : Outil de gestion de Monnaie Locale Complémentaire
 *
 * @author Julien Jorry <julien.jorry@gmail.com>
 */
class SolidoumeAdmin extends AbstractAdmin
{
    use LogEntryTrait;

    protected $baseRouteName = 'solidoume';
    protected $baseRoutePattern = 'solidoume';
    protected $security;

    protected $datagridValues = [
        // reverse order (default = 'ASC')
        '_sort_order' => 'DESC',
        // name of the ordered field (default = the model's id field, if any)
        '_sort_by' => 'createdAt',
        '_page' => 1,
        '_per_page' => 100,
    ];

    /**
     * {@inheritdoc}
     */
    protected function configureFormFields(FormMapper $formMapper)
    {
        $item = $this->getSubject();
        $user = $this->getConfigurationPool()->getContainer()->get('security.token_storage')->getToken() ? $this->getConfigurationPool()->getContainer()->get('security.token_storage')->getToken()->getUser() : null;
        $em = $this->getConfigurationPool()->getContainer()->get('doctrine');
        $adherents = $em->getRepository(Adherent::class)->findOrderByName();
        $cotisationMaximum = $em->getRepository(SolidoumeParameter::class)->getValueOf('maximum');
        $cotisationMinimum = $em->getRepository(SolidoumeParameter::class)->getValueOf('minimum');

        $formMapper
            ->add('user', HiddenType::class, [
                'data' => $user,
                'data_class' => null,
                'entity_class' => User::class,
                'em' => $this->getConfigurationPool()->getContainer()->get('doctrine')->getManager(),
            ])
            ->add('adherent', EntityType::class, [
                'class' => Adherent::class,
                'choices' => $adherents,
                'placeholder' => 'Choisir un adherent',
                'choice_label' => function ($adherent) {
                    return $adherent->getUser() ? ($adherent->getUser()->getLastname() . ' ' . $adherent->getUser()->getFirstname() . ' (' . $adherent->getUser()->getEmail() . ')') : $adherent->__toString();
                },
                'required' => false,
                'label' => false,
            ])
            ->add('amount', MoneyType::class, [
                'label' => 'Montant en euro(s) entre ' . $cotisationMinimum . ' et ' . $cotisationMaximum,
                'required' => true,
                'scale' => 2,
                'constraints' => [
                    new NotBlank(),
                    new LessThanOrEqual(['value' => $cotisationMaximum]),
                    new GreaterThanOrEqual(['value' => $cotisationMinimum]),
                ],
            ])
            ->add('paiementDate', ChoiceType::class, [
                'label' => 'Date de prélèvement',
                'required' => false,
                'choices' => range(1, 28),
                'choice_label' => function ($choice) {
                    return $choice;
                },
            ])
            ->add('isRecurrent', CheckboxType::class, [
                'label' => 'Paiement récurrent (tous les mois) ?',
                'required' => false,
                'label_attr' => ['class' => 'checkbox-inline'],
            ])
            ->add('isDonation', CheckboxType::class, [
                'label' => 'Est-ce une donation (sans participation au programme) ?',
                'required' => false,
                'label_attr' => ['class' => 'checkbox-inline'],
            ])
            ->add('enabled', CheckboxType::class, [
                'label' => 'Activé ?',
                'required' => false,
                'label_attr' => ['class' => 'checkbox-inline'],
            ])
        ;
    }

    /**
     * {@inheritdoc}
     */
    protected function configureListFields(ListMapper $listMapper)
    {
        unset($this->listModes['mosaic']);
        $listMapper
            ->add('user', null, ['label' => 'Utilisateur'])
            ->add('adherent', null, ['label' => 'Adhérent'])
            ->add('amount', null, ['label' => 'Montant'])
            ->add('paiementDate', null, ['label' => 'Date de prélèvement'])
            ->add('isDonation', null, ['label' => 'Donation'])
            ->add('isRecurrent', null, ['label' => 'Récurrent'])
            ->add('createdAt', 'date', [
                'pattern' => 'dd/MM/YYYY HH:mm',
                'label' => 'Création',
            ])
            ->add('updatedAt', 'date', [
                'pattern' => 'dd/MM/YYYY HH:mm',
                'label' => 'Mis à jour',
            ])
            ->add('enabled', null, ['label' => 'Activé ?'])
            ->add('comments', null, [
                'label' => 'Commentaires',
                'editable' => true,
            ])
            // ->add('lastMonthPayed', null, [
            //     'label' => 'Dernier prélèvement',
            //     'template' => '@kohinos/bundles/SonataAdminBundle/CRUD/list_solidoume_lastmonthpayed.html.twig',
            // ])
            ->add('allPrelevement', null, [
                    'label' => 'Prélèvements',
                    'template' => '@kohinos/bundles/SonataAdminBundle/CRUD/list_solidoume_prelevements.html.twig',
                ])
                ->add('allRedistribution', null, [
                    'label' => 'Redistributions',
                    'template' => '@kohinos/bundles/SonataAdminBundle/CRUD/list_solidoume_redistributions.html.twig',
                ])
            ->add('_action', null, [
                'actions' => [
                    'show' => [],
                    'edit' => [],
                ],
            ]);
    }

    /**
     * {@inheritdoc}
     */
    public function configure()
    {
        parent::configure();
        $this->setTemplate('list', '@kohinos/bundles/SonataAdminBundle/CRUD/solidoume_list.html.twig');
    }

    /**
     * {@inheritdoc}
     */
    protected function configureShowFields(ShowMapper $showMapper): void
    {
        $object = $showMapper->getAdmin()->getSubject();
        $showMapper
            ->add('createdAt', null, ['label' => 'Date d\'adhésion'])
            ->add('user', null, ['label' => 'Utilisateur'])
            ->add('adherent', null, ['label' => 'Adhérent'])
            ->add('amount', null, ['label' => 'Montant'])
            ->add('paiementDate', null, ['label' => 'Date de prélèvement'])
            ->add('isDonation', null, ['label' => 'Donation'])
            ->add('isRecurrent', null, ['label' => 'Récurrent'])
            ->add('enabled', null, ['label' => 'Activé ?'])
            ->add('comments', null, ['label' => 'Commentaires'])
            ->add('allPrelevement', null, [
                'label' => 'Prélèvements',
                'template' => '@kohinos/bundles/SonataAdminBundle/CRUD/show_solidoume_prelevements.html.twig',
            ])
            ->add('allRedistribution', null, [
                'label' => 'Redistributions',
                'template' => '@kohinos/bundles/SonataAdminBundle/CRUD/show_solidoume_redistributions.html.twig',
            ])
        ->end()
        ;
        $this->addLogEntries($showMapper, 'col-md-12');
    }

    /**
     * {@inheritdoc}
     */
    protected function configureSideMenu(ItemInterface $menu, string $action, AdminInterface $childAdmin = null)
    {
        if (!$childAdmin && !in_array($action, ['list'])) {
            return;
        }

        $menu->addChild('Paramètres', [
            'uri' => $this->getConfigurationPool()->getContainer()->get('router')->generate('solidoumeparam_list', [], UrlGeneratorInterface::ABSOLUTE_URL),
        ])->setAttribute('icon', 'fa fa-cogs');

        $menu->addChild('Redistributions', [
            'uri' => $this->getConfigurationPool()->getContainer()->get('router')->generate('solidoumeparam_redistribution', [], UrlGeneratorInterface::ABSOLUTE_URL),
        ])->setAttribute('icon', 'fa fa-list');
    }

    /**
     * {@inheritdoc}
     */
    public function getBatchActions()
    {
        $actions = parent::getBatchActions();
        unset($actions['delete']);

        return $actions;
    }

    public function getExportFields()
    {
        return [
            'Id' => 'id',
            'Adhérent' => 'adherent.fullname',
            'Adhérent email' => 'adherent.email',
            'Date de prélèvement' => 'paiementDate',
            'Montant' => 'amount',
            'Activé ?' => 'enabled',
            'Récurrent ?' => 'isRecurrent',
            'Don ?' => 'isDonation',
            'Crée le' => 'createdAt',
            'Mise à jour le' => 'updatedAt',
            'Commentaires' => 'comments',
        ];
    }

    /**
     * {@inheritdoc}
     */
    protected function configureDatagridFilters(DatagridMapper $datagridMapper): void
    {
        $datagridMapper
            ->add('enabled', null, [
                'label' => 'Activé',
                'show_filter' => true,
                'advanced_filter' => false,
            ])
            ->add('isRecurrent', null, [
                'label' => 'Récurrent ?',
                'advanced_filter' => false,
            ])
            ->add('isDonation', null, [
                'label' => 'Donation ?',
                'advanced_filter' => false,
            ])
            ->add('createdAt', 'doctrine_orm_datetime_range', [
                'field_type' => DateTimeRangePickerType::class,
                'label' => 'Date de création',
            ])
            ->add('updatedAt', 'doctrine_orm_datetime_range', [
                'field_type' => DateTimeRangePickerType::class,
                'label' => 'Date de mise à jour',
            ])
        ;
    }
}
