<?php

namespace App\Controller;

use App\Controller\Base\AbstractLiquidacionController;
use App\Electronico\Comprobante;
use App\Entity\Model\Customer;
use App\Entity\Model\Liquidacion;
use App\Entity\Model\Item;
use App\Entity\Model\ItemPago;
use App\Entity\Model\Provider;
use App\Entity\Model\Reembolso;
use App\Service\EmFactory;
use App\Util\RestApiFunciones;
use Knp\Component\Pager\PaginatorInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\NodeVisitor\MacroAutoImportNodeVisitor;

/**
 * @Route("/liqreembolso")
 */
class LiquidacionReembolsoController extends AbstractLiquidacionController
{

    protected $translator;

    /**
     * @Route("", name="liqreembolso_index")
     *
     */
    public function indexAction(EmFactory $emFactory, Request $request, PaginatorInterface $paginator, TranslatorInterface $translator)
    {
        $this->translator = $translator;
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();
        $empresaRepo = $em->getRepository('App\Entity\Model\Empresa');
        $emisor = $empresaRepo->findOneByUser($user->getRuc());

        $repo = $em->getRepository('App\Entity\Model\Liquidacion');
        $repo->setPaginator($paginator);
        // @todo Unhardcode this.
        $limit = 50;

        $form = $this->createForm('App\Form\SearchGenericType', null, [
            'action' => $this->generateUrl('liqreembolso_index'),
            'method' => 'GET',
        ]);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $pagination = $repo->paginatedSearchReembolso($form->getData(), $limit, $request->query->getInt('page', 1), $emisor->getId());
        } else {
            $pagination = $repo->paginatedSearchReembolso([], $limit, $request->query->getInt('page', 1), $emisor->getId());
        }

