<?php

class ContaForm extends TPage
{
    protected $form;
    private $formFields = [];
    private static $database = 'clinica';
    private static $activeRecord = 'Conta';
    private static $primaryKey = 'id';
    private static $formName = 'form_Conta';

    use BuilderMasterDetailFieldListTrait;

    /**
     * Form constructor
     * @param $param Request
     */
    public function __construct( $param )
    {
        parent::__construct();

        if(!empty($param['target_container']))
        {
            $this->adianti_target_container = $param['target_container'];
        }

        // creates the form
        $this->form = new BootstrapFormBuilder(self::$formName);
        // define the form title
        $this->form->setFormTitle("Cadastro de conta a receber");

        $criteria_clinica_id = new TCriteria();
        $criteria_pessoa_id = new TCriteria();
        $criteria_categoria_conta_id = new TCriteria();
        $criteria_lancamento_conta_tipo_pagamento_id = new TCriteria();

        $filterVar = TSession::getValue("userunitid");
        $criteria_clinica_id->add(new TFilter('system_unit_id', '=', $filterVar)); 
        $filterVar = Grupo::PACIENTE;
        $criteria_pessoa_id->add(new TFilter('id', 'in', "(SELECT pessoa_id FROM pessoa_grupo WHERE grupo_id = '{$filterVar}')")); 
        $filterVar = TipoConta::RECEBER;
        $criteria_categoria_conta_id->add(new TFilter('id', '=', $filterVar)); 
        $filterVar = "S";
        $criteria_lancamento_conta_tipo_pagamento_id->add(new TFilter('ativo', '=', $filterVar)); 

        $id = new TEntry('id');
        $tipo_conta_id = new THidden('tipo_conta_id');
        $clinica_id = new TDBCombo('clinica_id', 'clinica', 'Clinica', 'id', '{nome}','nome asc' , $criteria_clinica_id );
        $pessoa_id = new TDBUniqueSearch('pessoa_id', 'clinica', 'Pessoa', 'id', 'nome','nome asc' , $criteria_pessoa_id );
        $categoria_conta_id = new TDBCombo('categoria_conta_id', 'clinica', 'CategoriaConta', 'id', '{nome}','nome asc' , $criteria_categoria_conta_id );
        $descricao = new TEntry('descricao');
        $tipo = new TRadioGroup('tipo');
        $valor = new TNumeric('valor', '2', ',', '.', true, true );
        $tipo_pagamento = new TDBCombo('tipo_pagamento', 'clinica', 'TipoPagamento', 'id', '{nome}','nome asc'  );
        $data_vencimento = new TDate('data_vencimento');
        $repetir_ate_final_ano = new TCheckButton('repetir_ate_final_ano');
        $total_parcelas = new TSpinner('total_parcelas');
        $total_conta = new TNumeric('total_conta', '2', ',', '.', true, true );
        $button_atualizar_parcelas = new TButton('button_atualizar_parcelas');
        $lancamento_conta_id = new THidden('lancamento_conta_id[]');
        $lancamento_conta___row__id = new THidden('lancamento_conta___row__id[]');
        $lancamento_conta___row__data = new THidden('lancamento_conta___row__data[]');
        $lancamento_conta_valor = new TNumeric('lancamento_conta_valor[]', '2', ',', '.', true, true );
        $lancamento_conta_dt_vencimento = new TDate('lancamento_conta_dt_vencimento[]');
        $lancamento_conta_tipo_pagamento_id = new TDBCombo('lancamento_conta_tipo_pagamento_id[]', 'clinica', 'TipoPagamento', 'id', '{nome}','nome asc' , $criteria_lancamento_conta_tipo_pagamento_id );
        $this->parcelas = new TFieldList();
        $total_valor_parcelas = new TNumeric('total_valor_parcelas', '2', ',', '.' );

        $this->parcelas->addField(null, $lancamento_conta_id, []);
        $this->parcelas->addField(null, $lancamento_conta___row__id, ['uniqid' => true]);
        $this->parcelas->addField(null, $lancamento_conta___row__data, []);
        $this->parcelas->addField(new TLabel("Valor", null, '14px', null), $lancamento_conta_valor, ['width' => '60%']);
        $this->parcelas->addField(new TLabel("Data vencimento", null, '14px', null), $lancamento_conta_dt_vencimento, ['width' => '20%']);
        $this->parcelas->addField(new TLabel("Tipo de pagamento", null, '14px', null), $lancamento_conta_tipo_pagamento_id, ['width' => '20%']);

        $this->parcelas->width = '100%';
        $this->parcelas->setFieldPrefix('lancamento_conta');
        $this->parcelas->name = 'parcelas';
        $this->parcelas->class .= ' table-responsive';

        $this->criteria_parcelas = new TCriteria();

        $this->form->addField($lancamento_conta_id);
        $this->form->addField($lancamento_conta___row__id);
        $this->form->addField($lancamento_conta___row__data);
        $this->form->addField($lancamento_conta_valor);
        $this->form->addField($lancamento_conta_dt_vencimento);
        $this->form->addField($lancamento_conta_tipo_pagamento_id);

        $this->parcelas->setRemoveAction(null, 'fas:times #dd5a43', "Excluír");

        $tipo->setChangeAction(new TAction([$this,'onChange']));

        $lancamento_conta_valor->setExitAction(new TAction([$this,'onChangeValor']));

        $pessoa_id->addValidation("Pessoa", new TRequiredValidator()); 
        $categoria_conta_id->addValidation("Categoria", new TRequiredValidator()); 
        $descricao->addValidation("Descrição", new TRequiredValidator()); 
        $total_parcelas->addValidation("Total de parcelas", new TRequiredValidator()); 

        $lancamento_conta_tipo_pagamento_id->setDefaultOption(false);
        $total_parcelas->setRange(1, 2000, 1);
        $button_atualizar_parcelas->setImage('fas:cog #03A9F4');
        $button_atualizar_parcelas->addStyleClass('btn-default');
        $pessoa_id->setMinLength(1);
        $button_atualizar_parcelas->setAction(new TAction([$this, 'onGerarParcelas']), "Atualizar parcelas");
        $tipo->addItems(["S"=>"Simples","P"=>"Parcelada"]);
        $tipo->setLayout('horizontal');
        $tipo->setUseButton();
        $repetir_ate_final_ano->setUseSwitch(true, 'blue');
        $repetir_ate_final_ano->setIndexValue("1");
        $total_parcelas->setValue('1');
        $total_valor_parcelas->setValue('0,00');

        $data_vencimento->setDatabaseMask('yyyy-mm-dd');
        $lancamento_conta_dt_vencimento->setDatabaseMask('yyyy-mm-dd');

        $id->setEditable(false);
        $total_valor_parcelas->setEditable(false);

        $clinica_id->enableSearch();
        $tipo_pagamento->enableSearch();

        $pessoa_id->setMask('{nome_formatado}');
        $data_vencimento->setMask('dd/mm/yyyy');
        $lancamento_conta_dt_vencimento->setMask('dd/mm/yyyy');

        $id->setSize(100);
        $tipo->setSize('100%');
        $valor->setSize('100%');
        $pessoa_id->setSize('100%');
        $descricao->setSize('100%');
        $tipo_conta_id->setSize(200);
        $clinica_id->setSize('100%');
        $data_vencimento->setSize(150);
        $tipo_pagamento->setSize('100%');
        $total_parcelas->setSize('100%');
        $categoria_conta_id->setSize('100%');
        $total_valor_parcelas->setSize('100%');
        $lancamento_conta_valor->setSize('100%');
        $total_conta->setSize('calc(100% - 175px)');
        $lancamento_conta_dt_vencimento->setSize('100%');
        $lancamento_conta_tipo_pagamento_id->setSize('100%');



        $this->parcelas->class = ' tfieldlist';
        $this->parcelas->disableRemoveButton();
        $total_parcelas->style = 'text-align: right';

        $row1 = $this->form->addFields([new TLabel("Código:", null, '14px', null, '100%'),$id,$tipo_conta_id],[new TLabel("Clínica:", null, '14px', null, '100%'),$clinica_id]);
        $row1->layout = [' col-sm-8',' col-sm-4'];

        $row2 = $this->form->addFields([new TLabel("Paciente:", '#ff0000', '14px', null, '100%'),$pessoa_id],[new TLabel("Categoria:", '#ff0000', '14px', null, '100%'),$categoria_conta_id],[new TLabel("Descrição:", '#ff0000', '14px', null, '100%'),$descricao]);
        $row2->layout = [' col-sm-4',' col-sm-4',' col-sm-4'];

        $row3 = $this->form->addFields([new TLabel("Tipo de conta:", null, '14px', null, '100%'),$tipo]);
        $row3->layout = [' col-sm-12'];

        $row4 = $this->form->addFields([new TLabel("Valor:", '#FF0000', '14px', null, '100%'),$valor],[new TLabel("Tipo de pagamento:", '#FF0000', '14px', null, '100%'),$tipo_pagamento],[new TLabel("Data de vencimento:", '#FF0000', '14px', null, '100%'),$data_vencimento,new TLabel("Repetir até o final do ano:", null, '14px', null),$repetir_ate_final_ano]);
        $row4->layout = ['col-sm-3',' col-sm-3',' col-sm-6'];

        $row5 = $this->form->addFields([new TLabel("Total de parcelas:", '#ff0000', '14px', null, '100%'),$total_parcelas],[new TLabel("Total:", '#ff0000', '14px', null, '100%'),$total_conta,$button_atualizar_parcelas]);
        $row5->layout = [' col-sm-3',' col-sm-4'];

        $bcontainer_62cf238b6bca9 = new BContainer('bcontainer_62cf238b6bca9');
        $this->bcontainer_62cf238b6bca9 = $bcontainer_62cf238b6bca9;

        $bcontainer_62cf238b6bca9->setTitle("Parcelas", '#333', '18px', '', '#fff');
        $bcontainer_62cf238b6bca9->setBorderColor('#c0c0c0');

        $row6 = $bcontainer_62cf238b6bca9->addFields([$this->parcelas]);
        $row6->layout = [' col-sm-12'];

        $row7 = $this->form->addFields([$bcontainer_62cf238b6bca9]);
        $row7->layout = [' col-sm-12'];

        $row8 = $this->form->addFields([],[new TLabel("Total das parcelas", null, '14px', 'B', '100%'),$total_valor_parcelas]);
        $row8->layout = [' col-sm-10',' col-sm-2'];

        // create the form actions
        $btn_onsave = $this->form->addAction("Salvar", new TAction([$this, 'onSave'],['static' => 1]), 'fas:save #ffffff');
        $this->btn_onsave = $btn_onsave;
        $btn_onsave->addStyleClass('btn-primary'); 

        $btn_onclear = $this->form->addAction("Limpar formulário", new TAction([$this, 'onClear']), 'fas:eraser #dd5a43');
        $this->btn_onclear = $btn_onclear;

        $btn_onshow = $this->form->addAction("Voltar", new TAction(['ContaReceberList', 'onShow']), 'fas:arrow-left #000000');
        $this->btn_onshow = $btn_onshow;

        parent::setTargetContainer('adianti_right_panel');

        $btnClose = new TButton('closeCurtain');
        $btnClose->class = 'btn btn-sm btn-default';
        $btnClose->style = 'margin-right:10px;';
        $btnClose->onClick = "Template.closeRightPanel();";
        $btnClose->setLabel("Fechar");
        $btnClose->setImage('fas:times');

        $this->form->addHeaderWidget($btnClose);

        parent::add($this->form);

        $style = new TStyle('right-panel > .container-part[page-name=ContaForm]');
        $style->width = '70% !important';   
        $style->show(true);

    }

