<?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\CentroCusto\CentroCusto;
use App\Entities\Pessoa\Pessoa;
use App\Entities\PessoaFisica\PessoaFisica;
use App\Entities\Usuario\Usuario;
use App\Entities\UsuarioPerfil\UsuarioPerfil;
use App\Mappers\CentroCustoMapper;
use App\Models\CEPModel;
use App\Models\ClienteModel;
use App\Models\ConfirmacaoEmailModel;
use App\Models\EnderecoModel;
use App\Models\CentroCustoModel;
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\CentroCusto\CentroCustoUpdateViewModel\CentroCustoUpdateViewModel;
use App\ViewModels\CentroCusto\CentroCustoRegistrationViewModel\CentroCustoRegistrationViewModel;
use App\ViewModels\Orcamento\OrcamentoClienteItemDetalhe\OrcamentoClienteItemDetalhe;
use Exception;
use Kint\Parser\DOMDocumentPlugin;
use App\Services\JWT\UsuarioLogado;
use App\Utils\DateUtils;

class ComandaDAO extends DAO {

	public function getComandasByClienteIdByUnidadeId(int $clienteId, int $unidadeid): DAOResponse {

		$dao_response = new DAOResponse();

		try {

			$sql = <<<SQL
				select
					c.id as comanda_id , c.data_criada as data_criada , c.hora_criada as hora_criada ,
					c.id_cliente as cliente_id , c.id_pet as pet_id , c.id_unidade as unidade_id , 
					( select sum(valor) from comanda_item ci
							where ci.id_comanda  = c.id  and ci.comanda_item_status_id  not in  (3)
					) as valor ,
					c.data_criada as data_criacao , c.data_fechada as data_fechamento ,
					c.hora_criada as hora_criacao , c.hora_fechada as hora_fechamento ,
					pj.nome_fantasia as unidade_nome_fantasia , p.nome as pet_nome ,
					if (fechado_por is null, 0, 1)  as fechado
				from
					comanda c ,  unidade u , pessoa_juridica pj, pet p
				where
					c.id_cliente = :cliente_id:
					and u.id = :unidade_id:
					and u.id = c.id_unidade
					and pj.id = u.id_pessoa_juridica
					and p.id = c.id_pet
			SQL;

			$binds = [ 
				'cliente_id' => $clienteId,
				'unidade_id' => $unidadeid
			];
			$conn = db_connect();
			$query = $conn->query( $sql, $binds )
				->getResultArray();
			$error = $conn->error();

			if (intval( $error ['code'] ) != 0) {
				$dao_response->setErrors( $error );
				$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
				$dao_response->setData( [ ] );
			} else {
				if (count( $query ) > 0) {
					$dao_response->setStatus( DAOResponseInterface::SUCESS );
					$dao_response->setData( $query );
				} else {
					$dao_response->setStatus( DAOResponseInterface::RECORD_NOT_FOUND );
					$dao_response->setData( [ ] );
				}
			}
		} catch ( Exception $e ) {
			$dao_response->setErrors( $e->getMessage() );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
			$dao_response->setData( [ ] );
		}

		return $dao_response;

	}

	public function getComandasByClienteIdByPetIdByUnidadeId(int $clienteId, int $unidadeid, int $petid): DAOResponse {

		$dao_response = new DAOResponse();

		try {

			$sql = <<<SQL
				select
					c.id as comanda_id , c.data_criada as data_criada , c.hora_criada as hora_criada ,
					c.id_cliente as cliente_id , c.id_pet as pet_id , c.id_unidade as unidade_id ,
					( select sum(valor) from comanda_item ci
							where ci.id_comanda  = c.id  and ci.comanda_item_status_id  not in  (3)
					) as valor ,
					c.data_criada as data_criacao , c.data_fechada as data_fechamento ,
					c.hora_criada as hora_criacao , c.hora_fechada as hora_fechamento ,
					pj.nome_fantasia as unidade_nome_fantasia , p.nome as pet_nome ,
					if (fechado_por is null, 0, 1)  as fechado
				from
					comanda c ,  unidade u , pessoa_juridica pj, pet p
				where
					c.id_cliente = :cliente_id:
					and u.id = :unidade_id:
					and c.id_pet = :pet_id:
					and u.id = c.id_unidade
					and pj.id = u.id_pessoa_juridica
					and p.id = c.id_pet
			SQL;

			$binds = [ 
				'cliente_id' => $clienteId,
				'unidade_id' => $unidadeid,
				'pet_id' => $petid
			];
			$conn = db_connect();
			$query = $conn->query( $sql, $binds )
				->getResultArray();
			$error = $conn->error();

			if (intval( $error ['code'] ) != 0) {
				$dao_response->setErrors( $error );
				$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
				$dao_response->setData( [ ] );
			} else {
				if (count( $query ) > 0) {
					$dao_response->setStatus( DAOResponseInterface::SUCESS );
					$dao_response->setData( $query );
				} else {
					$dao_response->setStatus( DAOResponseInterface::RECORD_NOT_FOUND );
					$dao_response->setData( [ ] );
				}
			}
		} catch ( Exception $e ) {
			$dao_response->setErrors( $e->getMessage() );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
			$dao_response->setData( [ ] );
		}

		return $dao_response;

	}

