<?php
/**
 * Created by PhpStorm.
 * User: Moldedcraft 1
 * Date: 20 Sep 2019
 * Time: 10:01 AM
 */

namespace RxConnexionBundle\Command;

use Doctrine\ORM\EntityManager;
use RxConnexionBundle\Entity\AuditTrailEntity;
use RxConnexionBundle\Entity\PatientBillingBreakdownEntity;
use RxConnexionBundle\Entity\PatientBillingEntity;
use RxConnexionBundle\Entity\PatientNoteEntity;
use RxConnexionBundle\Entity\PatientRentalEntity;
use RxConnexionBundle\Service\InventoryService;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class PatientRentalInvoiceCommand extends ContainerAwareCommand
{
    /**
     * Configure a new Command Line
     */
    protected function configure()
    {
        $this
            ->setName('rxconexion:generate-patient-rental-invoice')
            ->setDescription('Auto generate monthly rental invoice');
    }


    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $startDT = new \DateTime();
        /**@var EntityManager $em*/
        $em = $this->getContainer()->get('doctrine.orm.entity_manager');


        $output->writeln('Please wait while records are being scanned...');

        $patientRentals = $em->getRepository(PatientRentalEntity::class)->getForAutoGenerateRentalInvoice();

        if($recordsTotal = count($patientRentals) > 0) {
            $insertCtr = 0;
            foreach ($patientRentals as $index => $patientBilling_form) {
                $insertCtr++;
                $output->write($this->progress_bar($index, $recordsTotal));

                $patientBillingBreakdowns = explode('@@', $patientBilling_form['patientBillingBreakdowns']);

                $patientBilling_form['patientBillingBreakdowns'] = array();
                foreach ($patientBillingBreakdowns as $patientBillingBreakdown) {

                    $patientBillingBreakdownItem = explode('~', $patientBillingBreakdown);
                    $patientBilling_form['patientBillingBreakdowns'][] = array(
                        'patientChart' => empty($patientBillingBreakdownItem[0]) ? null : $patientBillingBreakdownItem[0],
                        'chartProcedure' => empty($patientBillingBreakdownItem[1]) ? null : $patientBillingBreakdownItem[1],
                        'item' => empty($patientBillingBreakdownItem[2]) ? null : $patientBillingBreakdownItem[2],
                        'type' => $patientBillingBreakdownItem[3],
                        'description' => $patientBillingBreakdownItem[4],
                        'serialNumber' => $patientBillingBreakdownItem[5],
                        'item_type' => $patientBillingBreakdownItem[6],
                        'term' => $patientBillingBreakdownItem[7],
                        'quantity' => $patientBillingBreakdownItem[8],
                        'price' => $patientBilling_form['amortization_amount'],
                        'amount' => $patientBilling_form['amortization_amount'] * $patientBillingBreakdownItem[8],
                    );

                }

                /**@var PatientBillingEntity $patientBilling */
                $patientBilling_id = $em->getRepository(PatientBillingEntity::class)->nativeInsert($patientBilling_form);
                $patientBilling = $em->getRepository(PatientBillingEntity::class)->find($patientBilling_id);

                /**@var InventoryService $inventoryService */
                $inventoryService = $this->getContainer()->get('rx_connexion.inventoryService');
                $inventoryService->recordMovement('Patient Billing - Invoice', array(
                    'patientBilling' => $patientBilling
                ));

                $patientBilling->setInvoiceAmountDue($patientBilling->getAmountDue());

                $patientNote = new PatientNoteEntity();
                $patientNote->setNote($patientBilling_form['note']);
                $patientNote->setType(PatientNoteEntity::TYPE_BILLING);
                $patientNote->setPatient($patientBilling->getPatient());
                $em->persist($patientNote);
                $patientBilling->getPatient()->addPatientNote($patientNote);
                //$em->flush();

                /**@var PatientBillingBreakdownEntity $patientBillingBreakdown */
                foreach ($patientBilling->getPatientBillingBreakdowns() as $patientBillingBreakdown) {
                    $patientBillingBreakdown->setAmountBalance($patientBillingBreakdown->getAmount());
                    if ($patientBillingBreakdown->getPatientChart()) {
                        $patientBillingBreakdown->getPatientChart()->updateBillingStatus(null);
                    }
                    $patientBillingBreakdown->setAmountValue();
                }
                $patientBilling->setInvoiceAmountBalance($patientBilling->getAmountBalance());


                $newAT = new AuditTrailEntity(
                    'Patient Billing',
                    $em->getClassMetadata(PatientBillingEntity::class)->getTableName(),
                    AuditTrailEntity::AXN_NEW
                );
                $newAT->entity = $patientBilling;
                $newAT->parseDetails();
                $em->persist($newAT);
            }
            $em->flush();
            $output->writeln($this->progress_bar($recordsTotal, $recordsTotal, "Completed ($insertCtr invoice created)"));
        } else {
            $output->writeln("No rentals for invoice today.");
        }

        $endDT = new \DateTime();
        $timeDiff = $endDT->diff($startDT);

        $output->writeln('Runtime: ' . $timeDiff->format('%Hh %im %ss'));
    }

    private function progress_bar($done, $total, $info="", $width=50) {
        $perc = round(($done * 100) / $total);
        $bar = round(($width * $perc) / 100);
        return sprintf("%s%%[[%s>%s]] %s\r", $perc, str_repeat("=", $bar), str_repeat(" ", $width-$bar), $info);
    }


}