<?php

namespace AppBundle\Command;

use AppBundle\Entity\Distance;
use AppBundle\Entity\Preference;
use AppBundle\Enum\PreferenceKm;
use Doctrine\ORM\Query;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Clear user preferences: remove the one where the distance between the 2 users
 * is higher than the defined value.
 * @deprecated The Distance table is gone. This code has to be updated inorder to work!
 */
class CleanPreferencesCommand extends ContainerAwareCommand
{
    /**
     * 
     */
    protected function configure()
    {
        $this
            ->setName('cgenial:preferences:clean')
            ->setDescription("Clear user preferences: remove the one where the distance between the 2 users is higher than the defined value.");
    }

    /**
     * 
     * @param InputInterface $input 
     * @param OutputInterface $output 
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $em = $this->getContainer()->get("doctrine.orm.entity_manager");
        $progress = new ProgressBar($output, 2);

        // Get the preferences where the distance is higher than the maximum value
        $distances1 = $em->createQueryBuilder()
            ->select('distance, teacher, preference')
            ->from(Distance::class, 'distance')
            ->innerJoin('distance.prof', 'teacher')
            ->innerJoin('teacher.preferencemain', 'preference', 'with', 'preference.selectedUser = distance.inge')
            ->where('distance.km > :distance_km')
            ->setParameter(':distance_km', PreferenceKm::DISTANCE_MAX_INTERVENANTS)
            ->getQuery()
            ->getResult(Query::HYDRATE_ARRAY)
        ;

        $progress->advance();

        // Get the preferences where the distance is higher than the maximum value.
        // Reverse query as the preference is not reflexive:
        // if Sergio has a preference for Mohamed does not mean that Mohamed as a preference for Sergio.
        $distances2 = $em->createQueryBuilder()
            ->select('distance, engineer, preference')
            ->from(Distance::class, 'distance')
            ->innerJoin('distance.inge', 'engineer')
            ->innerJoin('engineer.preferencemain', 'preference', 'with', 'preference.selectedUser = distance.prof')
            ->where('distance.km > :distance_km')
            ->setParameter(':distance_km', PreferenceKm::DISTANCE_MAX_INTERVENANTS)
            ->getQuery()
            ->getResult(Query::HYDRATE_ARRAY)
        ;

        // Get the preferences identifiers
        $preferences1Ids = array_map(function($d) {
            return $d['prof']['preferencemain'][0]['id'];
        }, $distances1);

        $preferences2Ids = array_map(function($d) {
            return $d['inge']['preferencemain'][0]['id'];
        }, $distances2);

        // Merge the results
        $preferencesIds = array_merge($preferences1Ids, $preferences2Ids);

        // Remove the preferences
        $em->createQueryBuilder()
            ->delete(Preference::class, 'p')
            ->where('p.id IN(:p_id)')
            ->setParameter('p_id', $preferencesIds)
            ->getQuery()
            ->execute()
        ;

        $progress->finish();
    }
}