	public function getComandaItensEmAbertoByIdPetByUnidadeId(int $petid, int $unidadeid): DAOResponse {

		$dao_response = new DAOResponse();

		$sql = <<<SQL
			select distinct
				ci.id_comanda , ci.id as comandaitem_id, ci.valor , rp.id as requisicao_id,
				rp.id_convenio_procedimento , p.descricao as procedimento,
				tc.id as tipo_convenio_id , tc.descricao as tipo_convenio,
				cp.id_unidade, u.descricao  as unidade
			from
				requisicao_procedimento rp,	convenio_procedimento cp, procedimento p,
				convenio c,	tipo_convenio tc, unidade u, comanda_item ci
			where
				rp.id_pet = :pet_id:
				and rp.id_convenio_procedimento  = cp.id
				and cp.id_convenio  = c.id
				and c.id_tipo_convenio = tc.id
				and tc.id = 2				
				and cp.id_unidade = u.id
				and u.id = :unidade_id:
				and rp.id = ci.id_requisicao_procedimento
				and ci.comanda_item_status_id  = 1
				and ci.id_procedimento = p.id
				order by ci.id_comanda asc, ci.id asc
		SQL;

		$binds = [ 
			'pet_id' => $petid,
			'unidade_id' => $unidadeid
		];
		$conn = db_connect();
		$query = $conn->query( $sql, $binds )
			->getResultArray();
		$error = $conn->error();

		if (intval( $error ['code'] ) != 0) {
			$dao_response->setErrors( $error );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
			$dao_response->setData( [ ] );
		} else {
			if (count( $query ) > 0) {
				$dao_response->setStatus( DAOResponseInterface::SUCESS );
				$dao_response->setData( $query );
			} else {
				$dao_response->setStatus( DAOResponseInterface::RECORD_NOT_FOUND );
				$dao_response->setData( [ ] );
			}
		}

		return $dao_response;

	}

	public function getClienteIdByComandaId(int $comandaid): DAOResponse {

		$dao_response = new DAOResponse();

		$sql = <<<SQL
			select id_cliente from comanda where id = :comanda_id:
		SQL;

		$binds = [ 
			'comanda_id' => $comandaid
		];
		$conn = db_connect();
		$query = $conn->query( $sql, $binds )
			->getResultArray();
		$error = $conn->error();

		if (intval( $error ['code'] ) != 0) {
			$dao_response->setErrors( $error );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
			$dao_response->setData( [ ] );
		} else {
			if (count( $query ) > 0) {
				$dao_response->setStatus( DAOResponseInterface::SUCESS );
				$dao_response->setData( $query );
			} else {
				$dao_response->setStatus( DAOResponseInterface::RECORD_NOT_FOUND );
				$dao_response->setData( [ ] );
			}
		}

		return $dao_response;

	}

	public function persistComanadaRegistrationVM(CentroCustoRegistrationViewModel $centro_custo_registration_vm): DAOResponse {

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

		return $dao_response;

	}