    public static function onChangeValor($param = null) 
    {
        try 
        {
            $soma = 0;

            if (! empty($param['lancamento_conta_valor']))
            {
                foreach ($param['lancamento_conta_valor'] as $key => $value)
                {
                    $valor = (float) str_replace(',', '.', str_replace('.', '', $value));

                    $soma += $valor;
                }
            }

            $total_conta = (float) str_replace(',', '.', str_replace('.', '', $param['total_conta']??''));

            if ($soma != $total_conta) {
                TScript::create('$("[name=total_valor_parcelas]").css("color", "red");');
            } else {
                TScript::create('$("[name=total_valor_parcelas]").css("color", "unset");');
            }

            $obj = new stdClass;
            $obj->total_valor_parcelas = number_format($soma, 2, ',', '.');

            TForm::sendData(self::$formName, $obj, false, false);

        }
        catch (Exception $e) 
        {
            new TMessage('error', $e->getMessage());    
        }
    }

    public static function onChange($param = null) 
    {
        try 
        {
            if (empty($param['tipo']) || $param['tipo'] == 'S')
            {
                TScript::create("$('[name=valor]').closest('.tformrow').show();");
                TScript::create("$('[name=total_conta]').closest('.tformrow').hide();");
                TScript::create("$('[name*=lancamento_conta_valor').closest('.bContainer-fieldset').closest('.tformrow').hide();");
                TScript::create("$('[name=total_valor_parcelas').closest('.tformrow').hide();");
            }
            else
            {
                TScript::create("$('[name=valor]').closest('.tformrow').hide();");
                TScript::create("$('[name=total_conta]').closest('.tformrow').show();");
                TScript::create("$('[name*=lancamento_conta_valor').closest('.bContainer-fieldset').closest('.tformrow').show();");
                TScript::create("$('[name=total_valor_parcelas').closest('.tformrow').show();");
            }

        }
        catch (Exception $e) 
        {
            new TMessage('error', $e->getMessage());    
        }
    }

