<?php

namespace App\Controller;

use App\Entity\User;
use App\Bundle\Infoclinica\Region;
use App\Bundle\Infoclinica\Rest;
use App\Form\RegistrationFormType;
use App\Form\SettingType;
use App\Form\RefundType;
use App\Repository\UsrlogRepository;
use App\Entity\Usrlog;
use App\Security\LoginFormAuthenticator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;

class SecurityController extends AbstractController
{
    public function __construct(CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
    {
        $this->csrfTokenManager = $csrfTokenManager;
        $this->passwordEncoder = $passwordEncoder;
    }
    
    /**
     * @IsGranted("ROLE_USER")
     * @Route("/refund", name="security_refund", methods={"GET", "POST"})
     */
    public function refund(Request $request): Response
    {
        $refundForm = new RefundType();
        $form = $this->createForm(RefundType::class, $refundForm);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            if ($request->request->get('filial') == 3) {
                $to = 'info.mmc@sova.clinic, i.cherednichenko@sova.clinic, y.belova@sova.clinic';
                $company_name = 'АО «Многопрофильный медицинский центр»';
                $company_director = 'Бушеневой С.Н.';
                $to_mail = 'vozvrat-vlg@sova.clinic';
            } else {
                $to = 'i.cherednichenko@sova.clinic, v.karpova@sova.clinic, n.ermakova@sova.clinic';
                $company_name = 'АО «МЛДК»';
                $company_director = 'Бурлаковой  Н.Ф.';
                $to_mail = 'vozvrat@sova.clinic';
            }

            $subject = "Пациент сформировал заявление на возврат средств по онлайн консультации";
            $headers = 'From: ' . $request->request->get('email') . "\r\n" .
                'Reply-To: ' . $request->request->get('email') . "\r\n" .
                'X-Mailer: PHP/' . phpversion();
            $message = "Здравствуйте. Пациент сформировал заявление на возврат средств по онлайн консультации. Ожидаем отправки заявления с почты пациента.\r\n Данные по консультации:\r\n";
            $message .= 'ФИО пациента:' . $form->get('fio')->getData() ."\r\n";
            $message .= 'Телефон пациента:' . $request->request->get('phone') ."\r\n";
            $message .= 'Врач:' . $request->request->get('docName') ."\r\n";
            $message .= 'Индификатор записи:' . $request->request->get('schedident') ."\r\n";
            $message .= 'Сумма возврата:' . $form->get('sum')->getData() ."\r\n";
            $message .= 'Дата платежа:' . $form->get('refund_date')->getData()->format('d.m.Y') ."\r\n";

            mail($to, $subject, $message, $headers);

            $html = $this->render('security/refund_blank.html.twig', [
                'template' => Region::getTemplite(),
                'to_email' => $to_mail,
                'title' => 'Заявление на возврат',
                'company_name' => $company_name,
                'company_director' => $company_director,
                'address' => $request->request->get('address'),
                'phone' => $request->request->get('phone'),
                'email' => $request->request->get('email'),
                'current_date' => \date('Y-m-d'),
                'fio' => $form->get('fio')->getData(),
                'passport_serial' => explode(' ', $form->get('passport_serial')->getData())[0],
                'passport_number' => explode(' ', $form->get('passport_serial')->getData())[1],
                'passport_issued' => $form->get('passport_issued')->getData(),
                'passport_date' => $form->get('passport_date')->getData()->format('d.m.Y'),
                'refund_bases' => $form->get('refund_bases')->getData(),
                'sum' => $form->get('sum')->getData(),
                'refund_date' => $form->get('refund_date')->getData()->format('d.m.Y')
            ]);

            $mpdf = new \Mpdf\Mpdf();
            $mpdf->WriteHTML($html);
            $mpdf->Output();
        }

        return $this->render('security/refund_form.html.twig', [
            'form' => $form->createView(),
        ]);
    }

    /**
     * @IsGranted("ROLE_USER")
     * @Route("/case-history", name="security_case_history")
     */
    public function case_history(): Response
    {
        return $this->render('security/case_history.html.twig', [
            'template' => Region::getTemplite(),
            'title' => 'Приемы'
        ]);
    }

    /**
     * @IsGranted("ROLE_USER")
     * @Route("/referrals", name="security_referrals")
     */
    public function referrals(): Response
    {
        $referrals = [];

        return $this->render('security/referrals.html.twig', [
            'referrals' => $referrals,
            'template' => Region::getTemplite(),
            'title' => 'Результаты анализов',
        ]);
    }

    /**
     * @IsGranted("ROLE_USER")
     * @Route("/security-card", name="security_card")
     */
    public function securityCard(): Response
    {
        return $this->render('security/card.html.twig', [
            'template' => Region::getTemplite(),
            'title' => 'Медицинская карта',
        ]);
    }

    /**
     * @IsGranted("ROLE_USER")
     * @Route("/payment", name="security_payment")
     */
    public function payment(): Response
    {
        return $this->render('security/payment.html.twig', [
            'template' => Region::getTemplite(),
            'title' => 'Финансы',
        ]);
    }

    /**
     * @IsGranted("ROLE_USER")
     * @Route("/setting", name="security_setting")
     */
    public function setting(
        Request $request, 
        UserPasswordEncoderInterface $passwordEncoder
    ): Response
    {
        $user = $this->getUser();
        $form = $this->createForm(SettingType::class, $user);
        $form->handleRequest($request);
        $response = [];

        if ($request->getMethod() == 'POST') {
            
            $user->setToken($form->get('plainPassword')->getData());
            $user->setPassword(
                $passwordEncoder->encodePassword(
                    $user,
                    $form->get('plainPassword')->getData()
                )
            );

            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($user);
            $entityManager->flush();
        

            return $this->json([
                'success' => true,
                'redirect' => '/'
            ]);
        }
        
        return $this->render('security/setting.html.twig', [
            'template' => Region::getTemplite(),
            'form' => $form->createView(),
            'setting' => $response,
            'title' => 'Настройки',
        ]);
    }

