<?php

namespace App\DAO;

use App\DAO\DAOResponse\DAOResponse;
use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Filter\QueryFilter;
use App\DAO\Filter\QueryFilterBuilder;
use App\DAO\Order\QueryOrder;
use App\DAO\Pagination\Pagination;
use App\Entities\CEP\CEP;
use App\Entities\Cliente\Cliente;
use App\Entities\ConfirmacaoEmail\ConfirmacaoEmail;
use App\Entities\Endereco\Endereco;
use App\Entities\FormaPagamento\FormaPagamento;
use App\Entities\Pessoa\Pessoa;
use App\Entities\PessoaFisica\PessoaFisica;
use App\Entities\Usuario\Usuario;
use App\Entities\UsuarioPerfil\UsuarioPerfil;
use App\Mappers\FormaPagamentoMapper;
use App\Models\CEPModel;
use App\Models\ClienteModel;
use App\Models\ConfirmacaoEmailModel;
use App\Models\EnderecoModel;
use App\Models\FormaPagamentoModel;
use App\Models\PessoaFisicaModel;
use App\Models\PessoaModel;
use App\Models\UsuarioModel;
use App\Models\UsuarioPerfilModel;
use App\Services\LogService;
use App\Services\ServiceResponse\ServiceResponseInterface;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\ViewModels\FormaPagamento\FormaPagamentoUpdateViewModel\FormaPagamentoUpdateViewModel;
use App\ViewModels\FormaPagamento\FormaPagamentoRegistrationViewModel\FormaPagamentoRegistrationViewModel;
use Exception;
use Kint\Parser\DOMDocumentPlugin;

class FormaPagamentoDAO extends DAO {

	public function persistFormaPagamentoRegistrationVM(FormaPagamentoRegistrationViewModel $forma_pagamento_registration_vm): DAOResponse {

		$dao_response = new DAOResponse();
		try {
			$this->db->transStart();
			$forma_pagamento = $this->persistFormaPagamentoFromFormaPagamentoRegistrationVM( $forma_pagamento_registration_vm );
			$error = $this->db->error();
			if ($error && $error ['code']) {
				$this->setDatabaseErrorsForFormaPagamentoRegistration( $dao_response, $error );
			} else {
                $dao_response->setStatus( DAOResponseInterface::SUCESS );
                $dao_response->setData( $forma_pagamento );
                $this->db->transComplete();
			}
		} catch ( Exception $exception ) {
			$this->setDatabaseErrorsForFormaPagamentoRegistration( $dao_response, $this->db->error() );
		}

		return $dao_response;

	}

	private function setDatabaseErrorsForFormaPagamentoRegistration(DAOResponse $dao_response, array $error): void {

		if ($error ['code']) {
			$dao_response->setStatus( $error ['code'] );
			$dao_response->setErrors( $this->getDatabaseResponseErrorsForPersistence( $error ) );
		} else {
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
		}
		log_message( 'error', json_encode( $error ) );

	}

	private function persistFormaPagamentoFromFormaPagamentoRegistrationVM(FormaPagamentoRegistrationViewModel &$forma_pagamento_registration_vm): FormaPagamento {

		$forma_pagamento_model = new FormaPagamentoModel();
		$forma_pagamento = FormaPagamentoMapper::getFormaPagamentoFromFormaPagamentoRegistrationVM( $forma_pagamento_registration_vm );
		$forma_pagamento_model->registerFormaPagamento( $forma_pagamento );
		if (! $forma_pagamento->getId()) {
			throw new Exception( 'O cadastro de forma de pagamento não foi teve êxito' );
		}
		return $forma_pagamento;

	}

	public function getFormaPagamentoList(?Pagination $pagination, ?QueryFilterCollection $query_filter_collection, ?QueryOrderCollection $query_order_collection = null): DAOResponse {

		$sql = <<<SQL
			SELECT
				id as id,
				descricao as descricao,
				criado_em as criado_em,
				atualizado_em as atualizado_em,
				desativado_em as desativado_em,
				criado_por as criado_por,
				alterado_por as alterado_por,
				desativado_por as desativado_por,
				codauth
			FROM forma_pagamento
		SQL;
		$binds = [ ];
		return $this->getDAOResponseFromPaginatedSelect( $binds, $pagination, $query_filter_collection, $query_order_collection, $sql, function (array $result_array) {
			return FormaPagamentoMapper::getFormaPagamentoDetailsVMListFromArray( $result_array );
		} );
	}