    public static function onGerarParcelas($param = null) 
    {
        try 
        {
            $vencimentos = [];
            $valores = [];
            $tipos = [];

            if(empty($param['total_parcelas']) OR empty($param['total_conta']))
            {
                return;
            }

            $total = (float) str_replace(',', '.', str_replace('.', '', $param['total_conta']));

            $valorParcela = round(($total / $param['total_parcelas']), 2);

            for ($i = 1; $i <= $param['total_parcelas']; $i++) {
                 $vencimentos[] = date('10/m/Y', strtotime("now +{$i} month"));
                $tipos[] = TipoPagamento::PIX;
                 $valores[] = ($i == $param['total_parcelas']) ? number_format(($total - ($valorParcela * ($i-1))), 2, ',', '.') : number_format($valorParcela, 2, ',', '.');
            }

            $data = new stdClass;
            $data->lancamento_conta_dt_vencimento = $vencimentos;
            $data->lancamento_conta_valor = $valores;
            $data->lancamento_conta_tipo_pagamento_id = $tipos;
            $data->total_valor_parcelas = $param['total_conta'];

            TFieldList::clearRows('parcelas');
            TFieldList::addRows('parcelas', $param['total_parcelas'] - 1);

            TForm::sendData(self::$formName, $data, false, false, 750);

        }
        catch (Exception $e) 
        {
            new TMessage('error', $e->getMessage());    
        }
    }