	private function setDatabaseErrorsForComandaRegistration(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 persistComanadaFromComanadaRegistrationVM(CentroCustoRegistrationViewModel &$centro_custo_registration_vm): CentroCusto {

		$centro_custo_model = new CentroCustoModel();
		$centro_custo = CentroCustoMapper::getCentroCustoFromCentroCustoRegistrationVM( $centro_custo_registration_vm );
		$centro_custo_model->registerCentroCusto( $centro_custo );
		if (!$centro_custo->getId()) {
			throw new Exception( 'O cadastro de paciente não foi teve êxito' );
		}
		return $centro_custo;

	}

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

		$sql = <<<SQL
		    select distinct
		        comanda.id, comanda.data_criada, comanda.hora_criada, comanda.criado_por, pf1.nome,
		        comanda.data_fechada, comanda.hora_fechada, comanda.fechado_por,
		        (   select pessoa_fisica.nome 
		            from pessoa_fisica , usuario 
		            where 
		                usuario.id = comanda.fechado_por 
		                and usuario.id_pessoa = pessoa_fisica.id_pessoa 
		        ) as nome_fechado,
		        comanda.id_cliente, pf2.nome, comanda.id_pet, pet.nome,comanda.id_unidade, unidade.descricao
		    from 
		        comanda, cliente,  pessoa_fisica as pf1, pessoa_fisica as pf2,unidade, usuario us, pet
		    where
		        us.id = comanda.criado_por
		        and us.id_pessoa = pf1.id_pessoa
		        and comanda.id_cliente = cliente.id
		        and cliente.id_pessoa = pf2.id_pessoa
		        and comanda.id_pet = pet.id
		        and comanda.id_unidade = unidade.id
		SQL;
		$binds = [ ];
		return $this->getDAOResponseFromPaginatedSelect( $binds, $pagination, $query_filter_collection, $query_order_collection, $sql,
			function (array $result_array) {
				return CentroCustoMapper::getCentroCustoDetailsVMListFromArray( $result_array );
			} );

	}

	public function getComanda(QueryFilterCollection $query_filter_collection): DAOResponse {

		$sql = <<<SQL
		    select distinct
		        comanda.id, comanda.data_criada, comanda.hora_criada, comanda.criado_por, pf1.nome,
		        comanda.data_fechada, comanda.hora_fechada, comanda.fechado_por,
		        (   select pessoa_fisica.nome 
		            from pessoa_fisica , usuario 
		            where 
		                usuario.id = comanda.fechado_por 
		                and usuario.id_pessoa = pessoa_fisica.id_pessoa 
		        ) as nome_fechado,
		        comanda.id_cliente, pf2.nome, comanda.id_pet, pet.nome,comanda.id_unidade, unidade.descricao
		    from 
		        comanda, cliente,  pessoa_fisica as pf1, pessoa_fisica as pf2,unidade, usuario us, pet
		    where
		        us.id = comanda.criado_por
		        and us.id_pessoa = pf1.id_pessoa
		        and comanda.id_cliente = cliente.id
		        and cliente.id_pessoa = pf2.id_pessoa
		        and comanda.id_pet = pet.id
		        and comanda.id_unidade = unidade.id
		SQL;
		$binds = [ ];
		return $this->getDAOResponseFromUniqueRowSelect( $binds, $query_filter_collection, $sql,
			function (array $result_array) {
				$centro_custoVM = CentroCustoMapper::getCentroCustoDetailsVMFromArray( $result_array [0] );
				return $centro_custoVM;
			} );

	}

	public function getComandaId(int $id_centro_custo) {

		$sql = <<<SQL
		select distinct
		    comanda.id, comanda.data_criada, comanda.hora_criada, comanda.criado_por, pf1.nome,
		    comanda.data_fechada, comanda.hora_fechada, comanda.fechado_por,
		    (   select pessoa_fisica.nome 
		        from pessoa_fisica , usuario 
		        where 
		            usuario.id = comanda.fechado_por 
		            and usuario.id_pessoa = pessoa_fisica.id_pessoa 
		    ) as nome_fechado,
		    comanda.id_cliente, pf2.nome, comanda.id_pet, pet.nome,comanda.id_unidade, unidade.descricao
		from 
		    comanda, cliente,  pessoa_fisica as pf1, pessoa_fisica as pf2,unidade, usuario us, pet
		where
		    us.id = comanda.criado_por
		    and us.id_pessoa = pf1.id_pessoa
		    and comanda.id_cliente = cliente.id
		    and cliente.id_pessoa = pf2.id_pessoa
		    and comanda.id_pet = pet.id
		    and comanda.id_unidade = unidade.id
		SQL;

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

		return ($result_array);

	}

	// public function persistCentroCustoUpdateVM(int $id_paciente, CentroCustoUpdateViewModel $centro_custo_update_vm): DAOResponse {

	// $dao_response = new DAOResponse();
	// $this->db->transStart();
	// $status_persistence = $this->persistCentroCustoFromCentroCustoUpdateVM( $id_paciente, $centro_custo_update_vm );
	// $error = $this->db->error();
	// if ($error && $error ['code']) {
	// $this->setDatabaseErrorsForCentroCustoUpdate( $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 setDatabaseErrorsForCentroCustoUpdate(DAOResponse $dao_response, array $error): void {
	// $dao_response->setStatus( $error ['code'] );
	// $dao_response->setErrors( $this->getDatabaseResponseErrorsForPersistence( $error ) );
	// }