	public function getFormaPagamento(QueryFilterCollection $query_filter_collection): DAOResponse {

		$sql = '
            SELECT 
            id as id,
            descricao as descricao,
            criado_em as criado_em,
            atualizado_em as atualizado_em,
            desativado_em as desativado_em,
            criado_por as criado_por,
            alterado_por as alterado_por,
            desativado_por as desativado_por 
            FROM forma_pagamento
        ';
		$binds = [ ];
		return $this->getDAOResponseFromUniqueRowSelect( $binds, $query_filter_collection, $sql, function (array $result_array) {
			$forma_pagamentoVM = FormaPagamentoMapper::getFormaPagamentoDetailsVMFromArray( $result_array [0] );
			return $forma_pagamentoVM;
		} );

	}

	public function getFormaPagamentoFromId(int $id_forma_pagamento) {

		$sql = "  SELECT * FROM forma_pagamento WHERE id=? ";

		$binds = [$id_forma_pagamento ];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();

		return ($result_array);

	}



    public function persistFormaPagamentoUpdateVM(int $id_paciente, FormaPagamentoUpdateViewModel $forma_pagamento_update_vm): DAOResponse {

		$dao_response = new DAOResponse();
		$this->db->transStart();
		$status_persistence = $this->persistFormaPagamentoFromFormaPagamentoUpdateVM( $id_paciente, $forma_pagamento_update_vm );
		$error = $this->db->error();
		if ($error && $error ['code']) {
			$this->setDatabaseErrorsForFormaPagamentoUpdate( $dao_response, $error );
			return $dao_response;
		} else if ($status_persistence) {
			$this->db->transComplete();
			$dao_response->setStatus( DAOResponseInterface::SUCESS );
		}
		$this->db->close();
		return $dao_response;
	}

	private function setDatabaseErrorsForFormaPagamentoUpdate(DAOResponse $dao_response, array $error): void {
		$dao_response->setStatus( $error ['code'] );
		$dao_response->setErrors( $this->getDatabaseResponseErrorsForPersistence( $error ) );
	}

	private function persistFormaPagamentoFromFormaPagamentoUpdateVM(int $id_paciente, FormaPagamentoUpdateViewModel &$forma_pagamento_update_vm): bool {
		$forma_pagamento_model = new FormaPagamentoModel();
		$forma_pagamento = FormaPagamentoMapper::getFormaPagamentoFromFormaPagamentoUpdateVM( $forma_pagamento_update_vm );
		$sucess_update = $forma_pagamento_model->updateFormaPagamentoByID( $id_paciente, $forma_pagamento );
		return $sucess_update;
	}

	private function getDatabaseResponseErrorsForPersistence(array $error): array {

		$dao_response_errors = [ ];
		if ($error && $error ['code']) {
			if ($error ['code'] === DAOResponseInterface::FOREIGN_KEY_DONT_EXISTS) {
				if (strpos( $error ['message'], 'cep' ) !== false) {
					$dao_response_errors ['cep'] = 'Esse CEP não existe.';
				}
			} else if ($error ['code'] === DAOResponseInterface::DUPLICATED_UNIQUE_KEY) {
				if (strpos( $error ['message'], '\'cpf\'' ) !== false) {
					$dao_response_errors ['cpf'] = 'Uma pessoa com esse CPF já está cadastrada no sistema.';
				}
				if (strpos( $error ['message'], '\'pessoa_fisica.rg\'' ) !== false) {
					$dao_response_errors ['rg'] = 'Uma pessoa com esse RG já está cadastrada no sistema.';
				}
				if (strpos( $error ['message'], '\'email\'' ) !== false) {
					$dao_response_errors ['email'] = 'Uma pessoa com esse email já está cadastrada no sistema.';
				}
			}
		}
		return $dao_response_errors;

	}




    public function persistFormaPagamentoDeleteVM(int $id_paciente): DAOResponse {

        $dao_response = new DAOResponse();
        $this->db->transStart();
        $status_persistence = $this->deleteFormaPagamento( $id_paciente );
        $error = $this->db->error();
        if ($error && $error ['code']) {
            $this->setDatabaseErrorsForFormaPagamentoUpdate( $dao_response, $error );
            return $dao_response;
        } else if ($status_persistence) {
            $this->db->transComplete();
            $dao_response->setStatus( DAOResponseInterface::SUCESS );
        }
        $this->db->close();
        return $dao_response;
    }

    public function deleteFormaPagamento (int $id_forma_pagamento) : bool {
        $forma_pagamento_model = new FormaPagamentoModel();
        $sucess_update = $forma_pagamento_model->deleteFormaPagamentoByID( $id_forma_pagamento );
        return $sucess_update;
    }


}