    public function onSave($param = null) 
    {
        try
        {
            TTransaction::open(self::$database); // open a transaction

            $messageAction = null;

            $this->form->validate(); // validate form data

            $object = new Conta(); // create an empty object 

            $data = $this->form->getData(); // get form data as array
            $object->fromArray( (array) $data); // load the object with data

            if(!$object->id)
            {
                $object->tipo_conta_id = TipoConta::RECEBER;
                $object->data_emissao = date('Y-m-d H:i:s');    
            }

            if ($data->tipo == 'S')
            {
                $object->total_conta = $data->valor;
            }

            if (empty($object->total_conta))
            {
                throw new Exception('Valor não foi preenchido');
            }

            $object->store(); // save the object 

            $loadPageParam = [];

            if(!empty($param['target_container']))
            {
                $loadPageParam['target_container'] = $param['target_container'];
            }

            $this->total_valor_parcelas = 0;
            $this->count_parcelas = 1;

            if ($data->tipo == 'P')
            {
            $lancamento_conta_items = $this->storeItems('Lancamento', 'conta_id', $object, $this->parcelas, function($masterObject, $detailObject){ 

                $detailObject->parcela = $this->count_parcelas;

                $this->total_valor_parcelas += $detailObject->valor;
                $this->count_parcelas++;

            }, $this->criteria_parcelas); 

                if ($this->total_valor_parcelas != $object->total_conta)
                {
                    throw new Exception('Valor das parcelas não confere com o valor total da conta.');
                }
            }
            else
            {
                if ($data->id)
                {
                    Lancamento::where('conta_id', '=', $data->id)->delete();
                }

                if (empty($data->valor) || empty($data->data_vencimento) || empty($data->tipo_pagamento))
                {
                    throw new Exception('Valor, data de vencimento e tipo de pagamento são obrigatórios');
                }

                $object->total_conta = $data->valor;
                $object->total_parcelas = 1;

                $lancamento = new Lancamento;
                $lancamento->dt_vencimento = $data->data_vencimento;
                $lancamento->parcela = 1;
                $lancamento->valor = $data->valor;
                $lancamento->tipo_pagamento_id = $data->tipo_pagamento;
                $lancamento->conta_id = $object->id;
                $lancamento->store();

                if (empty($data->id) && $data->repetir_ate_final_ano)
                {
                    $mes = (int) date('m', strtotime($lancamento->dt_vencimento));
                    $qtde = 12 - $mes;

                    for($i = 1; $i <= $qtde; $i++)
                    {
                        $conta = clone $object;
                        unset($conta->id);
                        $conta->store();

                        $newlancamento = clone $lancamento;
                        unset($newlancamento->id);
                        $newlancamento->conta_id = $conta->id;
                        $newlancamento->dt_vencimento = date('Y-m-d', strtotime($lancamento->dt_vencimento . " + {$i} month"));
                        $newlancamento->store();

                    }
                }
            }

            // get the generated {PRIMARY_KEY}
            $data->id = $object->id; 

            $this->form->setData($data); // fill form data
            TTransaction::close(); // close the transaction

            TToast::show('success', "Registro salvo", 'topRight', 'far:check-circle');
            TApplication::loadPage('ContaReceberList', 'onShow', $loadPageParam); 

                        TScript::create("Template.closeRightPanel();");
            TForm::sendData(self::$formName, (object)['id' => $object->id]);

        }
        catch (Exception $e) // in case of exception
        {
            //</catchAutoCode> 

            new TMessage('error', $e->getMessage()); // shows the exception error message
            $this->form->setData( $this->form->getData() ); // keep form data
            TTransaction::rollback(); // undo all pending operations
        }
    }

