<?php

namespace App\Command\Migration;

use App\Entity\NetworkSettings;
use App\Entity\OrganizationalUnit;
use App\Model\OrganizationalUnitTypes;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(name: 'opengnsys:migration:organizational-unit', description: 'Migration data to new entities')]
class MigrateOrganizationalUnitCommand extends Command
{
    public function __construct(
        private readonly EntityManagerInterface $entityManager,
        private readonly ManagerRegistry $doctrine
    )
    {
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        /** @var EntityManagerInterface $oldDatabaseEntityManager */
        $oldDatabaseEntityManager = $this->doctrine->getManager('og_1');

        /** Obtener los centros de la base de datos antigua **/
        $rsmCenters = new ResultSetMapping();
        $rsmCenters->addScalarResult('idcentro', 'idcentro');
        $rsmCenters->addScalarResult('nombrecentro', 'nombrecentro');
        $rsmCenters->addScalarResult('comentarios', 'comentarios');

        $centersQuery = $oldDatabaseEntityManager->createNativeQuery('SELECT idcentro, nombrecentro, comentarios FROM centros', $rsmCenters);
        $centers = $centersQuery->getResult();

        /** Obtener los grupos de aulas de la base de datos antigua **/
        $rsmGroups = new ResultSetMapping();
        $rsmGroups->addScalarResult('idgrupo', 'idgrupo');
        $rsmGroups->addScalarResult('nombregrupo', 'nombregrupo');
        $rsmGroups->addScalarResult('comentarios', 'grupos.comentarios');
        $rsmGroups->addScalarResult('idcentro', 'grupos.idcentro');

        $groupsQuery = $oldDatabaseEntityManager->createNativeQuery('SELECT idgrupo, nombregrupo, grupos.comentarios, grupos.idcentro FROM grupos LEFT JOIN centros ON grupos.idcentro = centros.idcentro', $rsmGroups);
        $groups = $groupsQuery->getResult();

        /** Obtener las aulas de la base de datos antigua **/
        $rsmClassrooms = new ResultSetMapping();
        $rsmClassrooms->addScalarResult('idaula', 'idaula');
        $rsmClassrooms->addScalarResult('nombreaula', 'nombreaula');
        $rsmClassrooms->addScalarResult('comentarios', 'aulas.comentarios');
        $rsmClassrooms->addScalarResult('grupoid', 'aulas.grupoid');
        $rsmClassrooms->addScalarResult('idcentro', 'aulas.idcentro');
        $rsmClassrooms->addScalarResult('proxy', 'proxy');
        $rsmClassrooms->addScalarResult('dns', 'dns');
        $rsmClassrooms->addScalarResult('netmask', 'netmask');
        $rsmClassrooms->addScalarResult('router', 'router');
        $rsmClassrooms->addScalarResult('ntp', 'ntp');
        $rsmClassrooms->addScalarResult('timep2p', 'timep2p');
        $rsmClassrooms->addScalarResult('modp2p', 'modp2p');
        $rsmClassrooms->addScalarResult('ipmul', 'ipmul');
        $rsmClassrooms->addScalarResult('pormul', 'pormul');
        $rsmClassrooms->addScalarResult('modomul', 'modomul');
        $rsmClassrooms->addScalarResult('velmul', 'velmul');
        $rsmClassrooms->addScalarResult('pizarra', 'pizarra');
        $rsmClassrooms->addScalarResult('cagnon', 'cagnon');
        $rsmClassrooms->addScalarResult('ubicacion', 'ubicacion');

        $roomsQuery = $oldDatabaseEntityManager->createNativeQuery('SELECT idaula, nombreaula, aulas.comentarios, aulas.grupoid, aulas.idcentro,  proxy, dns, netmask, router, ntp, timep2p, modp2p, modomul, ipmul, velmul, pormul, pizarra, cagnon, ubicacion FROM aulas LEFT JOIN grupos ON aulas.grupoid = grupos.idgrupo', $rsmClassrooms);
        $rooms = $roomsQuery->getResult();

        /** Obtener los grupos de ordenadores de la base de datos antigua **/
        $rsmClientGroups = new ResultSetMapping();
        $rsmClientGroups->addScalarResult('idgrupo', 'idgrupo');
        $rsmClientGroups->addScalarResult('nombregrupoordenador', 'nombregrupoordenador');
        $rsmClientGroups->addScalarResult('comentarios', 'gruposordenadores.comentarios');
        $rsmClientGroups->addScalarResult('idaula', 'gruposordenadores.idaula');
        $clientGroupsQuery = $oldDatabaseEntityManager->createNativeQuery('SELECT idgrupo, nombregrupoordenador, gruposordenadores.comentarios, gruposordenadores.idaula FROM gruposordenadores LEFT JOIN aulas ON gruposordenadores.idaula = aulas.idaula', $rsmClientGroups);
        $clientGroups = $clientGroupsQuery->getResult();

        $organizationalUnitRepository = $this->entityManager->getRepository(OrganizationalUnit::class);

        /** Centros **/
        $output->writeln("CENTROS TOTAL: ". count($centers));
        foreach ($centers as $center){
            $centerOrganizationalUnit = null;
            $centerOrganizationalUnit = $organizationalUnitRepository->findOneBy(['migrationId' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT.'-'.$center['idcentro'], 'type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT]);
            if(!$centerOrganizationalUnit){
                $centerOrganizationalUnit = new OrganizationalUnit();
                $centerOrganizationalUnit->setMigrationId(OrganizationalUnitTypes::ORGANIZATIONAL_UNIT.'-'.$center['idcentro']);
                $centerOrganizationalUnit->setName($center['nombrecentro']);
                $centerOrganizationalUnit->setComments($center['comentarios']);
                $centerOrganizationalUnit->setType(OrganizationalUnitTypes::ORGANIZATIONAL_UNIT);
                $this->entityManager->persist($centerOrganizationalUnit);
            }
        }
        $this->entityManager->flush();

        /** Grupos de aulas **/
        $output->writeln("GRUPOS DE AULAS TOTAL: ". count($groups));
        foreach ($groups as $group){
            $groupPcOrganizationalUnit = null;
            $groupPcOrganizationalUnit = $organizationalUnitRepository->findOneBy(['migrationId' => OrganizationalUnitTypes::CLASSROOMS_GROUP.'-'.$group['idgrupo'], 'type' => OrganizationalUnitTypes::CLASSROOMS_GROUP]);
            if(!$groupPcOrganizationalUnit){
                $groupPcOrganizationalUnit = new OrganizationalUnit();
                $groupPcOrganizationalUnit->setMigrationId(OrganizationalUnitTypes::CLASSROOMS_GROUP.'-'.$group['idgrupo']);
                $groupPcOrganizationalUnit->setName($group['nombregrupo']);
                $groupPcOrganizationalUnit->setComments($group['grupos.comentarios']);
                $groupPcOrganizationalUnit->setType(OrganizationalUnitTypes::CLASSROOMS_GROUP);

                $center = $organizationalUnitRepository->findOneBy(['migrationId' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT.'-'.$group['grupos.idcentro']]);
                if ($center){
                    $groupPcOrganizationalUnit->setParent($center);
                }

                $this->entityManager->persist($groupPcOrganizationalUnit);
            }
        }
        $this->entityManager->flush();

        /** Aulas **/
        $output->writeln("AULAS TOTAL: ". count($rooms));
        foreach ($rooms as $room){
            $roomOrganizationalUnit = null;
            $roomOrganizationalUnit = $organizationalUnitRepository->findOneBy(['migrationId' => OrganizationalUnitTypes::CLASSROOM.'-'.$room['idaula'], 'type' => OrganizationalUnitTypes::CLASSROOM]);
            if(!$roomOrganizationalUnit){
                $roomOrganizationalUnit = new OrganizationalUnit();
                $roomOrganizationalUnit->setMigrationId(OrganizationalUnitTypes::CLASSROOM.'-'.$room['idaula']);
                $roomOrganizationalUnit->setName($room['nombreaula']);
                $roomOrganizationalUnit->setComments($room['aulas.comentarios']);
                $roomOrganizationalUnit->setBoard($room['pizarra']);
                $roomOrganizationalUnit->setProjector($room['cagnon']);
                $roomOrganizationalUnit->setLocation($room['ubicacion']);
                $roomOrganizationalUnit->setType(OrganizationalUnitTypes::CLASSROOM);

                $migrationId = $room['aulas.grupoid'] === 0 ? OrganizationalUnitTypes::ORGANIZATIONAL_UNIT.'-'.$room['aulas.idcentro'] : OrganizationalUnitTypes::CLASSROOMS_GROUP.'-'.$room['aulas.grupoid'];
                $organizationalUnit = $organizationalUnitRepository->findOneBy(['migrationId' => $migrationId]);

                if ($organizationalUnit){
                    $roomOrganizationalUnit->setParent($organizationalUnit);
                }

                $this->entityManager->persist($roomOrganizationalUnit);
            }

            $networkSettings = $roomOrganizationalUnit->getNetworkSettings();
            if(!$networkSettings){
                $networkSettings = new NetworkSettings();
                $roomOrganizationalUnit->setNetworkSettings($networkSettings);
                $this->entityManager->persist($networkSettings);
            }
            $networkSettings->setProxy($room['proxy']);
            $networkSettings->setDns($room['dns']);
            $networkSettings->setNetmask($room['netmask']);
            $networkSettings->setRouter($room['router']);
            $networkSettings->setNtp($room['ntp']);
            $networkSettings->setP2pTime($room['timep2p']);
            $networkSettings->setP2pMode($room['modp2p']);
            $networkSettings->setMcastIp($room['ipmul']);
            $networkSettings->setMcastSpeed($room['velmul']);
            $networkSettings->setMcastPort($room['pormul']);
            $networkSettings->setMcastMode($room['modomul']);
        }

        $this->entityManager->flush();

        /** Grupo Ordenador **/
        $output->writeln("GRUPOS ORDENADORES ". count($clientGroups));
        foreach ($clientGroups as $clientGroup){
            $groupPcOrganizationalUnit = null;
            $groupPcOrganizationalUnit = $organizationalUnitRepository->findOneBy(['migrationId' => OrganizationalUnitTypes::CLIENTS_GROUP.'-'.$clientGroup['idgrupo'], 'type' => OrganizationalUnitTypes::CLIENTS_GROUP]);
            if(!$groupPcOrganizationalUnit){
                $groupPcOrganizationalUnit = new OrganizationalUnit();
                $groupPcOrganizationalUnit->setMigrationId(OrganizationalUnitTypes::CLIENTS_GROUP.'-'.$clientGroup['idgrupo']);
                $groupPcOrganizationalUnit->setName($clientGroup['nombregrupoordenador']);
                $groupPcOrganizationalUnit->setComments($clientGroup['gruposordenadores.comentarios']);
                $groupPcOrganizationalUnit->setType(OrganizationalUnitTypes::CLIENTS_GROUP);

                $room = $organizationalUnitRepository->findOneBy(['migrationId' => OrganizationalUnitTypes::CLASSROOM.'-'.$clientGroup['gruposordenadores.idaula']]);
                if ($room){
                    $groupPcOrganizationalUnit->setParent($room);
                }

                $this->entityManager->persist($groupPcOrganizationalUnit);
            }
        }
        $this->entityManager->flush();

        return 1;
    }
}