    /**
     * @Route("/login", name="security_login")
     */
    public function login(Request $request, AuthenticationUtils $authenticationUtils): Response
    {        
        $template = preg_match('/sovamed\.ru/m', $request->getHost())? 'login' : 'login_wmtmed';

        return $this->render('security/' . $template . '.html.twig', [
            'template' => Region::getTemplite(),
            'alias' => null,
            'last_username' => $authenticationUtils->getLastUsername(), 
            'error' => $authenticationUtils->getLastAuthenticationError(),
            'title' => 'Личный кабинет - «СОВА»'
        ]);
    }

    /**
     * @Route("/logout", name="security_logout")
     */
    public function logout()
    {

    }

    /**
     * @Route("/api/usrlog/logout", name="security_usrlog_logout", methods={"POST"})
     */
    public function usrlogLogout(Request $request, UsrlogRepository $usrlogRepository): Response
    {
        $pcode = null;
        $user = $this->getUser();

        if ($user instanceof User) {
            $pcode = (string) $user->getUid();
        } else {
            $pcode = trim((string) $request->request->get('pcode', ''));
        }

        if ($pcode === '') {
            return $this->json(['success' => false, 'message' => 'pcode is required'], 400);
        }

        $usrlog = new Usrlog();
        $usrlog
            ->setPcode($pcode)
            ->setAgent((string) ($request->headers->get('User-Agent') ?? 'unknown'))
            ->setClientIp((string) ($request->getClientIp() ?? 'unknown'))
            ->setMethod('выход')
        ;

        $usrlogRepository->add($usrlog);

        return $this->json(['success' => true]);
    }

    /**
     * @Route("/registration", name="security_reg", methods={"GET","POST"})
     */
    public function registration(
        Request $request, 
        UserPasswordEncoderInterface $passwordEncoder
    ): Response
    {
        $user = new User();
        $form = $this->createForm(RegistrationFormType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $fullName = $form->get('firstName')->getData();
            $fullName .= ' '; 
            $fullName .= $form->get('middleName')->getData();
            $user->setFullName($fullName);
            $user->setToken($form->get('plainPassword')->getData());
            $user->setRoles(['ROLE_USER']);
            $user->setConfirm(0);
            $user->setPassword(
                $passwordEncoder->encodePassword(
                    $user,
                    $form->get('plainPassword')->getData()
                )
            );
            
            $infoclinica = new Rest();
            $response = $infoclinica->register($request->request->all());

            if ($response['response']['success'] == true) {
                $user->setUid(date('U'));
                $entityManager = $this->getDoctrine()->getManager();
                $entityManager->persist($user);
                $entityManager->flush();

                return $this->redirectToRoute('security_confirm', [
                    'id' => $user->getId(),
                    'rToken' => $response['response']['data']['rToken']
                ]);
            } else {
                $this->addFlash(
                    'notice',
                    $response['response']['data']['message'] ?? 'Cервис временно не доступен!'
                );
            }
        }

        return $this->render('security/register.html.twig', [
            'title' => 'Регистрация',
            'template' => Region::getTemplite(),
            'form' => $form->createView()
        ]);
    }

    /**
     * @Route("/forget", name="security_forget", methods={"POST"})
     */
    public function forget(Request $request, UserPasswordEncoderInterface $passwordEncoder)
    {
        $entityManager = $this->getDoctrine()->getManager();
        $email = false;
        $uid = $request->request->get('uid');

        if ($email = $request->request->get('login')) {
            $user = $entityManager->getRepository(User::class)
                ->findOneBy(['email' => \bin2hex($email)]);

            if ($user) {
                $uid = $user->getUid();
            }

            return $this->json(['uid' => $uid]);
        };

        $password = $request->request->get('password');

        if ($uid && $password) {
            $user = $entityManager->getRepository(User::class)
                ->findOneBy(['uid' => $uid]);
            
            if (!$user) {
                $user = new User();
            }

            $user->setUid($uid);
            $user->setToken($password);
            $user->setPassword(
                $passwordEncoder->encodePassword(
                    $user,
                    $password
                )
            );

            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($user);
            $entityManager->flush();

            return $this->json([
                'success' => true,
                'redirect' => '/login'
            ]); 
        }

        return $this->json([
            'success' => false,
            'uid' => $uid
        ]);
    }

    /**
     * @Route("/api/authenticated", name="security_authenticated", methods={"POST"})
     */
    public function authenticated(Request $request, 
        GuardAuthenticatorHandler $guardHandler, 
        LoginFormAuthenticator $authenticator, 
        UserPasswordEncoderInterface $passwordEncoder
    ): Response {
        $entityManager = $this->getDoctrine()->getManager();
        $userData = $request->request->get('user');
        
        $user = $entityManager->getRepository(User::class)
            ->findOneBy(['uid' => $userData['id']]);

        if (!$user && $userData) {
            $user = new User();
            
            $user
                ->setFullName($userData['fullName'])
                ->setEmail($userData['email'])
                ->setPhone($userData['phone'])
                ->setUid($userData['id'])
                ->setConfirm(1)
                ->setRoles(['ROLE_USER'])
                ->setToken($userData['id'])
                ->setPassword(
                    $passwordEncoder->encodePassword(
                        $user,
                        $userData['id']
                    )
                );
            
            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($user);
            $entityManager->flush();
            $entityManager->clear();
        }
        
        return $guardHandler->authenticateUserAndHandleSuccess(
            $user,
            $request,
            $authenticator,
            'main'
        );
    }

}