        $liquidaciones = [];
        foreach ($pagination->getItems() as $item) {
            $liquidaciones[] = $item;
        }
        $listForm = $this->createForm('App\Form\ListGenericType', $liquidaciones, [
            'action' => $this->generateUrl('liqreembolso_index'),
        ]);
        $listForm->handleRequest($request);
        if ($listForm->isSubmitted() && $listForm->isValid()) {
            $data = $listForm->getData();
            if (empty($data['invoices'])) {
                $this->addTranslatedMessage('flash.nothing_selected', 'warning');
            } else {
                if ($request->request->has('delete')) {
                    return $this->bulkDelete($data['invoices']);
                } elseif ($request->request->has('pdf')) {
                    return $this->bulkPdf($data['invoices']);
                } elseif ($request->request->has('print')) {
                    return $this->bulkPrint($data['invoices']);
                } elseif ($request->request->has('email')) {
                    return $this->bulkEmail($data['invoices']);
                }
            }
        }
        return $this->render('LiquidacionReembolso\index.html.twig',
            array(
                'invoices' => $pagination,
                //'currency' => $em->getRepository('SiwappConfigBundle:Property')->get('currency', 'EUR'),
                'currency' => $emisor == null ? 'USD' : $emisor->getCurrency(),
                'search_form' => $form->createView(),
                'list_form' => $listForm->createView(),
            ));
    }


    /**
     * @Route("/show/{slug}liq{id}", name="liqreembolso_show")
     *
     */
    public function showAction($id, EmFactory $emFactory, $slug, TranslatorInterface $translator, Request $request, LoggerInterface $logger)
    {
        $this->logger = $logger;
        $this->translator = $translator;
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();
        $empresaRepo = $em->getRepository('App\Entity\Model\Empresa');
        $emisor = $empresaRepo->findOneByUser($user->getRuc());

        $entity = $em->getRepository('App\Entity\Model\Liquidacion')->findBySlug($slug, $id);
        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Liquidacion entity.');
        }

        $defaultData = ['slug' => $slug, 'id'=>$id, 'customerEmail' => $entity->getProviderEmail()];

        $form = $this->createFormBuilder($defaultData)
            ->add('slug', HiddenType::class)
            ->add('id', HiddenType::class)
            ->add('customerEmail')
            ->setAction($this->generateUrl('liqreembolso_show', ['id' => $id, 'slug'=>$slug]))
            ->getForm();

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            // data is an array with "name", "email", and "message" keys
            $data = $form->getData();

            if ($request->request->has('Form-pdf')) {
                $this->generarPdf($entity);
            } elseif ($request->request->has('Form-email')) {
                if (isset($data['customerEmail'])) {
                    $email = $data['customerEmail'];
                    $this->enviarMail($email, $entity);
                } else
                    $this->addTranslatedMessage('Email del cliente nulo o en blanco', 'warning');
            } elseif ($request->request->has('Form-edit')) {
                if ($entity->getAutorizado() === false)
                    return $this->redirect($this->generateUrl('liqreembolso_edit', ['id' => $entity->getId(), 'slug' => $slug]));
            } elseif ($request->request->has('Form-delete')) {
                $error = $this->delete($entity);
                if ($error)
                    return $this->redirect($this->generateUrl('liqreembolso_index'));
            } elseif ($request->request->has('Form-anular')) {
                $entity->setAnulado(true);
                $em->persist($entity);
                $em->flush();
            } elseif ($request->request->has('Form-enviar')) {
                $this->enviarSriOnline($entity);
            } elseif ($request->request->has('Form-auto')) {
                if ($entity->getAutorizado() === false) {
                    $resp = $this->consultarAutorizacion($entity);
                    if ($resp != null)
                        $this->addTranslatedMessage($resp, 'danger');
                }

            }
        }

        if ($entity->getMensajeError()) {
            $this->addTranslatedMessage($entity->getMensajeError(), 'danger');
        }

        /*if (!$entity->isClosed()) {
            // When the liquidacion is open send to the edit form by default.
            return $this->redirect($this->generateUrl('liqreembolso_edit', array('id' => $id)));
        }
        */

        return $this->render('LiquidacionReembolso\show.html.twig',
            array(
                'entity' => $entity,
                'form' => $form->createView(),
                //'currency' => $em->getRepository('SiwappConfigBundle:Property')->get('currency', 'EUR'),
                'currency' => $emisor == null ? 'USD' : $emisor->getCurrency(),
            ));
    }

    /**
     * @Route("/new", name="liqreembolso_add")
     *
     */
    public function newAction(EmFactory $emFactory, Request $request, TranslatorInterface $translator)
    {
        $this->translator = $translator;
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();
        $empresaRepo = $em->getRepository('App\Entity\Model\Empresa');
        $empresa = $empresaRepo->findOneByUser($user->getRuc());

        $liquidacion = new Liquidacion();
        $liquidacion->setEsReembolso(true);
        $newItem = new Item();

        $tax = $em->getRepository('App\Entity\Model\Tax')->findTaxDefault($empresa->getId());
        $newItem->setTaxes($tax);
        $liquidacion->addItem($newItem);

        $itemPago = new ItemPago();
        $itemPago->setPlazo(0);
        $liquidacion->addPago($itemPago);

        $reembolso = new Reembolso();
        $liquidacion->addReembolso($reembolso);

        $form = $this->createForm('App\Form\LiquidacionReembolsoType', $liquidacion, [
            'action' => $this->generateUrl('liqreembolso_add'),
        ]);

        /*if ($request->isMethod('POST')) {

            $taxRepo = $em->getRepository('SiwappCoreBundle:Tax');

            $all = $request->request->all();

            $aux= $all['liquidacion']['items'];
            if ( $aux != null) {

                foreach ($aux as $clave=>$Item) {
                    if ($Item['taxes'] == "S") {
                        $tax = $taxRepo->find(1);
                        if (!$tax) {
                            continue;
                        }
                        $Item['taxes'] = array(1);
                    } else {
                        $tax = $taxRepo->find(2);
                        if (!$tax) {
                            continue;
                        }
                        $Item['taxes'] = array(2);
                    }
                    $aux[$clave]= $Item;

                }

                $all['liquidacion']['items'] = $aux;
                $request->request->replace($all);
            }
            $form->handleRequest($request);
        }
        else*/

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            if ($request->request->has('save_draft')) {
                $liquidacion->setStatus(Liquidacion::DRAFT);
            } else {
                // Any save action transforms this to opened.
                $liquidacion->setStatus(Liquidacion::OPENED);
            }

            $serie = $liquidacion->getSeries()->getValue();
            $liquidacion->setSerie($serie);
            $this->cargarImpuestos($liquidacion);
            $this->cargarReembolsos($liquidacion, $em);
            $liquidacion->setEmpresa($empresa);
            $liquidacion->setUsuario($user->getId());
            $liquidacion->setAmbiente($empresa->getTipoAmbiente());

            $em->persist($liquidacion);
            $em->flush();
            //$this->addTranslatedMessage('flash.added');

            $liqreembolso_id = $liquidacion->getId();

            $liquidacion = $this->generarXml($liquidacion);

            if ($empresa->getEnvioAutomatico()) {

                if ($liquidacion !== null) {
                    $app_url = $this->getParameter('cola_url');

                    $error = false;

                    $resp = RestApiFunciones::enviarComprobanteCola($error,
                        $liquidacion->getProviderName(),
                        $liquidacion->getProviderEmail(),
                        $user->getId(),
                        $liquidacion->getXml(),
                        $liquidacion->getClaveAcceso(),
                        $app_url,
                        'mifactureroecinvoice'
                    );

                    if ($error) {
                        $this->addTranslatedMessage($resp, 'danger');
                        $liquidacion->setMensajeError($resp);
                    }

                    $em->persist($liquidacion);
                    $em->flush();

                }

                return $this->redirect($this->generateUrl('liqreembolso_index'));

            }
            return $this->redirect($this->generateUrl('liqreembolso_show', ['id' => $liqreembolso_id, 'slug' => $liquidacion->getSlug()]));

        }
        $provider = new Provider();

        $formprovider = $this->createForm('App\Form\ProviderType', $provider, [
            'action' => $this->generateUrl('rest_provider_add'),
        ]);
        $formprovider->handleRequest($request);

        $formprovreembolso = $this->createForm('App\Form\ProviderType', $provider, [
            'action' => $this->generateUrl('rest_provider_add'),
        ]);
        $formprovreembolso->handleRequest($request);

        $reembolso = new Reembolso();
        $formreembolso = $this->createForm('App\Form\ReembolsoType', $reembolso, [
            'action' => $this->generateUrl('rest_provider_add'),
        ]);
        $formreembolso->handleRequest($request);

        return $this->render('LiquidacionReembolso\edit.html.twig',
            array(
                'form' => $form->createView(),
                'formprovider' => $formprovider->createView(),
                'formreembolso' => $formreembolso->createView(),
                'formprovreembolso' => $formprovreembolso->createView(),
                'provider' => $provider,
                'entity' => $liquidacion,
                //'currency' => $em->getRepository('SiwappConfigBundle:Property')->get('currency', 'EUR'),
                'currency' => $empresa == null ? 'USD' : $empresa->getCurrency(),
            ));
    }


    /**
     * @Route("/edit/{slug}liq{id}", name="liqreembolso_edit")
     *
     */
    public function editAction($id, EmFactory $emFactory, Request $request, $slug, TranslatorInterface $translator)
    {
        $this->translator = $translator;
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();
        $empresaRepo = $em->getRepository('App\Entity\Model\Empresa');
        $empresa = $empresaRepo->findOneByUser($user->getRuc());

        $liquidacion = $em->getRepository('App\Entity\Model\Liquidacion')->findBySlug($slug, $id);
        if (!$liquidacion && $liquidacion->getEmpresa() != $empresa) {
            throw $this->createNotFoundException('Unable to find Liquidacion entity.');
        }

        if($liquidacion->getAutorizado()){
            return $this->redirect($this->generateUrl('liqreembolso_show', ['id' => $id, 'slug' => $slug]));
        }

        $form = $this->createForm('App\Form\LiquidacionReembolsoType', $liquidacion, [
            'action' => $this->generateUrl('liqreembolso_edit', ['id' => $id, 'slug' => $slug]),
        ]);
        $form->handleRequest($request);

        $liquidacion->setEmpresa($empresa);

        if ($form->isSubmitted() && $form->isValid()) {
            $redirectRoute = 'liqreembolso_show';

            $serie = $liquidacion->getSeries()->getValue();
            $liquidacion->setSerie($serie);
            $this->cargarImpuestos($liquidacion);
            $this->cargarReembolsos($liquidacion, $em);
            $liquidacion->setEmpresa($empresa);
            $liquidacion->setUsuario($user->getId());
            $liquidacion->setAmbiente($empresa->getTipoAmbiente());

            $em->persist($liquidacion);
            $em->flush();
            //$this->addTranslatedMessage('flash.added');

            $liqreembolso_id = $liquidacion->getId();

            $liquidacion = $this->generarXml($liquidacion);

            if ($empresa->getEnvioAutomatico()) {

                if ($liquidacion !== null) {
                    $app_url = $this->getParameter('cola_url');

                    $error = false;

                    $resp = RestApiFunciones::enviarComprobanteCola($error,
                        $liquidacion->getProviderName(),
                        $liquidacion->getProviderEmail(),
                        $user->getId(),
                        $liquidacion->getXml(),
                        $liquidacion->getClaveAcceso(),
                        $app_url,
                        'mifactureroecinvoice'
                    );

                    if ($error) {
                        $this->addTranslatedMessage($resp, 'danger');
                        $liquidacion->setMensajeError($resp);
                    }

                    $em->persist($liquidacion);
                    $em->flush();

                }

                return $this->redirect($this->generateUrl('liqreembolso_index'));

            }
            return $this->redirect($this->generateUrl('liqreembolso_show', ['id' => $liqreembolso_id, 'slug' => $liquidacion->getSlug()]));
        }

        return $this->render('LiquidacionReembolso\edit.html.twig',
            array(
                'entity' => $liquidacion,
                'form' => $form->createView(),
                //'currency' => $em->getRepository('SiwappConfigBundle:Property')->get('currency', 'EUR'),
                'currency' => $empresa == null ? 'USD' : $empresa->getCurrency(),
            ));
    }

    public function enviarSriOnline(Liquidacion $liquidacion)
    {
        $liquidacion = $this->generarXml($liquidacion);
        $em = $this->getDoctrine()->getManager();

        if($liquidacion !== null) {
            $app_url = $this->getParameter('api_url');

            $error = false;
            $resp = RestApiFunciones::enviarComprobante($error, $liquidacion->getXml(), $liquidacion->getClaveAcceso(), $app_url);

            if ($error)
                $this->addTranslatedMessage($resp->message, 'danger');
            else {
                if ($resp->estado === 'recibido') {
                    $resp = $this->consultarAutorizacion($liquidacion);

                    if ($resp !== null)
                        $this->addTranslatedMessage($resp, 'danger');
                } else {
                    $liquidacion->setMensajeError($resp->message);
                    $this->addTranslatedMessage($resp->message, 'danger');
                    $em->persist($liquidacion);
                    $em->flush();
                }
            }

        }
    }

    /**
     * @Route("/payments/{slug}liq{id}", name="liqreembolso_payments")
     *
     */
    public function paymentsAction(Request $request, $slug, EmFactory $emFactory, TranslatorInterface $translator)
    {
        $this->translator = $translator;

        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();
        $empresaRepo = $em->getRepository('App\Entity\Model\Empresa');
        $empresa = $empresaRepo->findOneByUser($user->getRuc());

        // Return all payments
        $liquidacion = $em->getRepository('App\Entity\Model\Liquidacion')->findBySlug($slug);
        if (!$liquidacion) {
            throw $this->createNotFoundException('Unable to find Liquidacion entity.');
        }

        $payment = new Payment;
        $addForm = $this->createForm('App\Form\PaymentType', $payment, [
            'action' => $this->generateUrl('liqreembolso_payments', ['id' => $liquidacion->getId(), 'slug' => $slug]),
        ]);
        $addForm->handleRequest($request);
        if ($addForm->isSubmitted() && $addForm->isValid()) {
            $liquidacion->addPayment($payment);
            $em->persist($liquidacion);
            $em->flush();
            $this->addTranslatedMessage('payment.flash.added');

            // Rebuild the query, since we have new objects now.
            return $this->redirect($this->generateUrl('liqreembolso_index'));
        }

        $listForm = $this->createForm('App\Form\ListLiquidacionPaymentType', $liquidacion->getPayments()->getValues(), [
            'action' => $this->generateUrl('liqreembolso_payments', ['id' => $liquidacion->getId(), 'slug' => $slug]),
        ]);
        $listForm->handleRequest($request);

        if ($listForm->isSubmitted() && $listForm->isValid()) {
            $data = $listForm->getData();
            foreach ($data['payments'] as $payment) {
                $liquidacion->removePayment($payment);
                $em->persist($liquidacion);
                $em->flush();
            }
            $this->addTranslatedMessage('payment.flash.bulk_deleted');

            // Rebuild the query, since some objects are now missing.
            return $this->redirect($this->generateUrl('liqreembolso_index'));
        }

        return $this->render('Payment\list.html.twig',
            [
                'liquidacionId' => $liquidacionId,
                'add_form' => $addForm->createView(),
                'list_form' => $listForm->createView(),
                //'currency' => $em->getRepository('SiwappConfigBundle:Property')->get('currency', 'EUR'),
                'currency' => $emisor == null ? 'USD' : $emisor->getCurrency(),
            ]);
    }

    /**
     * @Route("/form-totals", name="liqreembolso_form_totals")
     */
    public function getLiquidacionFormTotals(EmFactory $emFactory, Request $request)
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();

        $post = $request->request->get('liquidacion_reembolso');
        if (!$post) {
            throw new NotFoundHttpException;
        }

        $response = $this->getLiquidacionTotalsFromPost($post, new Liquidacion, $request->getLocale());

        return new JsonResponse($response);
    }

    /**
     * @Route("/items/form-totals", name="itemsreembolso_form_totals")
     */
    public function getLiquidacionItemReembolsoFormTotals(EmFactory $emFactory, Request $request)
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();

        $post = $request->request->get('liquidacion_reembolso');
        if (!$post) {
            throw new NotFoundHttpException;
        }

        $response = $this->getLiquidacionReembolsosTotalsFromPost($post, new Liquidacion, $request->getLocale());

        return new JsonResponse($response);
    }

    /**
     * @Route("/pdfpreview/{slug}inv{id}", name="liquidacionreembo_show_pdf_preview")
     *
     */
    public function showOnlinePdfAction($id,  $slug, EmFactory $emFactory, TranslatorInterface $translator, Request $request, LoggerInterface $logger)
    {
        $this->logger = $logger;
        $this->translator = $translator;
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();
        $empresaRepo = $em->getRepository('App\Entity\Model\Empresa');
        $empresa = $empresaRepo->findOneByUser($user->getRuc());

        $invoice = $em->getRepository('App\Entity\Model\Liquidacion')->findBySlug($slug, $id);
        if (!$invoice) {
            throw $this->createNotFoundException('Unable to find Liquidacion entity.');
        }

        $filename = 'LIQ_' . $invoice->getSerie() . "-" . str_pad($invoice->getNumber(), 9, '0', STR_PAD_LEFT) . '.pdf';

        if ($invoice->getAutorizado())
            $xml = $invoice->getXmlAutorizado();
        else
            $xml = $invoice->getXml();

        $app_url = $this->getParameter('api_url').'liquidacionride.php';

        $error = false;
        $mensaje = "";
        $docPdf = RestApiFunciones::getPdf($error, $app_url, $invoice->getClaveAcceso(), $xml, $mensaje, $empresa->getRuc());

        if ($error) {
            $this->addTranslatedMessage('ERRROR AL GENERAR EL PDF, ' . $mensaje, 'danger');
        } else {
            file_put_contents($filename, $docPdf);

            $pdf = base64_encode(file_get_contents($filename));

            $response = new Response($pdf);
            $response->headers->set('Content-Type', 'application/octet-stream');
            $response->headers->set('Content-Description', 'File Transfer');
            $response->headers->set('Content-Disposition', 'attachment; filename="'.$filename.'"');
            // $response->headers->set('Expires', '0');
            // $response->headers->set('Content-Transfer-Encoding', 'binary');
            $response->headers->set('Content-length', strlen($pdf));
            $response->headers->set('Cache-Control', 'no-cache private');
            // $response->headers->set('Pragma', 'public');
            // Send headers before outputting anything
            $response->sendHeaders();



            try {
                unlink($filename);
            } catch (\Exception $ex) {

            }
            return $response;
        }
    }
}
