<?php

namespace App\Command;

use App\Entity\Interval;
use App\Entity\Filial;
use App\Entity\Department;
use App\Entity\Specialist;
use App\Entity\Location;
use App\Entity\Review;
use App\Entity\Schedule;
use App\Entity\Idoctor;
use App\Entity\Price;
use App\Bundle\Infoclinica\Rest;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\DependencyInjection\ContainerInterface;
use App\Bundle\Bitrix\Request as Bitrix;
use App\Bundle\Infoclinica\Request as InfoclinicaRequest;
use App\Bundle\Notisend\Request as NotisendRequest;

class InfoclinicaCommand extends Command
{
    private $container;

    public function __construct(ContainerInterface $container)
    {
        parent::__construct();
        $this->container = $container;
    }

    protected static $defaultName = 'app:Infoclinica';
    protected static $defaultDescription = 'Add a short description for your command';

    protected function configure(): void
    {
        $this
            ->setDescription(self::$defaultDescription)
            ->addArgument('var', InputArgument::OPTIONAL, 'variant update table')
            ->addOption('option1', null, InputOption::VALUE_NONE, 'Option description')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $infoclinica = new Rest();
        $entityManager = $this->container->get('doctrine')->getManager();
        $io = new SymfonyStyle($input, $output);

        $var = $input->getArgument('var');

        //  php bin/console app:Infoclinica departaments
        if ($var == 'departaments') {
            $departments = $infoclinica->getDepartments();

            if ($departments['response']['success'] == true) {
                foreach ($departments['response']['data'] as $item) {
                    $department = $entityManager->getRepository(Department::class)
                        ->findOneBy(['did' => $item['id'], 'onlineMode' => $item['onlineMode']]);

                    if (is_null($department)) {
                        $department = new Department;
                    }
                    
                    if (empty($item['viewInWeb'])) {
                        $item['viewInWeb'] = 0;
                    }

                    $department
                        ->setAlias('')
                        ->setActive($item['viewInWeb'])
                        ->setDid($item['id'])
                        ->setName($item['name'])
                        ->setGroupName($item['groupName'])
                        ->setOnlineMode($item['onlineMode']);

                    $entityManager->persist($department);
                    $entityManager->flush();
                    $io->success('id '. $department->getId() .' updated');
                }

            } else {
                $io->error('departament not updated');
            }

        // php bin/console app:Infoclinica reviews
        } elseif ($var == 'reviews') {
            $bitrix = Bitrix::init();
            $locations = $entityManager->getRepository(Location::class)
                ->findAll();

            foreach ($locations as $location) {
                try {
                    $reviews = $bitrix->getReviews($location->getDcode(), $location->getSpecialist()->getInfoclinica());
                } catch (Exception $e) {
                    $io->error($location->getSpecialist()->getId());
                    $io->error($e->getErrors());
                }

                $chunksize = count($reviews) - 1;

                foreach ($reviews as $key => $params) {
                    $review = $entityManager->getRepository(Review::class)
                        ->findOneBy(['bitrixId' => $params['REVIEW_ID']]);
                    
                    $active = ($params['DATA'][0]["ACTIVE"] == 'Y')? true: false;
                    
                    if (! $review) {
                        if (! $active) {
                            continue;
                        }

                        $review = new Review;
                    }
                    $dateCreate = \DateTime::createFromFormat(
                        'Y-m-d H:i:s', 
                        $params['DATA'][0]["DATE_CREATE"]
                    );

                    $review
                        ->setBitrixId((int) $params['REVIEW_ID'])
                        ->setSpecialist($location->getSpecialist())
                        ->setRating(5)
                        ->setMessage('')
                        ->setAuthor('')
                        ->setActive($active)
                        ->setDateCreate($dateCreate);

                    foreach ($params['DATA'] as $data) {
                        if ($data['CODE'] == "NAME") {
                           $review->setAuthor(trim(strip_tags($data['VALUE'])));
                        }

                        if ($data['CODE'] == "MESSAGE") {
                           $review->setMessage(trim(strip_tags($data['VALUE'])));
                        }

                        if ($data['CODE'] == "SOURCE_LINK") {
                            $re = '/(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])/m';
                            preg_match_all($re, $data['VALUE'], $matches, PREG_SET_ORDER, 0);

                            if (! empty($matches[0][0])) {
                                $review->setSource($matches[0][0]);
                            }
                        }

                        if ($data['CODE'] == "RATING") {
                           $review->setRating((int) $data['VALUE']);
                        }
                    }

                    $entityManager->persist($review);

                    if ($chunksize == $key) {
                        $entityManager->flush();
                        $io->success('review in '. $review->getId(). ' updated rows: ' . $chunksize);
                        $chunksize = 0;
                    }
                }
            }

        // php bin/console app:Infoclinica schedules
        } elseif ($var == 'schedules') {
            $specialists = $entityManager->getRepository(Specialist::class)
                ->findAll();
            
            foreach ($specialists as $specialist) {
                $fid = NULL;

                if (! empty($filial = $specialist->getFilial())) {
                    $fid = $filial->getFid();
                }

                $io->error('specialist id:' . $specialist->getSid() 
                    . ' department id:' . $specialist->getDepartment()->getDid()
                    . ' filial id:' . $fid
                    . ' onlineMode:' . $specialist->getOnlineMode()
                );
                
                $schedules =$infoclinica->getSchedule(
                    $specialist->getSid(),
                    $specialist->getDepartment()->getDid(), 
                    date('ymd', time()),
                    $fid,
                    $specialist->getOnlineMode()
                );

                if (! empty($schedules['response']['data'])) {
                    if ($schedules['response']['success'] == true) {
                        foreach ($schedules['response']['data'] as $data) {
                            foreach($data['intervals'] as $interval) {                           
                                $startInterval = \DateTime::createFromFormat(
                                    'H:i', 
                                    $interval['startInterval']
                                );
                                $endInterval = \DateTime::createFromFormat(
                                    'H:i', 
                                    $interval['endInterval']
                                );

                                $schedule = $entityManager->getRepository(Schedule::class)
                                    ->findOneBy([
                                        'schedident' => $interval['schedident'],
                                        'startInterval' => $startInterval,
                                        'endInterval' => $endInterval
                                    ]);
                                

                                if (is_null($schedule)) {
                                    $schedule = new Schedule;
                                }
                                
                                $workDate = \DateTime::createFromFormat(
                                    'Ymd', 
                                    $interval['workDate']
                                );

                                $schedule
                                    ->setSpecialist($specialist)
                                    ->setFilial($specialist->getFilial())
                                    ->setDepartment($specialist->getDepartment())
                                    ->setSchedident($interval['schedident'])
                                    ->setIsFree($interval['isFree'])
                                    ->setIsAvailable($interval['isAvailable'])
                                    ->setOnlineMode($specialist->getOnlineMode())
                                    ->setStartInterval($startInterval)
                                    ->setEndInterval($endInterval)
                                    ->setWorkDate($workDate);
                                
                                $entityManager->persist($schedule);
                                $entityManager->flush();
                                $io->success('schedident in '. $schedule->getSchedident(). ' updated');
                            }
                        }
                    }
                } else {
                    $io->error('specialist id:' . $specialist->getSid() 
                        . 'department id:' . $specialist->getDepartment()->getDid()
                        . 'filial id:' . $fid
                    );

                    $io->error('schedident in '. $schedule->getSchedident(). ' not updated');
                }
            }

        // php bin/console app:Infoclinica intervals
        } elseif ($var == 'intervals') {
            $specialists = $entityManager->getRepository(Specialist::class)
                ->findAll();

            foreach ($specialists as $specialist) {
                $fid = NULL;

                if (! empty($filial = $specialist->getFilial())) {
                    $fid = $filial->getFid();
                }

                $intervals = $infoclinica->getInterval(
                    $specialist->getSid(),
                    $specialist->getDepartment()->getDid(), 
                    date('ymd', time()),
                    $fid,
                    $specialist->getOnlineMode()
                );

                if (! empty($intervals)) {
                    foreach ($intervals as $data) {
                        foreach ($data as $intervalData) {
                            $interval = $entityManager->getRepository(Interval::class)
                                ->findOneBy([
                                    'schedident' => $intervalData['schedident'],
                                    'time' => $intervalData['time'],
                                    'workDate' => $intervalData['workDate']
                                ]);

                            if (is_null($interval)) {
                                $interval = new Interval;
                            }

                            $interval
                                ->setWorkDate($intervalData['workDate'])
                                ->setSpecialist($specialist)
                                ->setDepartment($specialist->getDepartment())
                                ->setSchedident($intervalData['schedident'])
                                ->setTime($intervalData['time'])
                                ->setRnum($intervalData['rNum'])
                                ->setIsFree($intervalData['isFree']);
                            
                            $entityManager->persist($interval);
                            $entityManager->flush(); 
                            $io->success('interval in '. $interval->getId(). ' updated');
                        }
                    }
                } else {
                    $io->error('intervals '. $specialist->getSid(). ' in not updated');   
                    var_dump($intervals);
                }
            }
        }

        return Command::SUCCESS;
    }
}