	// private function persistCentroCustoFromCentroCustoUpdateVM(int $id_paciente, CentroCustoUpdateViewModel &$centro_custo_update_vm): bool {
	// $centro_custo_model = new CentroCustoModel();
	// $centro_custo = CentroCustoMapper::getCentroCustoFromCentroCustoUpdateVM( $centro_custo_update_vm );
	// $sucess_update = $centro_custo_model->updateCentroCustoByID( $id_paciente, $centro_custo );
	// 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 persistComandaDeleteVM(int $id_paciente): DAOResponse {

		$dao_response = new DAOResponse();
		$this->db->transStart();
		$status_persistence = $this->deleteCentroCusto( $id_paciente );
		$error = $this->db->error();
		if ($error && $error ['code']) {
			$this->setDatabaseErrorsForCentroCustoUpdate( $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 deleteComanda(int $id_centro_custo): bool {

		$centro_custo_model = new CentroCustoModel();
		$sucess_update = $centro_custo_model->deleteCentroCustoByID( $id_centro_custo );
		return $sucess_update;

	}

	public function getMeusRecibementosTotalByUnidadeByPeriodo(int $idunidade, string $data_ini, string $data_fim): DAOResponse {

		try {
			$usr = UsuarioLogado::getUsuarioId();
			$sql = <<<SQL
				select
					ci.id_forma_pagamento, fp.descricao , sum(ci.valor) as valor
				from
					comanda_item ci,forma_pagamento fp,requisicao_procedimento rp,convenio_procedimento cp
				where
					ci.comanda_item_status_id  = 2
					and ci.id_forma_pagamento = fp.id
					and ci.data_atualizacao >=:dataini:
					and ci.data_atualizacao <=:datafim:
					and ci.atualizado_por = :usuariologado:
					and ci.id_requisicao_procedimento  = rp.id
					and rp.id_convenio_procedimento = cp.id
					and cp.id_unidade = :unidade:
					group by ci.id_forma_pagamento
			SQL;

			$binds = [ 
				"usuariologado" => $usr,
				"unidade" => $idunidade,
				"dataini" => $data_ini,
				"datafim" => $data_fim
			];
			$pagination = Pagination::builder()->setCurrentPage( 1 )
				->setNumRows( 15 )
				->setNumRows( 1 )
				->build();
			$dao_response = new DAOResponse();
			$conn = db_connect();
			$query = $conn->query( $sql, $binds )
				->getResultArray();
			$errors = $conn->error();
			if ($errors ['code'] != 0) {
				$dao_response->setErrors( $errors );
			} else {
				$total_formas_pagamentos ['totais'] = $query;
				$dao_response->setStatus( DAOResponseInterface::SUCESS );
				$dao_response->setData( $total_formas_pagamentos ['totais'] );
				$dao_response->setPagination( $pagination->toResponseArray() );
			}
		} catch ( Exception $e ) {
			$dao_response->getStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
			$dao_response->setData( [ ] );
			$dao_response->setErrors( $e->getMessage() );
		}

		return $dao_response;

	}

	public function getMeusRecibementosByUnidadeByPeriodo(int $idUnidade, string $data_ini, string $data_fim) {

		$sql_recebimentos = <<<SQL
			select
				ci.id, ci.data_atualizacao , ci.hora_atualizacao , ci.comanda_item_status_id ,
				ci.id_forma_pagamento , fp.descricao as formapagamento, ci.valor,
				ci.atualizado_por, pf.nome as resonsavel , cp.id_unidade ,
				ci.id_requisicao_procedimento, rp.id_convenio_procedimento ,
				rp.id_pet , pc.id_cliente, c.id as cliente_id, pf2.nome	as cliente
			from
				comanda_item ci , usuario u , pessoa_fisica pf, requisicao_procedimento rp,
				pet_cliente pc , cliente c , pessoa_fisica pf2 , forma_pagamento fp, convenio_procedimento cp
			where
				ci.comanda_item_status_id  = 2
				and ci.id_forma_pagamento = fp.id
				and ci.data_atualizacao >=:dataini:
				and ci.data_atualizacao <=:datafim:
				and ci.atualizado_por = :usuariologado:
				and ci.atualizado_por = u.id
				and u.id_pessoa = pf.id_pessoa
				and ci.id_requisicao_procedimento  = rp.id
				and rp.id_pet = pc.id_pet
				and pc.id_cliente = c.id
				and c.id_pessoa = pf2.id_pessoa
				and rp.id_convenio_procedimento = cp.id
				and cp.id_unidade = :unidade:
			order by ci.data_atualizacao asc, ci.hora_atualizacao asc
			Limit :page: , :per_page:
			
		SQL;

		$binds_recebimentos = [ 
			"usuariologado" => $usr,
			"unidade" => $idunidade,
			"dataini" => $data_ini,
			"datafim" => $data_fim,
			"page" => $offset,
			"per_page" => $per_page
		];

		$conn_recebimentos = db_connect();
		$query_recebimentos = $conn_recebimentos->query( $sql_recebimentos, $binds_recebimentos )
			->getResultArray();

		$recebimentos = $query_recebimentos;

	}

	public function getMeusRecibementosByUnidadeByPeriodoCount(int $idUnidade, string $data_ini, string $data_fim) {

		$sql_count_rows = <<<SQL
			select
				count(*) as count_rows
			from
				comanda_item ci , usuario u , pessoa_fisica pf, requisicao_procedimento rp,
				pet_cliente pc , cliente c , pessoa_fisica pf2 , forma_pagamento fp, convenio_procedimento cp
			where
				ci.comanda_item_status_id  = 2
				and ci.id_forma_pagamento = fp.id
				and ci.data_atualizacao >=:dataini:
				and ci.data_atualizacao <=:datafim:
				and ci.atualizado_por = :usuariologado:
				and ci.atualizado_por = u.id
				and u.id_pessoa = pf.id_pessoa
				and ci.id_requisicao_procedimento  = rp.id
				and rp.id_pet = pc.id_pet
				and pc.id_cliente = c.id
				and c.id_pessoa = pf2.id_pessoa
				and rp.id_convenio_procedimento = cp.id
				and cp.id_unidade = :unidade:
				
		SQL;

		$binds_count_rows = [ 
			"usuariologado" => $usr,
			"unidade" => $idunidade,
			"dataini" => $data_ini,
			"datafim" => $data_fim
		];
		$conn_count_rows = db_connect();
		$query_count_rows = $conn_count_rows->query( $sql_count_rows, $binds_count_rows )
			->getResultArray();

		$pagination = Pagination::builder()->setCurrentPage( $page )
			->setNumRows( $query_count_rows [0] ['count_rows'] )
			->setPerPage( $per_page )
			->build();

	}

	public function getItensByComandaIdForAudit(int $comandaId): DAOResponse {

		$dao_response = new DAOResponse();

		$sql = <<<SQL
			select
				c.id as comanda_id, ci.data_criacao as data_criada, ci.hora_criacao as hora_criada,
				c.id_cliente as cliente_id, c.id_pet as pet_id, c.id_unidade as unidade_id,
				ci.id as comanda_item_id, ci.comanda_item_status_id as status,cis.descricao as status_comanda,
				ci.id_procedimento as procedimento_id, p.descricao as procedimento_descricao,
				ci.valor as valor,  ci.id_requisicao_procedimento, rp.status_id as status_requisicao,
				rps.descricao as status_requisicao_descricao, tp.id as tipo_procedimento_id,
				tp.descricao as tipo_procedimento_descricao, cvnio.id as convenio_id,
				cvnio.codigo as convenio_codigo, cvnio.descricao as convenio_descricao,
				tc.id as tipo_convenio_id, tc.descricao as tipo_convenio_descricao,
				rp.data_requisicao as data_requisicao, rp.hora_requisicao as hora_requisicao,
				rp.data_execucao as data_execucao, rp.hora_execucao as hora_execucao,
				ci.id_forma_pagamento, ci.data_atualizacao as data_pagamento,
				ci.hora_atualizacao as hora_pagamento
			from
				comanda c , comanda_item ci, comanda_item_status cis,
				requisicao_procedimento rp, requisicao_procedimento_status rps,
				procedimento p, tipo_procedimento tp,
				convenio_procedimento cp, convenio cvnio, tipo_convenio tc
			where
				c.id = :id_comanda:
				and ci.id_comanda = c.id
				and ci.comanda_item_status_id <> 3
				and cis.id = ci.comanda_item_status_id
				and rp.id = ci.id_requisicao_procedimento
				and rp.status_id = rps.id
				and p.id = ci.id_procedimento
				and tp.id  = p.id_tipo_procedimento
				and cp.id = rp.id_convenio_procedimento
				and cvnio.id = cp.id_convenio
				and tc.id = cvnio.id_tipo_convenio
				
		SQL;

		$binds = [ 
			"id_comanda" => $comandaId
		];

		$conn = db_connect();
		$resp = $conn->query( $sql, $binds )
			->getResultArray();

		$errors = $conn->error();
		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
		} else {
			$dao_response->setStatus( DAOResponseInterface::SUCESS );
			$dao_response->setData( $resp );
		}

		return $dao_response;

	}

	public function adminExcluirItemComandaPublicaByRequisicaoID(int $requisicao_id): DAOResponse {

		$dao_response = new DAOResponse();

		$sql = <<<SQL
			update 
				comanda_item
			set
				comanda_item_status_id = 3,
				atualizado_por = :id_usuario:,
				data_atualizacao = :data_atz:,
				hora_atualizacao = :hora_atz:
			where 
				id_requisicao_procedimento = :id_requisicao:
				
		SQL;

		$binds = [ 
			'id_requisicao' => $requisicao_id,
			'id_usuario' => UsuarioLogado::getUsuarioId(),
			'data_atz' => DateUtils::today(),
			'hora_atz' => DateUtils::now_time()
		];

		$conn = db_connect();
		$conn->query( $sql, $binds )->numRows;

		$errors = $conn->error();
		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
		} else {
			$affectRows = $conn->affectedRows();
			if ($affectRows != 0) {
				$dao_response->setStatus( DAOResponseInterface::SUCESS );
			} else {
				$dao_response->setStatus( DAOResponseInterface::RECORD_NOT_FOUND );
			}
		}

		return $dao_response;

	}