    public function onEdit( $param )
    {
        try
        {
            if (isset($param['key']))
            {
                $key = $param['key'];  // get the parameter $key
                TTransaction::open(self::$database); // open a transaction

                $object = new Conta($key); // instantiates the Active Record 

                $object->total_valor_parcelas = 0;
                $object->tipo = 'P';

                $this->parcelas_items = $this->loadItems('Lancamento', 'conta_id', $object, $this->parcelas, function($masterObject, $detailObject, $objectItems){ 

                    $masterObject->total_valor_parcelas += $detailObject->valor;

                }, $this->criteria_parcelas); 

                $this->form->setData($object); // fill the form 

                $this->parcelas->getFoot()->style = 'display: none';

               self::onChange(['tipo' => 'P']);

                TTransaction::close(); // close the transaction 
            }
            else
            {
                $this->form->clear();
            }
        }
        catch (Exception $e) // in case of exception
        {
            new TMessage('error', $e->getMessage()); // shows the exception error message
            TTransaction::rollback(); // undo all pending operations
        }
    }

    /**
     * Clear form data
     * @param $param Request
     */
    public function onClear( $param )
    {
        $this->form->clear(true);

        $this->parcelas->addHeader();
        $this->parcelas->addDetail( new stdClass );

        $this->parcelas->addCloneAction(null, 'fas:plus #69aa46', "Clonar");

        TTransaction::open(self::$database);

        $clinica = Clinica::where('system_unit_id', '=', TSession::getValue('userunitid'))->first();

        $data = new stdClass;
        $data->clinica_id = $clinica->id;
        $data->tipo = 'S';
        $this->form->setData($data);

        TTransaction::close();

        self::onChange(['tipo' => 'S']);

    }

    public function onShow($param = null)
    {
        $this->parcelas->addHeader();
        $this->parcelas->addDetail( new stdClass );

        $this->parcelas->addCloneAction(null, 'fas:plus #69aa46', "Clonar");

        //$this->parcelas->getFoot()->style = 'display: none';

        TTransaction::open(self::$database);

        $clinica = Clinica::where('system_unit_id', '=', TSession::getValue('userunitid'))->first();

        $data = new stdClass;
        $data->clinica_id = $clinica->id;
        $data->tipo = 'S';
        $this->form->setData($data);

        TTransaction::close();

        self::onChange(['tipo' => 'S']);

    } 

    // public function onAddReceber()
    // {
    //     try
    //     {
    //         TTransaction::open(self::$database);

    //         $this->parcelas->addHeader();
    //         $this->parcelas->addDetail( new stdClass );
    //         $this->parcelas->addCloneAction(null, 'fas:plus #69aa46', "Clonar");
    //         $this->parcelas->getFoot()->style = 'display: none';

    //         $clinica = Clinica::where('system_unit_id', '=', TSession::getValue('userunitid'))->first();

    //         $data = new stdClass;
    //         $data->tipo_conta_id = TipoConta::RECEBER;
    //         $data->clinica_id = $clinica->id;

    //         $this->form->setData($data);

    //         TTransaction::close();

    //         self::onChange(['tipo' => 'P']);
    //     }
    //     catch (Exception $e)
    //     {
    //         TTransaction::rollback();
    //         new TMessage('error', $e->getMessage());
    //     }
    // }

    // public function onAddPagar()
    // {
    //     try
    //     {
    //         TTransaction::open(self::$database);

    //         $this->parcelas->addHeader();
    //         $this->parcelas->addDetail( new stdClass );
    //         $this->parcelas->addCloneAction(null, 'fas:plus #69aa46', "Clonar");
    //         $this->parcelas->getFoot()->style = 'display: none';

    //         $clinica = Clinica::where('system_unit_id', '=', TSession::getValue('userunitid'))->first();

    //         $data = new stdClass;
    //         $data->tipo_conta_id = TipoConta::PAGAR;
    //         $data->clinica_id = $clinica->id;

    //         $this->form->setData($data);

    //         TTransaction::close();

    //         self::onChange(['tipo' => 'S']);
    //     }
    //     catch (Exception $e)
    //     {
    //         TTransaction::rollback();
    //         new TMessage('error', $e->getMessage());
    //     }
    // }

}