	public function adminNewReqExecExameInComanda(array $request, array $objConenioProcedimento, int $requisicao_id): DAOResponse {

		$dao_response = new DAOResponse();

		$idPet = $request ['id_pet'];
		$idCliente = $request ['id_cliente'];
		$idAssistente = $request ['assistente_id'];
		$idUnidade = $request ['id_unidade'];
		$idComanda = $request ['id_comanda'];
		$idConvenioProcedimento = $request ['id_convenio_procedimento'];
		$objCP = $objConenioProcedimento [0];
		$idConvenio = '';
		$idProcedimento = '';

		try {
			$idPet = intval( $request ['id_pet'] );
			$idCliente = intval( $request ['id_cliente'] );
			$idAssistente = intval( $request ['assistente_id'] );
			$idUnidade = intval( $request ['id_unidade'] );
			$idComanda = intval( $request ['id_comanda'] );
			$idConvenioProcedimento = intval( $request ['id_convenio_procedimento'] );
			$idConvenio = intval( $objCP ['id_convenio'] );
			$idProcedimento = intval( $objCP ['id_procedimento'] );
		} catch ( Exception $e ) {
			$dao_response->setErrors( $e->getMessage() );
			$dao_response->setStatus( DAOResponseInterface::INSUFFICIENT_DATA );
			return $dao_response;
		}
		$dataExec = $request ['data_exec'];
		$horaExec = $request ['hora_exec'];

		$usrLogado = UsuarioLogado::getUsuarioId();

		$sql = <<<SQL
			insert into comanda_item
				(id_comanda, id_procedimento, id_convenio, valor, status_item, 
				comanda_item_status_id, id_requisicao_procedimento, criado_por, 
				data_criacao, hora_criacao,atualizado_por,data_atualizacao, hora_atualizacao) values
				(:id_comanda:, :id_procedimento:, :id_convenio:, :valor:, :status_item:, 
				:ci_status_id:, :id_requisicao:, :criado_por:, :data_criacao:, :hora_criacao:,
				:atualizado_por:,:data_atualizacao:, :hora_atualizacao:)			
				
		SQL;

		$binds = [ 
			'id_comanda' => $idComanda,
			'id_procedimento' => $idProcedimento,
			'id_convenio' => $idConvenio,
			'valor' => 0.0,
			'status_item' => 0,
			'ci_status_id' => 2,
			'id_requisicao' => $requisicao_id,
			'criado_por' => $usrLogado,
			'data_criacao' => $dataExec,
			'hora_criacao' => $horaExec,
			'atualizado_por' => $usrLogado,
			'data_atualizacao' => $dataExec,
			'hora_atualizacao' => $horaExec
		];

		$conn = db_connect();
		$conn->query( $sql, $binds )->numRows;

		$errors = $conn->error();
		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
		} else {
			$affectRows = $conn->affectedRows();
			if ($affectRows != 0) {
				$dao_response->setStatus( DAOResponseInterface::SUCESS );
				$dao_response->setData( [ 
					'id_comanda_item' => $conn->insertID()
				] );
			} else {
				$dao_response->setStatus( DAOResponseInterface::RECORD_NOT_FOUND );
			}
		}

		return $dao_response;

	}

	public function getDadosComandaID(int $comanda_id): DAOResponse {

		$sql = <<<SQL
			select 
				id,	data_criada, hora_criada, criado_por, data_fechada,	hora_fechada,
				id_cliente,	id_pet,	id_unidade,	fechado_por
			from 
				comanda
			where 
				id = :id_comanda:				
		SQL;

		$binds = [ 
			'id_comanda' => $comanda_id
		];

		$dao_response = new DAOResponse();
		$conn = db_connect();
		$result = $conn->query( $sql, $binds )
			->getResultArray();

		$errors = $conn->error();
		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
		} else {
			if (count( $result ) > 0) {
				$dao_response->setStatus( DAOResponseInterface::SUCESS );
				$dao_response->setData( $result [0] );
			} else {
				$dao_response->setStatus( DAOResponseInterface::RECORD_NOT_FOUND );
			}
		}

		return $dao_response;

	}

	public function getComandaAtivaByPetByClienteByUnidade(int $id_pet, int $id_cliente, int $id_unidade): DAOResponse {

		$dao_response = new DAOResponse();
		$sql = <<<SQL
		    select
		        id as comanda_id
		    from comanda c
		    WHERE
		        id_cliente = :cliente_id:
		        and id_pet = :id_pet:
		        and id_unidade = :id_unidade:
		        and fechado_por is null
		SQL;

		$binds = [ 
			'cliente_id' => $id_cliente,
			'id_pet' => $id_pet,
			'id_unidade' => $id_unidade
		];

		$conn = db_connect();
		$result = $conn->query( $sql, $binds )
			->getResultArray();
		$errors = $conn->error();
		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
		} else {
			if (count( $result ) > 0) {
				$dao_response->setStatus( DAOResponseInterface::SUCESS );
				$dao_response->setData( $result [0] );
			} else {
				$dao_response->setStatus( DAOResponseInterface::RECORD_NOT_FOUND );
			}
		}

		return $dao_response;

	}

	public function registerComnadanFromOrcamento(array $orcamento): DAOResponse {

		$dao_response = new DaoResponse();

		$sql = <<<SQL
		    insert into comanda 
				(data_criada, hora_criada, criado_por, data_fechada, hora_fechada, 
				id_cliente, id_pet, id_unidade, fechado_por)
		    values (
		        :data_criada:, :hora_criada:, :criado_por:, :data_fechada:,
		        :hora_fechada:, :id_cliente:, :id_pet:, :id_unidade:, :fechado_por:
		    )
		SQL;
		$binds = [ 
			'data_criada' => DateUtils::today(),
			'hora_criada' => DateUtils::now_time(),
			'criado_por' => UsuarioLogado::getUsuarioId(),
			'data_fechada' => '1900-01-01',
			'hora_fechada' => '00:00:00',
			'id_cliente' => $orcamento ['id_cliente'],
			'id_pet' => $orcamento ['id_pet'],
			'id_unidade' => $orcamento ['id_unidade'],
			'fechado_por' => null
		];

		$conn = db_connect();
		$result = $conn->query( $sql, $binds )->numRows;
		$errors = $conn->error();

		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setData( [ ] );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
		} else {
			$newId = $conn->insertID();
			$dao_response->setStatus( DAOResponseInterface::SUCESS );
			$dao_response->setData( [ 
				'id_comanda' => $newId
			] );
		}

		return $dao_response;

	}

	public function registerComandaItemFromOrcamento(OrcamentoClienteItemDetalhe $orcamentoDetalhe, int $id_comanda, int $id_requisicao): DAOResponse {

		$sql = <<<SQL
		    insert into comanda_item
		        (id_comanda, id_procedimento, id_convenio, valor, status_item, criado_por, 
				comanda_item_status_id, data_criacao, hora_criacao, id_requisicao_procedimento)
			values
				(:id_comanda:, :id_procedimento:, :id_convenio:, :valor:, 0 , :usuario_id:,
				:comanda_item_status:,:data_cr:, :hora_cr:, :id_requisicao:)
		    
		SQL;

		$status_comanda_item = 1;

		if (($orcamentoDetalhe->getIdTipoConvenio() == 1) || ($orcamentoDetalhe->getIdTipoConvenio() == 3)) {
			$status_comanda_item = 2;
		}

        if($status_comanda_item == 1 ){
            $sqlBuscaProcedimento = <<<SQL
		        select p.id from requisicao_procedimento rp 
		        inner join convenio_procedimento cp on rp.id_convenio_procedimento = cp.id
		        inner join procedimento p on cp.id_procedimento = p.id
		        where rp.id = $id_requisicao limit 1
		SQL;

            $query_result = db_connect()->query($sqlBuscaProcedimento)->getResult();
            $reponse_procedimento = $query_result[0]->id;

            if($reponse_procedimento == 968){
                $status_comanda_item = 2;
            }

        }


		$binds = [ 
			'id_comanda' => $id_comanda,
			'id_procedimento' => $orcamentoDetalhe->getIdProcedimento(),
			'id_convenio' => $orcamentoDetalhe->getIdConvenio(),
			'valor' => $orcamentoDetalhe->getValorUnidade(),
			'usuario_id' => UsuarioLogado::getUsuarioId(),
			'comanda_item_status' => $status_comanda_item,
			'data_cr' => DateUtils::today(),
			'hora_cr' => DateUtils::now_time(),
			'id_requisicao' => $id_requisicao
		];

		$dao_response = new DAOResponse();
		$conn = db_connect();
		$result = $conn->query( $sql, $binds )->numRows;
		$errors = $conn->error();

		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setData( [ ] );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
		} else {
			$newId = $conn->insertID();
			$dao_response->setStatus( DAOResponseInterface::SUCESS );
			$dao_response->setData( [ 
				'id_comanda_item' => $newId
			] );
		}

		return $dao_response;

	}
	
	
	
	public function getComandaItemExecutadoPorConvenioParaPdf($dataInicial, $dataFinal, $unidade, $convenio, $execucao):DAOResponse {
		
		$sql = '
            select
                p.id, 
                p.descricao, 
                tc.descricao as convenio_descricao, 
                count(*) total, 
                sum(ci.valor) as valor
            from comanda_item ci , procedimento p ,convenio c , requisicao_procedimento rp, convenio_procedimento cp, tipo_convenio tc
            where
                ci.comanda_item_status_id  = 2
                and ci.id_procedimento = p.id
                and ci.id_convenio = c.id
                and ci.id_requisicao_procedimento = rp.id
                and rp.id_convenio_procedimento = cp.id
				and rp.status_id = 2
                and tc.id = c.id_tipo_convenio 
                and cp.id_unidade = :unidade_id:
                and ci.data_criacao >= :data_inicial:
                and ci.data_criacao <= :data_final:
		';
		if ($convenio != 5) {
			$sql .= '
                and c.id_tipo_convenio = :convenio:
                group by p.descricao, tc.descricao
            ';
		} else {
			$sql .= '
                group by p.descricao, tc.descricao
            ';
		}
		$binds = [
				'data_inicial' => $dataInicial,
				'data_final' => $dataFinal,
				'unidade_id' => $unidade,
				'convenio' => $convenio,
				'execucao' => $execucao
		];
				
		$dao_response = new DAOResponse();
		$conn = db_connect();
		$result = $conn->query( $sql, $binds )->getResult();
		$errors = $conn->error();
		
		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setData( [ ] );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
		} else {			
			$dao_response->setStatus( DAOResponseInterface::SUCESS );
			$dao_response->setData( $result );
		}
		
		return $dao_response;
				
	}
	
	public function getComandaItemNaoExecutadoPorConvenioParaPdf($dataInicial, $dataFinal, $unidade, $convenio, $execucao):DAOResponse {
		
		$sql = '
            select
                p.id, 
                p.descricao, 
                tc.descricao as convenio_descricao, 
                count(*) total, 
                sum(ci.valor) as valor
            from comanda_item ci , procedimento p ,convenio c , requisicao_procedimento rp, convenio_procedimento cp, tipo_convenio tc
            where
                ci.comanda_item_status_id  = 2
                and ci.id_procedimento = p.id
                and ci.id_convenio = c.id
                and ci.id_requisicao_procedimento =rp.id
                and rp.id_convenio_procedimento = cp.id
				and rp.status_id = 1
                and tc.id = c.id_tipo_convenio 
                and cp.id_unidade = :unidade_id:
                and ci.data_criacao >= :data_inicial:
                and ci.data_criacao <= :data_final:
		';
		if ($convenio != 5) {
			$sql .= '
                and c.id_tipo_convenio = :convenio:
                group by p.descricao, tc.descricao 
            ';
		} else {
			$sql .= '
                group by p.descricao, tc.descricao 
            ';
		}
		$binds = [
				'data_inicial' => $dataInicial,
				'data_final' => $dataFinal,
				'unidade_id' => $unidade,
				'convenio' => $convenio,
				'execucao' => $execucao
		];
		
		$dao_response = new DAOResponse();
		$conn = db_connect();
		$result = $conn->query( $sql, $binds )->getResult();
		$errors = $conn->error();
		
		if ($errors ['code'] != 0) {
			$dao_response->setErrors( $errors );
			$dao_response->setData( [ ] );
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
		} else {
			$dao_response->setStatus( DAOResponseInterface::SUCESS );
			$dao_response->setData( $result );
		}
		
		return $dao_response;
		
	}

}
