<?php

namespace App\Controllers;

use App\DAO\ConsultaDAO;
use App\Services\JWT\UsuarioLogado;
use App\Services\ServiceResponse\ServiceResponseInterface;
use App\Services\JWTService;
use App\v2\Modules\Especies\Services\EspecieFinderService;
use CodeIgniter\Controller;
use CodeIgniter\HTTP\Request;
use CodeIgniter\HTTP\Response;
use CodeIgniter\HTTP\ResponseInterface;
use Exception;
use App\Utils\DateUtils;
use App\Services\RequisicaoService;

class RequisicaoController extends BaseController {

	public function register() {

		$usr = UsuarioLogado::getUsuarioId();
		$sql_tipoconvenio = <<<SQL
			select cp.id ,cp.id_convenio ,cp.id_unidade, tc.id as tipo_convenio, tc.descricao
			from convenio_procedimento cp , convenio c, tipo_convenio tc
			where
				cp.id = :id_convenio_procedimento:
				and cp.id_convenio = c.id
				and c.id_tipo_convenio = tc.id 
		SQL;
		$bind_tipoconvenio = [ 
			'id_convenio_procedimento' => $_POST ['id_convenio_procedimento']
		];

		$conn_tipoconvenio = db_connect();
		$tipoconvenio = $conn_tipoconvenio->query( $sql_tipoconvenio, $bind_tipoconvenio )
			->getResultArray();

		$sql_cliente = <<<SQL
			select id_cliente from pet_cliente where id_pet = :petid:
		SQL;

		$bind_idcliente = [ 
			'petid' => $_POST ['id_pet']
		];

		$conn_idcliente = db_connect();
		$idcliente = $conn_idcliente->query( $sql_cliente, $bind_idcliente )
			->getResultArray();

		$sql = <<<SQL
		        insert into requisicao_procedimento 
		            (id_medico, id_convenio_procedimento, id_consulta, status_id, usuario_executor, data_requisicao, hora_requisicao, data_execucao, hora_execucao, id_pet, id_requisitante)
		        values
		            ( :id_medico:, :id_convenio_procedimento:, :id_consulta:, :status_id:, :usuario_executor:,
		              :data_requisicao:, :hora_requisicao:, :data_execucao:, :hora_execucao:, :id_pet: , :id_requisitante: )
		SQL;

		if (!$_POST ['id_consulta']) {
			die( 'Informe uma consulta válida.' );
		}

		$conn = db_connect();
		$conn->query( $sql,
			[ 
				'id_medico' => $_POST ['id_medico'],
				'id_convenio_procedimento' => $_POST ['id_convenio_procedimento'],
				'id_consulta' => $_POST ['id_consulta'],
				'status_id' => 1, // CRIADO
				'id_pet' => $_POST ['id_pet'],
				'usuario_executor' => null,
				'data_requisicao' => date( 'Y-m-d' ),
				'hora_requisicao' => date( 'H:i:s' ),
				'data_execucao' => '1900-01-01',
				'hora_execucao' => '00:00:00',
				'id_requisitante' => $usr
			] )->numRows;
		$requisicaoId = $conn->insertID();
		$error = $conn->error();

		// if ($tipoconvenio [0] ['tipo_convenio'] == 2) {

		$sqlInserirComanda = <<<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;
		$bindsInserirComanda = [ 
			'data_criada' => date( 'Y-m-d' ),
			'hora_criada' => date( 'H:i:s' ),
			'criado_por' => UsuarioLogado::getUsuarioId(),
			'data_fechada' => '1900-01-01',
			'hora_fechada' => '00:00:00',
			'id_cliente' => ( int ) $idcliente [0] ['id_cliente'],
			'id_pet' => ( int ) $_POST ['id_pet'],
			'id_unidade' => ( int ) $tipoconvenio [0] ['id_unidade'],
			'fechado_por' => null
		];

		$sqlComandaAtiva = <<<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;
		$comandaAtiva = $conn->query( $sqlComandaAtiva,
			[ 
				'cliente_id' => ( int ) $idcliente [0] ['id_cliente'],
				'id_pet' => ( int ) $_POST ['id_pet'],
				'id_unidade' => ( int ) $tipoconvenio [0] ['id_unidade']
			] )
			->getResultArray();

		$comandaAtivaId = count( $comandaAtiva ) ? $comandaAtiva [0] ['comanda_id'] : 0;
		$usuarioId = UsuarioLogado::getUsuarioId();

		if ($comandaAtivaId) {
			$comandaId = $comandaAtivaId;
		} else {
			$conn->query( $sqlInserirComanda, $bindsInserirComanda );
			$comandaId = $conn->insertID();
		}

		$sqlInserirComandaItem = <<<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)
		    select
		        $comandaId as id_comanda
		        ,cp.id_procedimento as id_procedimento
		        ,cp.id_convenio as id_convenio
		        ,pv.valor as valor
		        ,0 as status_item
		        ,$usuarioId as criado_por
		        ,1 as comanda_item_status_id
		        ,now() as data_criacao
		        ,now() as hora_criacao
		        ,$requisicaoId as id_requisicao_procedimento
		    from procedimento_valor pv
		    inner join convenio_procedimento cp on pv.id_convenio_procedimento = cp.id
		    where
		        pv.id_convenio_procedimento = :convenio_procedimento_id:
		        and ((NOW() BETWEEN pv.data_inicio and pv.data_fim) or (pv.data_inicio <= now() and pv.data_fim ='1900-01-01') )
		    limit 1
		SQL;
		$bindsInserirComandaItem = [ 
			'convenio_procedimento_id' => ( int ) $_POST ['id_convenio_procedimento']
		];
		$conn->query( $sqlInserirComandaItem, $bindsInserirComandaItem );
		// }
		$error = $conn->error();
		if (!$error ['code']) {
			$sql_tipo_convenio = <<<SQL
				select
					rp.id as requisicao_id, rp.id_pet, cp.id as convenio_procedimento_id,
					cp.id_convenio as convenio_id, tc.id as tipo_convenio_id ,
					tc.descricao as tipo_convenio
				from
					requisicao_procedimento rp, convenio_procedimento cp,
					convenio c , tipo_convenio tc
				where
					rp.id  = :requisicao_id:
					and rp.id_convenio_procedimento = cp.id
					and cp.id_convenio = c.id
					and c.id_tipo_convenio =tc.id
			SQL;

			$binds_tipo_convenio = [ 
				'requisicao_id' => $requisicaoId
			];

			$result_tc = $conn->query( $sql_tipo_convenio, $binds_tipo_convenio )
				->getResultArray();
			$error = $conn->error();

			if (!$error ['code']) {
				$idTipoConvenio = $result_tc [0] ['tipo_convenio_id'];
				if ((intval( $idTipoConvenio ) == 1) || (intval( $idTipoConvenio ) == 3)) {
					$sql_update_pbpg = <<<SQL
						update comanda_item
						set comanda_item_status_id = 2
						where id_requisicao_procedimento = :requisicao_id:
					SQL;
					$binds_update_pbpg = [ 
						'requisicao_id' => $requisicaoId
					];
					$conn->query( $sql_update_pbpg, $binds_update_pbpg );
					$error = $conn->error();
				}
			}
		}
		return $this->response->setStatusCode( $error ['code'] ? 400 : 200 )
			->setJSON( 
			[ 
				'message' => $error ['code'] ? 'Falha na operação' : 'Requisição cadastrada com sucesso.',
				'data' => $requisicaoId,
				'error' => $error
			] );

	}

	public function registerProcedimentoConsulta($id_cliente, $id_pet, $id_unidade) {

		if (!intval( $_POST ['id_convenio_procedimento'] )) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Convenio_procedimento invalido.',
				'error' => 'Convenio_procedimento invalido.'
			] );
		}
		
		$sqlValidaProcedimentoInternacao = <<<SQL
		    select * from convenio_procedimento cp where id = :id_convenio_procedimento: and id_procedimento = 1105
		SQL;
		
		$bindValidaProcedimentoInternacao = [
		    'id_convenio_procedimento' => $_POST['id_convenio_procedimento']
		];
		
		$query_result = db_connect()->query($sqlValidaProcedimentoInternacao, $bindValidaProcedimentoInternacao)->getResult();
		$status_comanda_pagamento = 1;
		if(count($query_result) > 0):
		$status_comanda_pagamento = 2;
		endif;

		$usr = UsuarioLogado::getUsuarioId();
		// Cria a requisição do procedimento
		$sql = <<<SQL
		    insert into requisicao_procedimento 
			(id_medico, id_convenio_procedimento, id_consulta, status_id, usuario_executor, 
			id_requisitante, data_requisicao, hora_requisicao, data_execucao, hora_execucao, id_pet)
		    values (
		        :id_medico:,
		        :id_convenio_procedimento:,
		        :id_consulta:,
		        :status_id:,
		        :usuario_executor:,
				:id_requisitante:,
		        :data_requisicao:,
		        :hora_requisicao:,
		        :data_execucao:,
		        :hora_execucao:,
		        :id_pet:
		    )
		SQL;

		$binds = [ 
			'id_medico' => null,
			'id_convenio_procedimento' => ( int ) $_POST ['id_convenio_procedimento'],
			'id_consulta' => null,
			'status_id' => 1, // CRIADO
			'usuario_executor' => UsuarioLogado::getUsuarioId(),
			'id_requisitante' => $usr,
			'data_requisicao' => date( 'Y-m-d' ),
			'hora_requisicao' => date( 'H:i:s' ),
			'data_execucao' => '1900-01-01',
			'hora_execucao' => '00:00:00',
			'id_pet' => ( int ) $id_pet
		];

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

		if ($error ['code'] != 0) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => $error ['message'],
				'error' => $error ['code']
			] );
		}

		// Finaliza criação da requisição de um procedimento

		// Cria a comanda e gera item pra comanda
		$requisicaoProcedimentoId = $requisicaoId;

		$sqlInserirComanda = <<<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;
		$bindsInserirComanda = [ 
			'data_criada' => date( 'Y-m-d' ),
			'hora_criada' => date( 'H:i:s' ),
			'criado_por' => UsuarioLogado::getUsuarioId(),
			'data_fechada' => '1900-01-01',
			'hora_fechada' => '00:00:00',
			'id_cliente' => ( int ) $id_cliente,
			'id_pet' => ( int ) $id_pet,
			'id_unidade' => ( int ) $id_unidade,
			'fechado_por' => null
		];

		$sqlComandaAtiva = <<<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;
		$comandaAtiva = $conn->query( $sqlComandaAtiva,
			[ 
				'cliente_id' => ( int ) $id_cliente,
				'id_pet' => ( int ) $id_pet,
				'id_unidade' => ( int ) $id_unidade
			] )
			->getResultArray();
		$comandaAtivaId = count( $comandaAtiva ) ? $comandaAtiva [0] ['comanda_id'] : 0;
		$usuarioId = UsuarioLogado::getUsuarioId();

		$conn->transBegin();
		if ($comandaAtivaId) {
			$comandaId = $comandaAtivaId;
		} else {
			$conn->query( $sqlInserirComanda, $bindsInserirComanda );
			$comandaId = $conn->insertID();
		}

		$sqlInserirComandaItem = <<<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)
		    select
		        $comandaId as id_comanda
		        ,cp.id_procedimento as id_procedimento
		        ,cp.id_convenio as id_convenio
		        ,pv.valor as valor
		        ,0 as status_item 
		        ,$usuarioId as criado_por
		        ,$status_comanda_pagamento as comanda_item_status_id               
		        ,now() as data_criacao
		        ,now() as hora_criacao
		        ,$requisicaoProcedimentoId as id_requisicao_procedimento
		    from procedimento_valor pv
		    inner join convenio_procedimento cp on pv.id_convenio_procedimento = cp.id
		    where
		        pv.id_convenio_procedimento = :convenio_procedimento_id:
		        and ((NOW() BETWEEN pv.data_inicio and pv.data_fim) or (pv.data_inicio <= now() and pv.data_fim ='1900-01-01') ) 	
		    limit 1
		SQL;
		$bindsInserirComandaItem = [ 
			'convenio_procedimento_id' => ( int ) $_POST ['id_convenio_procedimento']
		];
		$conn->query( $sqlInserirComandaItem, $bindsInserirComandaItem );
		// $conn->query( $sql, $binds );
		$error = $conn->error();
		if (!$error ['code']) {
			$sql_tipo_convenio = <<<SQL
				select
					rp.id as requisicao_id, rp.id_pet, cp.id as convenio_procedimento_id, 
					cp.id_convenio as convenio_id, tc.id as tipo_convenio_id ,
					tc.descricao as tipo_convenio
				from 
					requisicao_procedimento rp, convenio_procedimento cp, 
					convenio c , tipo_convenio tc
				where
					rp.id  = :requisicao_id:
					and rp.id_convenio_procedimento = cp.id
					and cp.id_convenio = c.id
					and c.id_tipo_convenio =tc.id 
			SQL;

			$binds_tipo_convenio = [ 
				'requisicao_id' => $requisicaoProcedimentoId
			];

			$result_tc = $conn->query( $sql_tipo_convenio, $binds_tipo_convenio )
				->getResultArray();
			$error = $conn->error();

			if (!$error ['code']) {
				$idTipoConvenio = $result_tc [0] ['tipo_convenio_id'];
				if ((intval( $idTipoConvenio ) == 1) || (intval( $idTipoConvenio ) == 3)) {
					$sql_update_pbpg = <<<SQL
						update comanda_item
						set comanda_item_status_id = 2
						where id_requisicao_procedimento = :requisicao_id:
					SQL;
					$binds_update_pbpg = [ 
						'requisicao_id' => $requisicaoProcedimentoId
					];
					$conn->query( $sql_update_pbpg, $binds_update_pbpg );
					$error = $conn->error();

					if (!$error ['code']) {
						$conn->transCommit();
					}
				} else {
					$conn->transCommit();
				}
			}
		}

		// Finaliza a criação da comanda e do item da comanda

		return $this->response->setStatusCode( $error ['code'] ? 400 : 200 )
			->setJSON( 
			[ 
				'message' => $error ['code'] ? 'Falha na operação' : 'Requisição cadastrada com sucesso.',
				'data' => $requisicaoId,
				'error' => $error
			] );

	}


    public function registerProcedimentoInternacao($id_cliente, $id_pet, $id_unidade)
    {

        if (!intval($_POST ['id_convenio_procedimento'])) {
            return $this->response->setStatusCode(400)
                ->setJSON([
                    'message' => 'Convenio_procedimento invalido.',
                    'error' => 'Convenio_procedimento invalido.'
                ]);
        }

        $sqlValidaProcedimentoInternacao = <<<SQL
		    select * from convenio_procedimento cp where id = :id_convenio_procedimento: and id_procedimento = 968
		SQL;

        $bindValidaProcedimentoInternacao = [
            'id_convenio_procedimento' => $_POST['id_convenio_procedimento']
        ];

        $query_result = db_connect()->query($sqlValidaProcedimentoInternacao, $bindValidaProcedimentoInternacao)->getResult();
        $status_comanda_pagamento = 1;
        if(count($query_result) > 0):
            $status_comanda_pagamento = 2;
            endif;

        $conn = db_connect();
        if($status_comanda_pagamento == 2):
            $sql = <<<SQL
                select * from internacao_pet ip where id_pet = :id_pet: order by criado_em desc limit 1
            SQL;

            $binds = [
                'id_pet' => ( int )$id_pet
            ];

            $query_result_2 = $conn->query($sql, $binds)->getResult();
            if (count($query_result_2) > 0) {
                if ($query_result_2[0]->status != 3) {
                    return $this->response->setStatusCode(400)
                        ->setJSON([
                            'message' => "Este pet já possui internação em aberto!",
                            'error' => 400
                        ]);
                }
            }
            endif;

        $usr = UsuarioLogado::getUsuarioId();
        // Cria a requisição do procedimento
        $sql = <<<SQL
		    insert into requisicao_procedimento 
			(id_medico, id_convenio_procedimento, id_consulta, status_id, usuario_executor, 
			id_requisitante, data_requisicao, hora_requisicao, data_execucao, hora_execucao, id_pet)
		    values (
		        :id_medico:,
		        :id_convenio_procedimento:,
		        :id_consulta:,
		        :status_id:,
		        :usuario_executor:,
				:id_requisitante:,
		        :data_requisicao:,
		        :hora_requisicao:,
		        :data_execucao:,
		        :hora_execucao:,
		        :id_pet:
		    )
		SQL;

        $binds = [
            'id_medico' => null,
            'id_convenio_procedimento' => ( int )$_POST ['id_convenio_procedimento'],
            'id_consulta' => null,
            'status_id' => 1, // CRIADO
            'usuario_executor' => UsuarioLogado::getUsuarioId(),
            'id_requisitante' => $usr,
            'data_requisicao' => date('Y-m-d'),
            'hora_requisicao' => date('H:i:s'),
            'data_execucao' => '1900-01-01',
            'hora_execucao' => '00:00:00',
            'id_pet' => ( int )$id_pet
        ];


        $conn->query($sql, $binds)->numRows;
        $error = $conn->error();
        $requisicaoId = $conn->insertID();

        if ($error ['code'] != 0) {
            return $this->response->setStatusCode(400)
                ->setJSON([
                    'message' => $error ['message'],
                    'error' => $error ['code']
                ]);
        }


        // valida se o procedimento é entrada de internação, se for persiste internação
        if($status_comanda_pagamento == 2){
            // Cria a internação do pet
            $sql = <<<SQL
                INSERT INTO internacao_pet 
                    (id_pet, id_unidade, id_requisicao, status, criado_em, alterado_em, criado_por, alterado_por)
                VALUES (:id_pet:, :id_unidade:, :id_requisicao:, :status:, :criado_em:, :alterado_em:, :criado_por:, :alterado_por:);
            SQL;

            $binds = [
                'id_pet' => (int) $id_pet,
                'id_unidade' => (int) $id_unidade,
                'id_requisicao' => $requisicaoId,
                'status' => 1, //ENTRADA INTERNAÇÃO
                'criado_em' => DateUtils::now(),
                'alterado_em' => DateUtils::now(),
                'criado_por' => UsuarioLogado::getUsuarioId(),
                'alterado_por' => UsuarioLogado::getUsuarioId()
            ];

            $conn->query( $sql, $binds )->numRows;
            $error = $conn->error();
            $internacaoId = $conn->insertID();

            if ($error ['code'] != 0) {
                return $this->response->setStatusCode( 400 )
                    ->setJSON( [
                        'message' => $error ['message'],
                        'error' => $error ['code']
                    ] );
            }
        }

        // Finaliza criação da requisição de um procedimento

        // Cria a comanda e gera item pra comanda
        $requisicaoProcedimentoId = $requisicaoId;

        $sqlInserirComanda = <<<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;
        $bindsInserirComanda = [
            'data_criada' => date('Y-m-d'),
            'hora_criada' => date('H:i:s'),
            'criado_por' => UsuarioLogado::getUsuarioId(),
            'data_fechada' => '1900-01-01',
            'hora_fechada' => '00:00:00',
            'id_cliente' => ( int )$id_cliente,
            'id_pet' => ( int )$id_pet,
            'id_unidade' => ( int )$id_unidade,
            'fechado_por' => null
        ];

        $sqlComandaAtiva = <<<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;
        $comandaAtiva = $conn->query($sqlComandaAtiva,
            [
                'cliente_id' => ( int )$id_cliente,
                'id_pet' => ( int )$id_pet,
                'id_unidade' => ( int )$id_unidade
            ])
            ->getResultArray();
        $comandaAtivaId = count($comandaAtiva) ? $comandaAtiva [0] ['comanda_id'] : 0;
        $usuarioId = UsuarioLogado::getUsuarioId();

        $conn->transBegin();
        if ($comandaAtivaId) {
            $comandaId = $comandaAtivaId;
        } else {
            $conn->query($sqlInserirComanda, $bindsInserirComanda);
            $comandaId = $conn->insertID();
        }

        $sqlInserirComandaItem = <<<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)
		    select
		        $comandaId as id_comanda
		        ,cp.id_procedimento as id_procedimento
		        ,cp.id_convenio as id_convenio
		        ,pv.valor as valor
		        ,0 as status_item 
		        ,$usuarioId as criado_por
		        ,$status_comanda_pagamento as comanda_item_status_id                
		        ,now() as data_criacao
		        ,now() as hora_criacao
		        ,$requisicaoProcedimentoId as id_requisicao_procedimento
		    from procedimento_valor pv
		    inner join convenio_procedimento cp on pv.id_convenio_procedimento = cp.id
		    where
		        pv.id_convenio_procedimento = :convenio_procedimento_id:
		        and ((NOW() BETWEEN pv.data_inicio and pv.data_fim) or (pv.data_inicio <= now() and pv.data_fim ='1900-01-01') ) 	
		    limit 1
		SQL;
        $bindsInserirComandaItem = [
            'convenio_procedimento_id' => ( int )$_POST ['id_convenio_procedimento']
        ];
        $conn->query($sqlInserirComandaItem, $bindsInserirComandaItem);
        // $conn->query( $sql, $binds );
        $error = $conn->error();
        if (!$error ['code']) {
            $sql_tipo_convenio = <<<SQL
				select
					rp.id as requisicao_id, rp.id_pet, cp.id as convenio_procedimento_id, 
					cp.id_convenio as convenio_id, tc.id as tipo_convenio_id ,
					tc.descricao as tipo_convenio
				from 
					requisicao_procedimento rp, convenio_procedimento cp, 
					convenio c , tipo_convenio tc
				where
					rp.id  = :requisicao_id:
					and rp.id_convenio_procedimento = cp.id
					and cp.id_convenio = c.id
					and c.id_tipo_convenio =tc.id 
			SQL;

            $binds_tipo_convenio = [
                'requisicao_id' => $requisicaoProcedimentoId
            ];

            $result_tc = $conn->query($sql_tipo_convenio, $binds_tipo_convenio)
                ->getResultArray();
            $error = $conn->error();

            if (!$error ['code']) {
                $idTipoConvenio = $result_tc [0] ['tipo_convenio_id'];
                if ((intval($idTipoConvenio) == 1) || (intval($idTipoConvenio) == 3)) {
                    $sql_update_pbpg = <<<SQL
						update comanda_item
						set comanda_item_status_id = 2
						where id_requisicao_procedimento = :requisicao_id:
					SQL;
                    $binds_update_pbpg = [
                        'requisicao_id' => $requisicaoProcedimentoId
                    ];
                    $conn->query($sql_update_pbpg, $binds_update_pbpg);
                    $error = $conn->error();

                    if (!$error ['code']) {
                        $conn->transCommit();
                    }
                } else {
                    $conn->transCommit();
                }
            }
        }
        // Finaliza a criação da comanda e do item da comanda

        return $this->response->setStatusCode( $error ['code'] ? 400 : 200 )
            ->setJSON(
                [
                    'message' => $error ['code'] ? 'Falha na operação' : 'Requisição cadastrada com sucesso.',
                    'data' => $requisicaoId,
                    'error' => $error
                ] );
    }


    public function registerProcedimentoSaidaInternacao($id_cliente, $id_pet, $id_unidade) {

        $sqlBuscaConvenioProcedimento = <<<SQL
		    select id from convenio_procedimento cp where cp.id_procedimento = 969 and id_unidade = $id_unidade
		SQL;

        $query_result = db_connect()->query($sqlBuscaConvenioProcedimento)->getResult();
        $convenio_procedimento_id = $query_result[0]->id;


        $usr = UsuarioLogado::getUsuarioId();
        // Cria a requisição do procedimento
        $sql = <<<SQL
		    insert into requisicao_procedimento 
			(id_medico, id_convenio_procedimento, id_consulta, status_id, usuario_executor, 
			id_requisitante, data_requisicao, hora_requisicao, data_execucao, hora_execucao, id_pet)
		    values (
		        :id_medico:,
		        :id_convenio_procedimento:,
		        :id_consulta:,
		        :status_id:,
		        :usuario_executor:,
				:id_requisitante:,
		        :data_requisicao:,
		        :hora_requisicao:,
		        :data_execucao:,
		        :hora_execucao:,
		        :id_pet:
		    )
		SQL;

        $binds = [
            'id_medico' => null,
            'id_convenio_procedimento' => $convenio_procedimento_id,
            'id_consulta' => null,
            'status_id' => 1, // CRIADO
            'usuario_executor' => UsuarioLogado::getUsuarioId(),
            'id_requisitante' => $usr,
            'data_requisicao' => date( 'Y-m-d' ),
            'hora_requisicao' => date( 'H:i:s' ),
            'data_execucao' => '1900-01-01',
            'hora_execucao' => '00:00:00',
            'id_pet' => ( int ) $id_pet
        ];

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

        if ($error ['code'] != 0) {
            return $this->response->setStatusCode( 400 )
                ->setJSON( [
                    'message' => $error ['message'],
                    'error' => $error ['code']
                ] );
        }


        // Cria a internação do pet
        $sql = <<<SQL
		    INSERT INTO internacao_pet 
		        (id_pet, id_unidade, id_requisicao, status, criado_em, alterado_em, criado_por, alterado_por)
		    VALUES  (:id_pet:, :id_unidade:, :id_requisicao:, :status:, :criado_em:, :alterado_em:, :criado_por:, :alterado_por:);
		SQL;

        $binds = [
            'id_pet' => (int) $id_pet,
            'id_unidade' => (int) $id_unidade,
            'id_requisicao' => (int) $requisicaoId,
            'status' => 3, //ALTA HOSPITALAR
            'criado_em' => DateUtils::now(),
            'alterado_em' => DateUtils::now(),
            'criado_por' => UsuarioLogado::getUsuarioId(),
            'alterado_por' => UsuarioLogado::getUsuarioId()
        ];

        $conn->query( $sql, $binds )->numRows;
        $error = $conn->error();
        $internacaoId = $conn->insertID();

        if ($error ['code'] != 0) {
            return $this->response->setStatusCode( 400 )
                ->setJSON( [
                    'message' => $error ['message'],
                    'error' => $error ['code']
                ] );
        }

        // Finaliza criação da requisição de um procedimento

        // Cria a comanda e gera item pra comanda
        $requisicaoProcedimentoId = $requisicaoId;

        $sqlInserirComanda = <<<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;
        $bindsInserirComanda = [
            'data_criada' => date( 'Y-m-d' ),
            'hora_criada' => date( 'H:i:s' ),
            'criado_por' => UsuarioLogado::getUsuarioId(),
            'data_fechada' => '1900-01-01',
            'hora_fechada' => '00:00:00',
            'id_cliente' => ( int ) $id_cliente,
            'id_pet' => ( int ) $id_pet,
            'id_unidade' => ( int ) $id_unidade,
            'fechado_por' => null
        ];

        $sqlComandaAtiva = <<<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;
        $comandaAtiva = $conn->query( $sqlComandaAtiva,
            [
                'cliente_id' => ( int ) $id_cliente,
                'id_pet' => ( int ) $id_pet,
                'id_unidade' => ( int ) $id_unidade
            ] )
            ->getResultArray();
        $comandaAtivaId = count( $comandaAtiva ) ? $comandaAtiva [0] ['comanda_id'] : 0;
        $usuarioId = UsuarioLogado::getUsuarioId();

        $conn->transBegin();
        if ($comandaAtivaId) {
            $comandaId = $comandaAtivaId;
        } else {
            $conn->query( $sqlInserirComanda, $bindsInserirComanda );
            $comandaId = $conn->insertID();
        }


        $sqlInserirComandaItem = <<<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)
		    select
		        $comandaId as id_comanda
		        ,cp.id_procedimento as id_procedimento
		        ,cp.id_convenio as id_convenio
		        ,pv.valor as valor
		        ,0 as status_item 
		        ,$usuarioId as criado_por
		        ,2 as comanda_item_status_id                
		        ,now() as data_criacao
		        ,now() as hora_criacao
		        ,$requisicaoProcedimentoId as id_requisicao_procedimento
		    from procedimento_valor pv
		    inner join convenio_procedimento cp on pv.id_convenio_procedimento = cp.id
		    where
		        pv.id_convenio_procedimento = :convenio_procedimento_id:
		        and ((NOW() BETWEEN pv.data_inicio and pv.data_fim) or (pv.data_inicio <= now() and pv.data_fim ='1900-01-01') ) 	
		    limit 1
		SQL;
        $bindsInserirComandaItem = [
            'convenio_procedimento_id' => $convenio_procedimento_id
        ];
        $conn->query( $sqlInserirComandaItem, $bindsInserirComandaItem );
        // $conn->query( $sql, $binds );
        $error = $conn->error();
        if (!$error ['code']) {
            $sql_tipo_convenio = <<<SQL
				select
					rp.id as requisicao_id, rp.id_pet, cp.id as convenio_procedimento_id, 
					cp.id_convenio as convenio_id, tc.id as tipo_convenio_id ,
					tc.descricao as tipo_convenio
				from 
					requisicao_procedimento rp, convenio_procedimento cp, 
					convenio c , tipo_convenio tc
				where
					rp.id  = :requisicao_id:
					and rp.id_convenio_procedimento = cp.id
					and cp.id_convenio = c.id
					and c.id_tipo_convenio =tc.id 
			SQL;

            $binds_tipo_convenio = [
                'requisicao_id' => $requisicaoProcedimentoId
            ];

            $result_tc = $conn->query( $sql_tipo_convenio, $binds_tipo_convenio )
                ->getResultArray();
            $error = $conn->error();

            if (!$error ['code']) {
                $idTipoConvenio = $result_tc [0] ['tipo_convenio_id'];
                if ((intval( $idTipoConvenio ) == 1) || (intval( $idTipoConvenio ) == 3)) {
                    $sql_update_pbpg = <<<SQL
						update comanda_item
						set comanda_item_status_id = 2
						where id_requisicao_procedimento = :requisicao_id:
					SQL;
                    $binds_update_pbpg = [
                        'requisicao_id' => $requisicaoProcedimentoId
                    ];
                    $conn->query( $sql_update_pbpg, $binds_update_pbpg );
                    $error = $conn->error();

                    if (!$error ['code']) {
                        $conn->transCommit();
                    }
                } else {
                    $conn->transCommit();
                }
            }
        }

        // Finaliza a criação da comanda e do item da comanda

        return $this->response->setStatusCode( $error ['code'] ? 400 : 200 )
            ->setJSON(
                [
                    'message' => $error ['code'] ? 'Falha na operação' : 'Requisição cadastrada com sucesso.',
                    'data' => $requisicaoId,
                    'error' => $error
                ] );

    }


    public function getRequisicoesInternacao($unidade_id) {

        $sql = <<<SQL
            SELECT 
                c.id as cliente_id, 
                pf.nome as nome_cliente, 
                p2.id as id_pet, 
                p2.nome as nome_pet, 
                rp.data_requisicao, 
                rp.hora_requisicao,
                rp.status_id,
                rp.data_execucao,
                rp.usuario_executor,
                ip.status as internacao_status 
            FROM 
                internacao_pet ip
                inner join requisicao_procedimento rp ON ip.id_requisicao = rp.id 
                inner join pet p2 on rp.id_pet = p2.id
                inner join pet_cliente pc on p2.id = pc.id_pet 
                inner join cliente c on pc.id_cliente = c.id 
                inner join pessoa_fisica pf on pf.id_pessoa = c.id_pessoa 
            WHERE 
                ip.status IN (1, 2)
              AND ip.id_unidade = :unidade:
              AND NOT EXISTS (
                SELECT 1
                FROM internacao_pet ip2
                WHERE ip.id_pet = ip2.id_pet
                  AND ip2.status = 3
                  AND ip2.criado_em > ip.criado_em
              )
              AND ip.criado_em = (
                SELECT MAX(ip2.criado_em)
                FROM internacao_pet ip2
                WHERE ip.id_pet = ip2.id_pet
                  AND ip2.status <> 3
              );
        SQL;

        $binds = [
            'unidade' => $unidade_id
        ];

        $query_result = db_connect()->query($sql, $binds)
            ->getResult();

        $resultado_mapeado = [];

        if (count($query_result) > 0) {
            foreach ($query_result as $row) {
                $label = "";
                $codigo = 0;
                if($row->status_id == 1 && $row->internacao_status == 1):
                    $codigo = 1;
                    $label = "Aguardando entrada internação";
                elseif ($row->status_id == 2 && $row->internacao_status == 1):
                    $codigo = 2;
                    $label = "Internado";
                elseif ($row->internacao_status == 2 ):
                    $codigo = 3;
                    $label = "Aguardando alta hospitalar";
                endif;

                $item_mapeado = [
                    'cliente_id' => $row->cliente_id,
                    'nome_cliente' => $row->nome_cliente,
                    'id_pet' => $row->id_pet,
                    'nome_pet' => $row->nome_pet,
                    'data_requisicao' => $row->data_requisicao,
                    'hora_requisicao' => $row->hora_requisicao,
                    'convenio_cliente_id' => $row->convenio_cliente_id,
                    'status_requisicao' => $row->status_id,
                    'nome_status_requisicao' => $label,
                    'codigo' => $codigo,
                    'data_execucao' => $row->data_execucao,
                    'usuario_executor' => $row->usuario_executor
                ];

                $resultado_mapeado[] = $item_mapeado;
            }
        }

        $status_code = count($resultado_mapeado) > 0 ? 200 : 204;
        $response = [
            'message' => 'Dados encontrados com sucesso.',
            'data' => $resultado_mapeado
        ];
        return $this->response->setStatusCode($status_code)
            ->setJSON($response);
    }



	public function registerProcedimentoRecepcaoExame() {

		$id_cliente = 0;
		$id_pet = 0;
		$id_unidade = 0;
		try {
			$id_cliente = intval( $_POST ["id_cliente"] );
			$id_pet = intval( $_POST ["id_pet"] );
			$id_unidade = intval( $_POST ["id_unidade"] );
			$usr = UsuarioLogado::getUsuarioId();
		} catch ( Exception $e ) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Dados incorretos',
				'data' => [ ],
				'error' => [ 
					'code' => $e->getCode(),
					'msg' => $e->getMessage()
				]
			] );
		}

		if (($id_cliente == 0) || ($id_pet == 0) || ($id_unidade == 0)) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Dados incorretos',
				'data' => [ ],
				'error' => ''
			] );
		}
		
		$sqlValidaProcedimentoInternacao = <<<SQL
		    select * from convenio_procedimento cp where id = :id_convenio_procedimento: and id_procedimento = 1247
		SQL;
		
		$bindValidaProcedimentoInternacao = [
		    'id_convenio_procedimento' => $_POST['id_convenio_procedimento']
		];
		
		$query_result = db_connect()->query($sqlValidaProcedimentoInternacao, $bindValidaProcedimentoInternacao)->getResult();
		$status_comanda_pagamento = 1;
		if(count($query_result) > 0):
		$status_comanda_pagamento = 2;
		endif;

		$sql_medico = <<<SQL
			select u.id as is_usuario , u.id_pessoa ,p.id as id_profissional, m.id as id_medico  
			from usuario u, profissional p , medico m
			where u.id = :usuario_id: and p.id_pessoa = u.id_pessoa and m.id_profissional = p.id 
		SQL;
		$bind_medico = [ 
			'usuario_id' => $usr
		];

		$conn_medico = db_connect();
		$result_medico = $conn_medico->query( $sql_medico, $bind_medico )
			->getResultArray();

		// Cria a requisição do procedimento
		$sql = <<<SQL
		    INSERT INTO requisicao_procedimento 
			(id_medico, id_convenio_procedimento, id_consulta, status_id, usuario_executor, id_requisitante, data_requisicao, hora_requisicao, data_execucao, hora_execucao, id_pet)
		    VALUES (
		        :id_medico:,
		        :id_convenio_procedimento:,
		        :id_consulta:,
		        :status_id:,
		        :usuario_executor:,
				:id_requisitante:,
		        :data_requisicao:,
		        :hora_requisicao:,
		        :data_execucao:,
		        :hora_execucao:,
		        :id_pet:
		    )
		SQL;
		if (count( $result_medico ) > 0) {
			$idMedico = $result_medico [0] ['id_medico'];
			$bind_sql = [ 
				'id_medico' => $idMedico,
				'id_convenio_procedimento' => ( int ) $_POST ['id_convenio_procedimento'],
				'id_consulta' => null,
				'status_id' => 1, // CRIADO
				'usuario_executor' => null,
				'id_requisitante' => $usr,
				'data_requisicao' => date( 'Y-m-d' ),
				'hora_requisicao' => date( 'H:i:s' ),
				'data_execucao' => '1900-01-01',
				'hora_execucao' => '00:00:00',
				'id_pet' => ( int ) $id_pet
			];
		} else {
			$bind_sql = [ 
				'id_medico' => null,
				'id_convenio_procedimento' => ( int ) $_POST ['id_convenio_procedimento'],
				'id_consulta' => null,
				'status_id' => 1, // CRIADO
				'usuario_executor' => null,
				'id_requisitante' => $usr,
				'data_requisicao' => date( 'Y-m-d' ),
				'hora_requisicao' => date( 'H:i:s' ),
				'data_execucao' => '1900-01-01',
				'hora_execucao' => '00:00:00',
				'id_pet' => ( int ) $id_pet
			];
		}

		$conn = db_connect();
		$conn->query( $sql, $bind_sql )->numRows;
		$requisicaoId = $conn->insertID();
		$error = $conn->error();

		if ($error ['code']) {
			die( 'Ocorreu um erro ao criar a requisição' );
		}

		// Finaliza criação da requisição de um procedimento

		// Cria a comanda e gera item pra comanda
		$requisicaoProcedimentoId = $requisicaoId;

		$sqlInserirComanda = <<<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;
		$bindsInserirComanda = [ 
			'data_criada' => date( 'Y-m-d' ),
			'hora_criada' => date( 'H:i:s' ),
			'criado_por' => UsuarioLogado::getUsuarioId(),
			'data_fechada' => '1900-01-01',
			'hora_fechada' => '00:00:00',
			'id_cliente' => ( int ) $id_cliente,
			'id_pet' => ( int ) $id_pet,
			'id_unidade' => ( int ) $id_unidade,
			'fechado_por' => null
		];

		$sqlComandaAtiva = <<<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;
		$comandaAtiva = $conn->query( $sqlComandaAtiva,
			[ 
				'cliente_id' => ( int ) $id_cliente,
				'id_pet' => ( int ) $id_pet,
				'id_unidade' => ( int ) $id_unidade
			] )
			->getResultArray();

		$comandaAtivaId = count( $comandaAtiva ) ? $comandaAtiva [0] ['comanda_id'] : 0;
		$usuarioId = UsuarioLogado::getUsuarioId();

		$conn->transBegin();
		if ($comandaAtivaId) {
			$comandaId = $comandaAtivaId;
		} else {
			$conn->query( $sqlInserirComanda, $bindsInserirComanda );
			$comandaId = $conn->insertID();
		}

		$sqlInserirComandaItem = <<<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)
		    select
		        $comandaId as id_comanda
		        ,cp.id_procedimento as id_procedimento
		        ,cp.id_convenio as id_convenio
		        ,pv.valor as valor
		        ,0 as status_item 
		        ,$usuarioId as criado_por
		        ,$status_comanda_pagamento as comanda_item_status_id                
		        ,now() as data_criacao
		        ,now() as hora_criacao
		        ,$requisicaoProcedimentoId as id_requisicao_procedimento
		    from procedimento_valor pv
		    inner join convenio_procedimento cp on pv.id_convenio_procedimento = cp.id
		    where
		        pv.id_convenio_procedimento = :convenio_procedimento_id:
		        and ((NOW() BETWEEN pv.data_inicio and pv.data_fim) or (pv.data_inicio <= now() and pv.data_fim ='1900-01-01') ) 	
		    limit 1
		SQL;
		$bindsInserirComandaItem = [ 
			'convenio_procedimento_id' => ( int ) $_POST ['id_convenio_procedimento']
		];
		$conn->query( $sqlInserirComandaItem, $bindsInserirComandaItem );
		// $conn->query( $sql, $binds );
		$error = $conn->error();
		if (!$error ['code']) {
			$sql_tipo_convenio = <<<SQL
				select
					rp.id as requisicao_id, rp.id_pet, cp.id as convenio_procedimento_id,
					cp.id_convenio as convenio_id, tc.id as tipo_convenio_id ,
					tc.descricao as tipo_convenio
				from
					requisicao_procedimento rp, convenio_procedimento cp,
					convenio c , tipo_convenio tc
				where
					rp.id  = :requisicao_id:
					and rp.id_convenio_procedimento = cp.id
					and cp.id_convenio = c.id
					and c.id_tipo_convenio =tc.id
			SQL;

			$binds_tipo_convenio = [ 
				'requisicao_id' => $requisicaoProcedimentoId
			];

			$result_tc = $conn->query( $sql_tipo_convenio, $binds_tipo_convenio )
				->getResultArray();
			$error = $conn->error();

			if (!$error ['code']) {
				$idTipoConvenio = $result_tc [0] ['tipo_convenio_id'];
				if ((intval( $idTipoConvenio ) == 1) || (intval( $idTipoConvenio ) == 3)) {
					$sql_update_pbpg = <<<SQL
						update 
							comanda_item
						set 
							comanda_item_status_id = 2,
							data_atualizacao = :data_atz:,
							hora_atualizacao = :hora_atz:
							
						where id_requisicao_procedimento = :requisicao_id:
					SQL;
					$binds_update_pbpg = [ 
						'requisicao_id' => $requisicaoProcedimentoId,
						'data_atz' => DateUtils::today(),
						'hora_atz' => DateUtils::now_time()
					];
					$conn->query( $sql_update_pbpg, $binds_update_pbpg );
					$error = $conn->error();

					if (!$error ['code']) {
						$conn->transCommit();
					}
				} else {
					$conn->transCommit();
				}
			}
		}

		// Finaliza a criação da comanda e do item da comanda

		return $this->response->setStatusCode( $error ['code'] ? 400 : 200 )
			->setJSON( 
			[ 
				'message' => $error ['code'] ? 'Falha na operação' : 'Requisição cadastrada com sucesso.',
				'data' => $requisicaoId,
				'error' => $error
			] );

	}

	public function getRequisicoesEmAbertoByPetIdByUnidadeToAtender(int $pet_id, int $unidade_id): Response {

		$service = new RequisicaoService();
		$service_response = $service->getRequisicoesEmAbertoByPetIdByUnidadeToAtender( $pet_id, $unidade_id );

		$response_messages = [ 
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados foram encontrados com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_PARTIAL_CONTENT,
				'message' => 'Consulta realizada com sucesso. Não foram encontrado dados.'
			],
			ServiceResponseInterface::FORBIDDEN => [ 
				'code' => ResponseInterface::HTTP_FORBIDDEN,
				'message' => 'Usuário sem permissão para esta operação.'
			],
			ServiceResponseInterface::HAVE_CONFLICTS => [ 
				'code' => ResponseInterface::HTTP_CONFLICT,
				'message' => 'Dados conflitantes.'
			],
			ServiceResponseInterface::FOREIGN_KEY_DONT_EXISTS => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Dados inválidos.'
			],
			ServiceResponseInterface::INSUFFICIENT_DATA => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Dados inválidos.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::UNKNOWN_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_FAILED_DEPENDENCY,
				'message' => 'Erro interno decomunicação com Banco de dados.'
			]
		];

		return $this->getResponse( $service_response, $response_messages );

	}

	public function getRequisicoesExamesEmAbertoByPetIdUnidadeId(int $idPet, int $idUnidade): Response {

		$service = new RequisicaoService();
		$service_response = $service->getRequisicoesExamesEmAbertoByPetIdUnidadeId( $idPet, $idUnidade );

		$response_messages = [ 
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados foram encontrados com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_PARTIAL_CONTENT,
				'message' => 'Consulta realizada com sucesso. Não foram encontrado dados.'
			],
			ServiceResponseInterface::FORBIDDEN => [ 
				'code' => ResponseInterface::HTTP_FORBIDDEN,
				'message' => 'Usuário sem permissão para esta operação.'
			],
			ServiceResponseInterface::HAVE_CONFLICTS => [ 
				'code' => ResponseInterface::HTTP_CONFLICT,
				'message' => 'Dados conflitantes.'
			],
			ServiceResponseInterface::FOREIGN_KEY_DONT_EXISTS => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Dados inválidos.'
			],
			ServiceResponseInterface::INSUFFICIENT_DATA => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Dados inválidos.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::UNKNOWN_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_FAILED_DEPENDENCY,
				'message' => 'Erro interno decomunicação com Banco de dados.'
			]
		];

		return $this->getResponse( $service_response, $response_messages );

	}

	public function getRequisicoesEmAbertoByPetId(int $pet_id, int $unidade_id) {

		/*
		 * Retirados para o assistente ver os exames requisitados pela recepcao
		 * -- and rp.id_medico = m.id
		 * -- and id_consulta = cs.id
		 */
		// $sql = <<<SQL
		// select distinct
		// rp.id as requisicao_procedimento_id, rp.status_id as status_id
		// ,rp.data_requisicao as data_requisicao, rp.hora_execucao as hora_execucao
		// ,rp.status_anamnese as status_anamnese, rp.id_consulta_exame as id_consulta_exame
		// ,pr.id as procedimento_ide, pr.descricao as procedimento_descricao
		// ,tp.id as tipo_procedimento_id, tp.descricao as tipo_procedimento_descricao
		// ,cnv.id as convenio_id, cnv.codigo as convenio_codigo
		// ,cnv.descricao as convenio_descricao, tc.id as tipo_convenio_id
		// ,tc.descricao as tipo_convenio_descricao, rp.id_pet as pet_id
		// ,COALESCE(
		// (select id_formulario from procedimento_formulario prfm, formulario frm
		// where prfm.id_procedimento = pr.id
		// and prfm.id_formulario = frm.id
		// and frm.ativo = 1 limit 1),0) as formulario
		// from
		// requisicao_procedimento rp , convenio_procedimento cp, convenio cnv
		// , tipo_convenio tc ,pet pe, pet_cliente pc, cliente c ,pessoa_fisica pf
		// , tipo_procedimento tp , procedimento pr, medico m, consulta cs
		// where
		// cp.id_unidade = :unidade:
		// and rp.status_id =1
		// and cp.id = rp.id_convenio_procedimento
		// and cp.id_convenio = cnv.id
		// and cnv.id_tipo_convenio = tc.id
		// and cp.id_procedimento = pr.id
		// and pr.id_tipo_procedimento = tp.id
		// and tp.id = 4
		// and rp.id_pet = :petid:
		// and rp.id_pet = pe.id
		// and rp.id_pet = pc.id_pet
		// and pc.id_cliente = c.id
		// and c.id_pessoa = pf.id_pessoa
		// order by data_requisicao asc, hora_requisicao asc
		// SQL;
		$sql = <<<SQL
		select
		rp.id as requisicao_procedimento_id , rp.data_requisicao , rp.hora_requisicao , rp.status_anamnese ,
		rp.id_consulta , rp.id_pet as pet_id , rp.id_convenio_procedimento,cp.id_convenio , cp.id_procedimento as procedimento_id,
		p.descricao as procedimento_descricao , tp.id as tipo_procedimento_id ,tp.descricao as tipo_procedimento_descricao,
		c.id as convenio_id , c.descricao as convenio_descricao, c.codigo as convenio_codigo,
		tc.id as tipo_convenio_id ,tc.descricao as tipo_convenio_descricao, (select pf.nome from usuario u, pessoa_fisica pf 
					where u.id = rp.id_requisitante and u.id_pessoa = pf.id_pessoa
				) as nome,
		COALESCE(
				(select id_formulario from procedimento_formulario prfm, formulario frm
						where prfm.id_procedimento = p.id
						and prfm.id_formulario = frm.id
						and frm.ativo = 1 limit 1),0) as formulario
		from
			requisicao_procedimento rp, convenio_procedimento cp , procedimento p , tipo_procedimento tp,
			convenio c , tipo_convenio tc, comanda_item ci
		where
			rp.id_pet = :petid:
			and rp.status_id = 1
			and rp.id_convenio_procedimento  = cp.id
			and cp.id_unidade = :unidade:
			and cp.id_convenio = c.id
			and c.id_tipo_convenio = tc.id
			and cp.id_procedimento =p.id
			and p.id_tipo_procedimento = tp.id
			and ci.id_requisicao_procedimento = rp.id 
			and tp.id = 4
		SQL;
		$binds = [ 
			'unidade' => $unidade_id,
			'petid' => $pet_id
		];

        if (!is_null($_GET['status_comanda']) && $_GET['status_comanda'] == 2) {
            // Adicione o filtro no SQL e adicione o parâmetro no array de binds
            $sql .= ' AND ci.comanda_item_status_id = :comandaid:';
            $binds['comandaid'] = 2;
        }

		$query_result = db_connect()->query( $sql, $binds )
			->getResult();

		return $this->response->setStatusCode( count( $query_result ) > 0 ? 200 : 204 )
			->setJSON( [ 
			'message' => 'Dados encontrados com sucesso.',
			'data' => $query_result
		] );

	}

	public function getRequisicoesConsultasEmAbertoByPetId(int $pet_id) {

		$petId = $pet_id ?? 0;

		$sql = <<<SQL
		    select
		        rp.id as requisicao_procedimento_id
		        ,rp.data_requisicao  as data_requisicao
		        ,rp.hora_execucao as hora_execucao
		        ,p.id as procedimento_id
		        ,p.descricao as procedimento_descricao
		        ,tp.id as tipo_procedimento_id
		        ,tp.descricao as tipo_procedimento_descricao
		        ,cvn.id as convenio_id
		        ,cvn.codigo as convenio_codigo
		        ,cvn.descricao as convenio_descricao
		        ,tc.id as tipo_convenio_id
		        ,tc.descricao  as tipo_convenio_descricao
		        ,rp.id_pet as pet_id, (select pf.nome from usuario u, pessoa_fisica pf 
					where u.id = rp.id_requisitante and u.id_pessoa = pf.id_pessoa
				) as nome
		    from 
		    	requisicao_procedimento rp, procedimento p ,tipo_procedimento tp 
		    	, tipo_convenio tc, convenio cvn, convenio_procedimento cp
		    where
		        rp.id_pet  = :pet_id:
		        and rp.status_id = 1
		        and cvn.id = cp.id_convenio
		        and p.id = cp.id_procedimento
		        and tc.id = cvn.id_tipo_convenio
		        and cp.id = rp.id_convenio_procedimento
		        and tp.id = p.id_tipo_procedimento
				and tp.id = 2		        
		    order by rp.data_requisicao desc, rp.hora_execucao, p.descricao
		SQL;
		$data = db_connect()->query( $sql, [ 
			'pet_id' => $petId
		] )
			->getResultArray();
		return $this->response->setStatusCode( count( $data ) > 0 ? 200 : 404 )
			->setJSON( [ 
			'message' => 'Dados encontrados com sucesso.',
			'data' => $data
		] );

		if (count( $data ) > 0) {
			return $this->response->setStatusCode( 200 )
				->setJSON( [ 
				'message' => 'Dados encontrados com sucesso.',
				'data' => $data
			] );
		}
		if (count( $data ) == 0) {
			return $this->response->setStatusCode( 204 )
				->setJSON( [ 
				'message' => 'Nenhum dado encontrado.',
				'data' => $data
			] );
		}

	}

	public function getRequisicoesInternacaoEmAbertoByPetId($pet_id, $unidade_id) {

		/*
		 * Retirados para o assistente ver os exames requisitados pela recepcao
		 * -- and rp.id_medico = m.id
		 * -- and id_consulta = cs.id
		 */
		$sql = <<<SQL
			SELECT
			    rp.id AS requisicao_procedimento_id,
			    rp.status_id AS status_id,
			    rp.data_requisicao AS data_requisicao,
			    rp.hora_requisicao AS hora_requisicao,rp.hora_execucao AS hora_execucao,rp.status_anamnese AS status_anamnese,
			    rp.id_consulta_exame AS id_consulta_exame,
			    pr.id AS procedimento_ide,
			    pr.descricao AS procedimento_descricao,
			    tp.id AS tipo_procedimento_id,
			    tp.descricao AS tipo_procedimento_descricao,
			    cnv.id AS convenio_id,
			    cnv.codigo AS convenio_codigo,
			    cnv.descricao AS convenio_descricao,
			    tc.id AS tipo_convenio_id,
			    tc.descricao AS tipo_convenio_descricao,
			    rp.id_pet AS pet_id, (select pf.nome from usuario u, pessoa_fisica pf 
					where u.id = rp.id_requisitante and u.id_pessoa = pf.id_pessoa
				) as nome
			FROM requisicao_procedimento rp
			    JOIN convenio_procedimento cp ON cp.id = rp.id_convenio_procedimento
			    JOIN convenio cnv ON cp.id_convenio = cnv.id
			    JOIN tipo_convenio tc ON cnv.id_tipo_convenio = tc.id
			    JOIN pet pe ON rp.id_pet = pe.id
			    JOIN pet_cliente pc ON rp.id_pet = pc.id_pet
			    JOIN cliente c ON pc.id_cliente = c.id
			    JOIN pessoa_fisica pf ON c.id_pessoa = pf.id_pessoa
			    JOIN procedimento pr ON cp.id_procedimento = pr.id
			    JOIN tipo_procedimento tp ON pr.id_tipo_procedimento = tp.id
			    JOIN comanda_item ci ON ci.id_requisicao_procedimento = rp.id
			WHERE cp.id_unidade = :unidade:
			  AND rp.status_id = 1
			  AND tp.id = 6
			  AND rp.id_pet = :petid:
		SQL;

		$binds = [ 
			'unidade' => $unidade_id,
			'petid' => $pet_id
		];

        if (!is_null($_GET['status_comanda']) && $_GET['status_comanda'] == 2) {
            // Adicione o filtro no SQL e adicione o parâmetro no array de binds
            $sql .= ' AND ci.comanda_item_status_id = :comandaid:';
            $binds['comandaid'] = 2;
        }

        $sql .= ' ORDER BY data_requisicao ASC, hora_requisicao ASC;';

		$query_result = db_connect()->query( $sql, $binds )
			->getResult();



		return $this->response->setStatusCode( count( $query_result ) > 0 ? 200 : 204 )
			->setJSON( [ 
			'message' => 'Dados encontrados com sucesso.',
			'data' => $query_result
		] );

	}

    public function getFormularioInternacaoByTipo($tipo) {

        if($tipo == 1):
            $procedimento = 969;
        elseif($tipo == 2):
            $procedimento = 970;
        elseif($tipo == 3):
            $procedimento = 971;
        else:
            return $this->response->setStatusCode( 400 )
                ->setJSON([
                    'message' => 'Dados incorretos',
                    'data' => [ ],
                    'error' => [
                        'code' => 400,
                        'msg' => "O tipo de procedimento não é válido"
                    ]
                ]);
        endif;

        $sql = <<<SQL
			SELECT f.id, f.titulo from procedimento_formulario pf 
		    INNER JOIN formulario f on pf.id_formulario = f.id  
		    WHERE pf.id_procedimento = :procedimento:
		SQL;

        $binds = [
            'procedimento' => $procedimento
        ];

        $query_result = db_connect()->query( $sql, $binds )
            ->getResult();

        return $this->response->setStatusCode( count( $query_result ) > 0 ? 200 : 204 )
            ->setJSON( [
                'message' => 'Dados encontrados com sucesso.',
                'data' => $query_result
            ] );

    }
    
    public function getRequisicoesHigieneEmAbertoByPetIdUnidadeId($pet_id, $unidade_id) {
        $comanda_status = null;
        if(!is_null($_GET['status_comanda'])){
            $comanda_status = $_GET['status_comanda'];
        }
        
        $service = new RequisicaoService();
        $service_response = $service->getRequisicoesHigieneEmAbertoByPetIdUnidadeId( $pet_id, $unidade_id, $comanda_status );
        
        $response_messages = [
            ServiceResponseInterface::SUCESS => [
                'code' => ResponseInterface::HTTP_OK,
                'message' => 'Os dados foram encontrados com sucesso.'
            ],
            ServiceResponseInterface::RECORD_NOT_FOUND => [
                'code' => ResponseInterface::HTTP_PARTIAL_CONTENT,
                'message' => 'Consulta realizada com sucesso. Não foram encontrado dados.'
            ],
            ServiceResponseInterface::FORBIDDEN => [
                'code' => ResponseInterface::HTTP_FORBIDDEN,
                'message' => 'Usuário sem permissão para esta operação.'
            ],
            ServiceResponseInterface::HAVE_CONFLICTS => [
                'code' => ResponseInterface::HTTP_CONFLICT,
                'message' => 'Dados conflitantes.'
            ],
            ServiceResponseInterface::FOREIGN_KEY_DONT_EXISTS => [
                'code' => ResponseInterface::HTTP_BAD_REQUEST,
                'message' => 'Dados inválidos.'
            ],
            ServiceResponseInterface::INSUFFICIENT_DATA => [
                'code' => ResponseInterface::HTTP_BAD_REQUEST,
                'message' => 'Dados inválidos.'
            ],
            ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [
                'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
                'message' => 'Erro interno do servidor.'
            ],
            ServiceResponseInterface::UNKNOWN_ERROR => [
                'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
                'message' => 'Erro interno do servidor.'
            ],
            ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [
                'code' => ResponseInterface::HTTP_FAILED_DEPENDENCY,
                'message' => 'Erro interno decomunicação com Banco de dados.'
            ]
        ];
        
        return $this->getResponse( $service_response, $response_messages );
    }

	public function getRequisicoesMedicacaoEmAbertoByPetId($pet_id, $unidade_id) {

		/*
		 * Retirados para o assistente ver os exames requisitados pela recepcao
		 * -- and rp.id_medico = m.id
		 * -- and id_consulta = cs.id
		 */
		// $sql = <<<SQL
		// select distinct
		// rp.id as requisicao_procedimento_id, rp.status_id as status_id
		// ,rp.data_requisicao as data_requisicao, rp.hora_execucao as hora_execucao
		// ,rp.status_anamnese as status_anamnese, rp.id_consulta_exame as id_consulta_exame
		// ,pr.id as procedimento_ide, pr.descricao as procedimento_descricao
		// ,tp.id as tipo_procedimento_id, tp.descricao as tipo_procedimento_descricao
		// ,cnv.id as convenio_id, cnv.codigo as convenio_codigo
		// ,cnv.descricao as convenio_descricao, tc.id as tipo_convenio_id
		// ,tc.descricao as tipo_convenio_descricao, rp.id_pet as pet_id
		// ,COALESCE(
		// (select id_formulario from procedimento_formulario prfm, formulario frm
		// where prfm.id_procedimento = pr.id
		// and prfm.id_formulario = frm.id
		// and frm.ativo = 1 limit 1),0) as formulario
		// from
		// requisicao_procedimento rp , convenio_procedimento cp, convenio cnv
		// , tipo_convenio tc ,pet pe, pet_cliente pc, cliente c ,pessoa_fisica pf
		// , tipo_procedimento tp , procedimento pr, medico m, consulta cs
		// where
		// cp.id_unidade = :unidade:
		// and rp.status_id = 1
		// and cp.id = rp.id_convenio_procedimento
		// and cp.id_convenio = cnv.id
		// and cnv.id_tipo_convenio = tc.id
		// and cp.id_procedimento = pr.id
		// and pr.id_tipo_procedimento = tp.id
		// and tp.id = 5
		// and rp.id_pet = :petid:
		// and rp.id_pet = pe.id
		// and rp.id_pet = pc.id_pet
		// and pc.id_cliente = c.id
		// and c.id_pessoa = pf.id_pessoa
		// order by data_requisicao asc, hora_requisicao asc
		// SQL;
		$sql = <<<SQL
			select
				rp.id as requisicao_procedimento_id , rp.data_requisicao , rp.hora_requisicao ,
				rp.status_anamnese , rp.id_consulta , rp.id_pet as pet_id , rp.id_convenio_procedimento,
				cp.id_convenio , cp.id_procedimento as procedimento_id,	p.descricao as procedimento_descricao ,
				tp.id as tipo_procedimento_id ,tp.descricao as tipo_procedimento_descricao,
				c.id as convenio_id , c.descricao as convenio_descricao, c.codigo as convenio_codigo,
				tc.id as tipo_convenio_id ,tc.descricao as tipo_convenio_descricao, (select pf.nome from usuario u, pessoa_fisica pf 
					where u.id = rp.id_requisitante and u.id_pessoa = pf.id_pessoa
				) as nome,
				COALESCE(
					(select 
						id_formulario 
					from 
						procedimento_formulario prfm, formulario frm
					where 
						prfm.id_procedimento = p.id
						and prfm.id_formulario = frm.id
						and frm.ativo = 1 limit 1),0)
				as formulario
			from
				requisicao_procedimento rp, convenio_procedimento cp , 
				procedimento p , tipo_procedimento tp,
				convenio c , tipo_convenio tc, comanda_item ci
			where
				rp.id_pet = :petid:
				and rp.status_id = 1
				and rp.id_convenio_procedimento  = cp.id
				and cp.id_unidade = :unidade:
				and cp.id_convenio = c.id
				and c.id_tipo_convenio = tc.id
				and cp.id_procedimento =p.id
				and p.id_tipo_procedimento = tp.id
				and tp.id = 5
			    and ci.id_requisicao_procedimento = rp.id 
		SQL;

		$binds = [ 
			'unidade' => $unidade_id,
			'petid' => $pet_id
		];

        if (!is_null($_GET['status_comanda']) && $_GET['status_comanda'] == 2) {
            // Adicione o filtro no SQL e adicione o parâmetro no array de binds
            $sql .= ' AND ci.comanda_item_status_id = :comandaid:';
            $binds['comandaid'] = 2;
        }

		$query_result = db_connect()->query( $sql, $binds )
			->getResult();

		return $this->response->setStatusCode( count( $query_result ) > 0 ? 200 : 204 )
			->setJSON( [ 
			'message' => 'Dados encontrados com sucesso.',
			'data' => $query_result
		] );

	}

	public function getRequisicoesCirurgiaEmAbertoByPetId($pet_id, $unidade_id) {

		/*
		 * Retirados para o assistente ver os exames requisitados pela recepcao
		 * -- and rp.id_medico = m.id
		 * -- and id_consulta = cs.id
		 */
// 		$sql = <<<SQL
// 			select distinct
// 				rp.id as requisicao_procedimento_id, rp.status_id as status_id
// 				,rp.data_requisicao  as data_requisicao, rp.hora_execucao as hora_execucao
// 				,rp.status_anamnese as status_anamnese, rp.id_consulta_exame as id_consulta_exame
// 				,pr.id as procedimento_ide, pr.descricao as procedimento_descricao
// 				,tp.id as tipo_procedimento_id, tp.descricao as tipo_procedimento_descricao
// 				,cnv.id as convenio_id, cnv.codigo as convenio_codigo
// 				,cnv.descricao as convenio_descricao, tc.id as tipo_convenio_id
// 				,tc.descricao  as tipo_convenio_descricao, rp.id_pet as pet_id
// 				,COALESCE(
// 					(select id_formulario from procedimento_formulario prfm, formulario frm
// 						where prfm.id_procedimento = pr.id
// 							and prfm.id_formulario = frm.id
// 							and frm.ativo = 1 limit 1),0) as formulario
// 			from
// 				requisicao_procedimento rp , convenio_procedimento cp, convenio cnv
// 				, tipo_convenio tc ,pet pe, pet_cliente pc, cliente c ,pessoa_fisica pf
// 				, tipo_procedimento tp , procedimento pr, medico m, consulta cs
// 			where
// 				cp.id_unidade = :unidade:
// 				and rp.status_id = 1
// 				and cp.id = rp.id_convenio_procedimento
// 				and cp.id_convenio = cnv.id
// 				and cnv.id_tipo_convenio = tc.id
// 				and cp.id_procedimento = pr.id
// 				and pr.id_tipo_procedimento = tp.id
// 				and tp.id = 3
// 				and rp.id_pet = :petid:
// 				and rp.id_pet = pe.id
// 				and rp.id_pet = pc.id_pet
// 				and pc.id_cliente = c.id
// 				and c.id_pessoa = pf.id_pessoa
// 			order by data_requisicao asc, hora_requisicao asc
// 		SQL;
		
		$sql = <<<SQL
			select distinct
				rp.id as requisicao_procedimento_id, rp.status_id as status_id
				,rp.data_requisicao  as data_requisicao, rp.hora_execucao as hora_execucao
				,rp.status_anamnese as status_anamnese, rp.id_consulta_exame as id_consulta_exame
				,pr.id as procedimento_ide, pr.descricao as procedimento_descricao
				,tp.id as tipo_procedimento_id, tp.descricao as tipo_procedimento_descricao
				,cnv.id as convenio_id, cnv.codigo as convenio_codigo
				,cnv.descricao as convenio_descricao, tc.id as tipo_convenio_id
				,tc.descricao  as tipo_convenio_descricao, rp.id_pet as pet_id, (select pf.nome from usuario u, pessoa_fisica pf 
					where u.id = rp.id_requisitante and u.id_pessoa = pf.id_pessoa
				) as nome	
			from
				requisicao_procedimento rp , convenio_procedimento cp, convenio cnv, 
				tipo_convenio tc ,pet pe, tipo_procedimento tp , procedimento pr
			where
				rp.id_pet = :petid:				
				and rp.status_id = 1
				and rp.id_convenio_procedimento = cp.id
				and cp.id_unidade = :unidade: 
				and cp.id_convenio = cnv.id
				and cnv.id_tipo_convenio = tc.id
				and cp.id_procedimento = pr.id
				and pr.id_tipo_procedimento = tp.id
				and tp.id = 3								
			order by data_requisicao asc, hora_requisicao asc
		SQL;

		$binds = [ 
			'unidade' => $unidade_id,
			'petid' => $pet_id
		];

		$query_result = db_connect()->query( $sql, $binds )
			->getResult();

		return $this->response->setStatusCode( count( $query_result ) > 0 ? 200 : 204 )
			->setJSON( [ 
			'message' => 'Dados encontrados com sucesso.',
			'data' => $query_result
		] );

	}

	public function getRequisicoesConsultasEmAbertoByPetIdByUnidadeId($pet_id, $unidade_id) {

		$petId = $pet_id ?? 0;

		$sql = <<<SQL
		select
		    rp.id as requisicao_procedimento_id
		    ,rp.data_requisicao  as data_requisicao
		    ,rp.hora_execucao as hora_execucao
		    ,p.id as procedimento_id
		    ,p.descricao as procedimento_descricao
		    ,tp.id as tipo_procedimento_id
		    ,tp.descricao as tipo_procedimento_descricao
		    ,cvn.id as convenio_id
		    ,cvn.codigo as convenio_codigo
		    ,cvn.descricao as convenio_descricao
		    ,tc.id as tipo_convenio_id
		    ,tc.descricao  as tipo_convenio_descricao
		    ,rp.id_pet as pet_id
		from
		    requisicao_procedimento rp, procedimento p ,tipo_procedimento tp
		    , tipo_convenio tc, convenio cvn, convenio_procedimento cp
		where
		    rp.id_pet  = :pet_id:
		    and rp.status_id = 1
		    and cvn.id = cp.id_convenio
		    and cp.id_unidade = :unidade_id:
		    and p.id = cp.id_procedimento
		    and tc.id = cvn.id_tipo_convenio
		    and cp.id = rp.id_convenio_procedimento
		    and tp.id = p.id_tipo_procedimento
			and tp.id = 2
		order by rp.data_requisicao desc, rp.hora_execucao, p.descricao
		SQL;
		$data = db_connect()->query( $sql, [ 
			'pet_id' => $petId,
			'unidade_id' => $unidade_id
		] )
			->getResultArray();
		return $this->response->setStatusCode( count( $data ) > 0 ? 200 : 404 )
			->setJSON( [ 
			'message' => 'Dados encontrados com sucesso.',
			'data' => $data
		] );

	}

	public function marcarComoExecutado($requisicao_procedimento_id) {

		$executor = UsuarioLogado::getUsuarioId();
		// 'usuario_id' => UsuarioLogado::getUsuarioId()
		$requisicaoProcedimentoId = $requisicao_procedimento_id ?? 0;
		$conn = db_connect();
		$sql = <<<SQL
		    update 
		        requisicao_procedimento 
		    set 
		        status_id = 2,
		        usuario_executor = :usuario_id:,
		        data_execucao = :data_execucao:,
		        hora_execucao = :hora_execucao:
		    where id = :requisicao_procedimento_id:
		SQL;
		$binds = [ 
			'usuario_id' => $executor,
			'data_execucao' => date( 'Y-m-d' ),
			'hora_execucao' => date( 'H:i:s' ),
			'requisicao_procedimento_id' => $requisicaoProcedimentoId
		];

		$sqlExisteNaComanda = <<<SQL
		    select id 
		    from comanda_item
		    where id_requisicao_procedimento = :requisicaoprocedimento:
		SQL;
		$binds_nacomanda = [ 
			'requisicaoprocedimento' => $requisicaoProcedimentoId
		];

		log_message( 'info', json_encode( [ 
			'sql' => $sqlExisteNaComanda,
			'binds' => $binds_nacomanda
		] ) );

		$dadosExisteNaComanda = $conn->query( $sqlExisteNaComanda, $binds_nacomanda )
			->getResultArray();

		log_message( 'info', json_encode( $dadosExisteNaComanda ) );

		if (count( $dadosExisteNaComanda ) > 0) {
			$conn->query( $sql, $binds );
			$error = $conn->error();
			if (!$error ['code']) {

				/* verificar se é publico */
				/* se for publico marcar na comanda como pago. */

				$sqlTipoConvenio = <<<SQL
				    select
				        c.id_tipo_convenio 
				    from 
				        requisicao_procedimento rp, convenio_procedimento cp, convenio c
				    where rp.id_convenio_procedimento = cp.id
				        and cp.id_convenio = c.id
				        and rp.id = :requisicaoprocedimento:
				
				SQL;
				$binds_tipoConvenio = [ 
					'requisicaoprocedimento' => $requisicaoProcedimentoId
				];

				$tipoConvenio = $conn->query( $sqlTipoConvenio, $binds_tipoConvenio )
					->getResultArray();
				log_message( 'info', json_encode( [ 
					'tipo_convenio' => $tipoConvenio
				] ) );

				// Se o convenio for público ele marca como pago
				if (intval( $tipoConvenio [0] ['id_tipo_convenio'] ) == 1) {
					log_message( 'info', json_encode( 'atualizar comanda_item -->-->' ) );
					$sqlUpdateComandaItem = <<<SQL
					    update
					        comanda_item
					    set
					        comanda_item_status_id = 2,
							atualizado_por = :usr:,
							data_atualizacao = :data:,
							hora_atualizacao = :hora:
					    where id_requisicao_procedimento = :requisicaoprocedimento:
					SQL;
					$binds_comandaItem = [ 
						'requisicaoprocedimento' => $requisicaoProcedimentoId,
						'usr' => $executor,
						'data' => DateUtils::today(),
						'hora' => DateUtils::now_time()
					];
					log_message( 'info', json_encode( $sqlUpdateComandaItem ) );
					$conn->query( $sqlUpdateComandaItem, $binds_comandaItem );
					$error = $conn->error();
					log_message( 'info', json_encode( $error ) );

					if (!$error ['code']) {
						return $this->response->setStatusCode( 200 )
							->setJSON( [ 
							'message' => 'Operação realizada com sucesso.'
						] );
					}
				}

				return $this->response->setStatusCode( 200 )
					->setJSON( [ 
					'message' => 'Operação realizada com sucesso.'
				] );
			}

			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Essa requisição não existe ou já foi executada.'
			] );
		}

		$data ['id_requisicao_procedimento'] = $requisicao_procedimento_id;
		$agendamentoDao = new ConsultaDAO();
		$id_agendamento = $agendamentoDao->registerAgendamentoBaseRequisicao( $data );
		$id_consulta = $agendamentoDao->registerConsultaEndpointRequisicao( $id_agendamento );
		$agendamentoDao->updateRequisicaoProcedimento( $requisicao_procedimento_id, $id_consulta );

		$sqlDadosRequisicao = <<<SQL
		    select
		        rp.id as requisicao_procedimento_id
		        ,age.id_cliente as cliente_id
		        ,ap.id_pet as pet_id
		        ,a.id_unidade  as unidade_id
		        ,rp.id_convenio_procedimento as convenio_procedimento_id
		    from requisicao_procedimento rp 
		    inner join consulta c ON c.id = rp.id_consulta 
		    inner join agendamento age on age.id = c.id_agendamento
		    inner join agendamento_pet ap on ap.id_agendamento = age.id
		    inner join agenda a on a.id = age.id_agenda 
		    where
		        rp.id = :requisicao_procedimento_id:
		        and rp.status_id  = 1
		SQL;

		$dadosRequisicao = $conn->query( $sqlDadosRequisicao, [ 
			'requisicao_procedimento_id' => $requisicaoProcedimentoId
		] )
			->getResultArray();

		if (!count( $dadosRequisicao )) {
			die( 'Essa requisição não existe ou já foi executada.' );
		}

		$dadosRequisicao = $dadosRequisicao [0];

		$sqlInserirComanda = <<<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;
		$bindsInserirComanda = [ 
			'data_criada' => date( 'Y-m-d' ),
			'hora_criada' => date( 'H:i:s' ),
			'criado_por' => UsuarioLogado::getUsuarioId(),
			'data_fechada' => '1900-01-01',
			'hora_fechada' => '00:00:00',
			'id_cliente' => $dadosRequisicao ['cliente_id'],
			'id_pet' => $dadosRequisicao ['pet_id'],
			'id_unidade' => $dadosRequisicao ['unidade_id'],
			'fechado_por' => null
		];

		$sqlComandaAtiva = <<<SQL
		        select
		            id as comanda_id
		        from comanda c
		        where
		            id_cliente = :cliente_id:
		            and id_pet = :id_pet:
		            and fechado_por is null
		SQL;

		$comandaAtiva = $conn->query( $sqlComandaAtiva, [ 
			'cliente_id' => $dadosRequisicao ['cliente_id'],
			'id_pet' => $dadosRequisicao ['pet_id']
		] )
			->getResultArray();
		$comandaAtivaId = count( $comandaAtiva ) ? $comandaAtiva [0] ['comanda_id'] : 0;
		$usuarioId = UsuarioLogado::getUsuarioId();

		$conn->transBegin();
		if ($comandaAtivaId) {
			$comandaId = $comandaAtivaId;
		} else {
			$conn->query( $sqlInserirComanda, $bindsInserirComanda );
			$comandaId = $conn->insertID();
		}

		$sqlInserirComandaItem = <<<SQL
		    insert into comanda_item (id_comanda, id_procedimento, id_convenio, valor, status_item, criado_por, comanda_item_status_id, data_atualizacao, hora_atualizacao, data_criacao, hora_criacao, id_requisicao_procedimento)
		    select
		        $comandaId as id_comanda
		        ,cp.id_procedimento as id_procedimento
		        ,cp.id_convenio as id_convenio
		        ,pv.valor as valor
		        ,0 as status_item 
		        ,$usuarioId as criado_por
		        ,1 as comanda_item_status_id
		        ,now() as data_atualizacao
		        ,now() as hora_atualizacao
		        ,now() as data_criacao
		        ,now() as hora_criacao
		        ,$requisicaoProcedimentoId as id_requisicao_procedimento
		    from procedimento_valor pv
		    inner join convenio_procedimento cp on pv.id_convenio_procedimento = cp.id
		    where
		        pv.id_convenio_procedimento = :convenio_procedimento_id:
		        and ((NOW() BETWEEN pv.data_inicio and pv.data_fim) or (pv.data_inicio <= now() and pv.data_fim ='1900-01-01') ) 	
		    limit 1
		SQL;
		$bindsInserirComandaItem = [ 
			'convenio_procedimento_id' => $dadosRequisicao ['convenio_procedimento_id']
		];
		$conn->query( $sqlInserirComandaItem, $bindsInserirComandaItem );
		$conn->query( $sql, $binds );
		$error = $conn->error();
		if (!$error ['code']) {
			$conn->transCommit();
		}
		return $this->response->setStatusCode( 200 )
			->setJSON( [ 
			'message' => 'Operação realizada com sucesso.'
		] );

	}

	public function getRequisicoesConsultasEmAberto($unidade_id) {

		$sql = <<<SQL
		    select distinct
		        rp.id,rp.id_convenio_procedimento ,rp.id_pet, pe.nome as nome_pet
		        , pc.id_cliente, pf.nome as nome_cliente, tp.id as id_tipo_procedimento
		        , tp.descricao as tipo_procedimento, pr.id as id_procedimento, pr.descricao 
		        , tc.id as id_tipo_convenio, tc.descricao as tipo_convenio, rp.data_requisicao 
		        , rp.hora_requisicao
		    from
		        requisicao_procedimento rp , convenio_procedimento cp, convenio cnv 
		        , tipo_convenio tc ,pet pe, pet_cliente pc, cliente c ,pessoa_fisica pf
		        , tipo_procedimento tp , procedimento pr
		    where
		        cp.id_unidade = :unidade:
		        and cp.id = rp.id_convenio_procedimento
		        and cp.id_convenio = cnv.id
		        and cnv.id_tipo_convenio = tc.id
		        and cp.id_procedimento = pr.id
		        and pr.id_tipo_procedimento = tp.id
		        and tp.id = 2
		        and rp.id_medico  is null
		        and id_consulta  is null
		        and rp.id_pet  = pe.id
		        and rp.id_pet  = pc.id_pet
		        and pc.id_cliente = c.id
		        and c.id_pessoa = pf.id_pessoa
		    order by data_requisicao asc, hora_requisicao asc
		SQL;

		$binds = [ 
			'unidade' => $unidade_id
		];

		$query_result = db_connect()->query( $sql, $binds )
			->getResult();

		return $this->response->setStatusCode( count( $query_result ) > 0 ? 200 : 204 )
			->setJSON( [ 
			'message' => 'Dados encontrados com sucesso.',
			'data' => $query_result
		] );

	}

	public function getRequisicoesExamesEmAberto($unidade_id) {

		/*
		 * and rp.id_medico = m.id
		 * and id_consulta = cs.id
		 */
		$sql = <<<SQL
		    select distinct
		        rp.id,rp.id_convenio_procedimento ,rp.id_pet, pe.nome as nome_pet
		        , pc.id_cliente, pf.nome as nome_cliente, tp.id as id_tipo_procedimento
		        , tp.descricao as tipo_procedimento, pr.id as id_procedimento, pr.descricao
		        , tc.id as id_tipo_convenio, tc.descricao as tipo_convenio, rp.data_requisicao
		        , rp.hora_requisicao
		    from
		        requisicao_procedimento rp , convenio_procedimento cp, convenio cnv
		        , tipo_convenio tc ,pet pe, pet_cliente pc, cliente c ,pessoa_fisica pf
		        , tipo_procedimento tp , procedimento pr, medico m, consulta cs
		    where
		        cp.id_unidade = :unidade:
				and rp.status_id =1
		        and cp.id = rp.id_convenio_procedimento
		        and cp.id_convenio = cnv.id
		        and cnv.id_tipo_convenio = tc.id
		        and cp.id_procedimento = pr.id
		        and pr.id_tipo_procedimento = tp.id
		        and tp.id = 4
		        and rp.id_pet  = pe.id
		        and rp.id_pet  = pc.id_pet
		        and pc.id_cliente = c.id
		        and c.id_pessoa = pf.id_pessoa		        
		    order by data_requisicao asc, hora_requisicao asc
		SQL;

		$binds = [ 
			'unidade' => $unidade_id
		];

		$query_result = db_connect()->query( $sql, $binds )
			->getResult();

		return $this->response->setStatusCode( count( $query_result ) > 0 ? 200 : 204 )
			->setJSON( [ 
			'message' => 'Dados encontrados com sucesso.',
			'data' => $query_result
		] );

	}

	public function getRequisicoesCirurgiasEmAberto($unidade_id) {

		$sql = <<<SQL
		    select distinct
		        rp.id,rp.id_convenio_procedimento ,rp.id_pet, pe.nome as nome_pet
		        , pc.id_cliente, pf.nome as nome_cliente, tp.id as id_tipo_procedimento
		        , tp.descricao as tipo_procedimento, pr.id as id_procedimento, pr.descricao
		        , tc.id as id_tipo_convenio, tc.descricao as tipo_convenio, rp.data_requisicao
		        , rp.hora_requisicao
		    from
		        requisicao_procedimento rp , convenio_procedimento cp, convenio cnv
		        , tipo_convenio tc ,pet pe, pet_cliente pc, cliente c ,pessoa_fisica pf
		        , tipo_procedimento tp , procedimento pr
		    where
		        cp.id_unidade = :unidade:
		        and cp.id = rp.id_convenio_procedimento
		        and cp.id_convenio = cnv.id
		        and cnv.id_tipo_convenio = tc.id
		        and cp.id_procedimento = pr.id
		        and pr.id_tipo_procedimento = tp.id
		        and tp.id = 3
		        and rp.id_medico  is null
		        and id_consulta  is null
		        and rp.id_pet  = pe.id
		        and rp.id_pet  = pc.id_pet
		        and pc.id_cliente = c.id
		        and c.id_pessoa = pf.id_pessoa
		    order by data_requisicao asc, hora_requisicao asc
		SQL;

		$binds = [ 
			'unidade' => $unidade_id
		];

		$query_result = db_connect()->query( $sql, $binds )
			->getResult();

		return $this->response->setStatusCode( count( $query_result ) > 0 ? 200 : 204 )
			->setJSON( [ 
			'message' => 'Dados encontrados com sucesso.',
			'data' => $query_result
		] );

	}

	public function CancelarRequisicaoConsultaByUser(int $requisicaoId) {

		try {
			$usuarioId = UsuarioLogado::getUsuarioId();
			/*
			 * ====================================
			 * $sql_req_det =<<<SQL
			 * select
			 * rp.id, rp.id_convenio_procedimento , rp.status_id ,ci.id as comanda_item_id,
			 * ci.comanda_item_status_id, tc.id as tipo_convenio_id, tc.descricao as tipo_convenio
			 * from requisicao_procedimento rp, convenio_procedimento cp , convenio c, tipo_convenio tc ,comanda_item ci
			 * where
			 * rp.id = :requisicao_id:
			 * and rp.id = ci.id_requisicao_procedimento
			 * and rp.id_convenio_procedimento = cp.id
			 * and cp.id_convenio = c.id
			 * and c.id_tipo_convenio = tc.id
			 * SQL;
			 *
			 * $binds_req_det = ['requisicao_id' => $requisicaoId];
			 *
			 * $conn_req_det = db_connect();
			 * $result_req_det = $conn_req_det->query($sql_req_det,$binds_req_det)->getResultArray();
			 * $error_req_det = $conn_req_det->error();
			 *
			 * if($error_req_det['code'] != 0) {
			 * return $this->response->setStatusCode( 400 )
			 * ->setJSON( [
			 * 'message' => 'Dados informados inválido.',
			 * 'error' => $error_req_det
			 * ] );
			 * }
			 *
			 * if((intval($result_req_det[0]['comanda_item_status_id']) != 1) &&
			 * (intval($result_req_det[0]['tipo_convenio_id']) != 1)) {
			 * return $this->response->setStatusCode( 403 )
			 * ->setJSON( [
			 * 'message' => 'Requisição não pode ser excluida por esse perfil.',
			 *
			 * ] );
			 * }
			 * ===================
			 */

			$sql_requisicao = <<<SQL
				select
					rp.id as rquisicao_id, rp.status_id requisicao_status_id,
					ci.id as comanda_item_id, ci.comanda_item_status_id
				from
					requisicao_procedimento rp, comanda_item ci
				where
					rp.status_id = 1
					and (rp.usuario_executor = :user_id: or rp.id_requisitante = :user_id:)
					and rp.id = ci.id_requisicao_procedimento
					and ci.comanda_item_status_id = 1
					and rp.id = :requisicao_id:
			SQL;

			$bind_requisicao = [ 
				'user_id' => $usuarioId,
				'requisicao_id' => $requisicaoId
			];

			$con_requisicao = db_connect();
			$result_requisicao = $con_requisicao->query( $sql_requisicao, $bind_requisicao )
				->getResultArray();
			$error_requisico = $con_requisicao->error();

			$con_requisicao->close();
			if (count( $result_requisicao ) == 0) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Dados informados inválido.',
					'data' => [ ]
				] );
			}

			$comanda_item_id = intval( $reslt_requisicao [0] ['comanda_item_id'] );

			$data_atualizacao = DateUtils::today();
			$hora_atualizacao = DateUtils::now_time();

			$sql_requisicao_excluir = <<<SQL
				update requisicao_procedimento 
					set status_id = 3, 
						data_atualizacao = :data_atz: , 
						hora_atualizacao = :hora_atz: ,
						atualizado_por = :usuario_id:
				where 
					id = :requisicao_id: 
			SQL;

			$bind_requisicao_excluir = [ 
				'requisicao_id' => $requisicaoId,
				'data_atz' => $data_atualizacao,
				'hora_atz' => $hora_atualizacao,
				'usuario_id' => $usuarioId
			];

			$con_requisicao_excluir = db_connect();
			$result_requisicao_excluir = $con_requisicao_excluir->query( $sql_requisicao_excluir, $bind_requisicao_excluir )
				->getResultArray();
			$error_requisicao_excluir = $con_requisicao_excluir->error();
			$affectRows_requisicao = $con_requisicao_excluir->affectedRows();
			$con_requisicao_excluir->close();

			if (intval( $affectRows_requisicao ) < 1) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Requisição já excluída ou não encontrada.',
					'data' => [ ]
				] );
			}

			$sql_comanda_item_excluir = <<<SQL
				update comanda_item
				set comanda_item_status_id = 3,
					atualizado_por = :usuario_id:,
					data_atualizacao = :data_atz:,
					hora_atualizacao = :hora_atz:
			where
				id_requisicao_procedimento = :requisicao_id:
				and comanda_item_status_id = 1
			SQL;

			$bind_comanda_item_excluir = [ 
				'requisicao_id' => $requisicaoId,
				'data_atz' => $data_atualizacao,
				'hora_atz' => $hora_atualizacao,
				'usuario_id' => $usuarioId
			];

			$con_comanda_item_excluir = db_connect();

			$result_comanda_item_excluir = $con_comanda_item_excluir->query( $sql_comanda_item_excluir, $bind_comanda_item_excluir )
				->getResultArray();
			$error_comanda_item_excluir = $con_comanda_item_excluir->error();
			$affectRows_comanda_item = $con_comanda_item_excluir->affectedRows();
			$con_comanda_item_excluir->close();

			if (intval( $affectRows_comanda_item ) < 1) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Item já excluído da comanda ou não encontrado.',
					'data' => [ ]
				] );
			}

			return $this->response->setStatusCode( 200 )
				->setJSON( [ 
				'message' => 'Requisiao cancelada com sucesso.',
				'data' => [ ]
			] );
		} catch ( Exception $e ) {
			return $this->response->setStatusCode( 460 )
				->setJSON( [ 
				'message' => 'falha ao pesquisar.',
				'data' => [ ],
				'error' => [ 
					'code' => $e->getCode(),
					'msg' => $e->getMessage()
				]
			] );
		}

	}

	public function CancelarRequisicaoExameByMedico(int $requisicaoId) {

		try {

			$usuarioId = UsuarioLogado::getUsuarioId();
			$data_atz = DateUtils::today();
			$hora_atz = DateUtils::now_time();

			$sql_req_det = <<<SQL
				select
					rp.id, rp.id_convenio_procedimento , rp.status_id ,ci.id as comanda_item_id,
					ci.comanda_item_status_id, tc.id as tipo_convenio_id, tc.descricao as tipo_convenio
				from requisicao_procedimento rp, convenio_procedimento cp , convenio c, tipo_convenio tc ,comanda_item ci
				where
					rp.id = :requisicao_id:
					and rp.id = ci.id_requisicao_procedimento
					and rp.id_convenio_procedimento = cp.id
					and cp.id_convenio = c.id
					and c.id_tipo_convenio = tc.id
			SQL;

			$binds_req_det = [ 
				'requisicao_id' => $requisicaoId
			];

			$conn_req_det = db_connect();
			$result_req_det = $conn_req_det->query( $sql_req_det, $binds_req_det )
				->getResultArray();
			$error_req_det = $conn_req_det->error();

			if ($error_req_det ['code'] != 0) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Dados informados inválido.',
					'error' => $error_req_det
				] );
			}

			if ((intval( $result_req_det [0] ['comanda_item_status_id'] ) != 1) && (intval( $result_req_det [0] ['tipo_convenio_id'] ) != 1)) {
				return $this->response->setStatusCode( 403 )
					->setJSON( [ 
					'message' => 'Requisição não pode ser excluida por esse perfil.'
				] );
			}

			/* recupera id do medico */
			$sql_medico = <<<SQL
				select distinct
					u.id, u.email, p.id as pessoa_id, prf.id as profissional_id, m.id as medico_id
				from
					usuario u, pessoa p, profissional prf, medico m
				where
					u.id = :usuario_id:
					and u.id_pessoa = p.id
					and p.id = prf.id_pessoa
					and prf.id = m.id_profissional  
			SQL;

			$binds_medico = [ 
				'usuario_id' => $usuarioId
			];
			/* ************************************************* */

			$result_medico = db_connect()->query( $sql_medico, $binds_medico )
				->getResult();

			if (count( $result_medico ) == 0) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Dados informados inválido.',
					'data' => [ ]
				] );
			}

			$medico = ( object ) $result_medico [0];

			$sql_reqmedico = <<<SQL
				select id 
				from requisicao_procedimento rp
				where
					rp.id  = :requisicao_id:
					and id_medico = :medico_id:
					and status_id = 1
			SQL;

			$binds_reqmedico = [ 
				'requisicao_id' => $requisicaoId,
				'medico_id' => $medico->medico_id
			];

			$result_reqmedico = db_connect()->query( $sql_reqmedico, $binds_reqmedico )
				->getResult();

			if (count( $result_reqmedico ) == 0) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Dados informados inválido.',
					'data' => [ ]
				] );
			}

			$sql_comandaitem = <<<SQL
				select 
					ci.id , ci.comanda_item_status_id
				from 
					comanda_item ci
				where
					id_requisicao_procedimento = :requisicao_id:
			SQL;

			$bind_comandaitem = [ 
				'requisicao_id' => $requisicaoId
			];

			$conn_comandaitem = db_connect();
			$result_comandaitem = $conn_comandaitem->query( $sql_comandaitem, $bind_comandaitem )
				->getResultArray();

			/* query cancelar requisicao */
			$sql_reqcancel = <<<SQL
				update requisicao_procedimento
					set status_id = 3,
						atualizado_por = :usuario_id:,
						data_atualizacao = :data_atz:,
						hora_atualizacao = :hora_atz:
				where
					id = :requisicao_id:
					and id_medico = :medico_id:
					and status_id = 1
			SQL;

			$binds_reqcancel = [ 
				'usuario_id' => $usuarioId,
				'requisicao_id' => $requisicaoId,
				'data_atz' => $data_atz,
				'hora_atz' => $hora_atz,
				'medico_id' => $medico->medico_id
			];
			/* ************************************************** */

			if (count( $result_comandaitem ) == 0) {
				$conn_reqcancel = db_connect();
				$result_reqcancel = $conn_reqcancel->query( $sql_reqcancel, $binds_reqcancel )
					->getResultArray();
				$error_reqcancel = $conn_reqcancel->error();
				$affectedrows = $conn_reqcancel->affectedRows();
				$conn_reqcancel->close();
				if ($affectedrows == 0) {
					return $this->response->setStatusCode( 400 )
						->setJSON( [ 
						'message' => 'Dados informados inválido.',
						'data' => [ ]
					] );
				} else {
					return $this->response->setStatusCode( 200 )
						->setJSON( [ 
						'message' => 'Requisiao cancelada com sucesso.',
						'data' => [ ]
					] );
				}
			}

			$conn_reqcancel = db_connect();
			$result_reqcancel = $conn_reqcancel->query( $sql_reqcancel, $binds_reqcancel )
				->getResultArray();
			$error_reqcancel = $conn_reqcancel->error();
			$affectedrows_reqcancel = $conn_reqcancel->affectedRows();
			$conn_reqcancel->close();

			if ($affectedrows_reqcancel == 0) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Dados informados inválido.',
					'data' => [ ]
				] );
			}

			$sql_tipo_convenio = <<<SQL
				select 
					tc.id , tc.descricao
				from 
					requisicao_procedimento rp, convenio_procedimento cp, 
					convenio c , tipo_convenio tc
				where
					rp.id =:requisicao_id:
					and rp.id_convenio_procedimento = cp.id
					and cp.id_convenio = c.id
					and c.id_tipo_convenio = tc.id
			SQL;

			$binds_tipo_convenio = [ 
				'requisicao_id' => $requisicaoId
			];

			$conn_tipo_cpnvenio = db_connect();
			$result_tipo_convenio = $conn_tipo_cpnvenio->query( $sql_tipo_convenio, $binds_tipo_convenio )
				->getResultArray();

			$resp_tipo_convenio = $result_tipo_convenio [0];

			if ($resp_tipo_convenio ['id'] == 1) {
				$sql_comandaitemcancel = <<<SQL
					update comanda_item
						set comanda_item_status_id = 3,
							atualizado_por = :usuario_id:,
							data_atualizacao = :data_atz:,
							hora_atualizacao = :hora_atz:
					where
						id_requisicao_procedimento = :requisicao_id:
						and comanda_item_status_id = 2
				SQL;
			} else {

				$sql_comandaitemcancel = <<<SQL
					update comanda_item
						set comanda_item_status_id = 3,
							atualizado_por = :usuario_id:,
							data_atualizacao = :data_atz:,
							hora_atualizacao = :hora_atz:
					where
						id_requisicao_procedimento = :requisicao_id:
						and comanda_item_status_id = 1
				SQL;
			}
			$binds_comandaitemcancel = [ 
				'usuario_id' => $usuarioId,
				'requisicao_id' => $requisicaoId,
				'data_atz' => $data_atz,
				'hora_atz' => $hora_atz
			];

			$conn_comandaitemcancel = db_connect();
			$result_comandaitemcancel = $conn_comandaitemcancel->query( $sql_comandaitemcancel, $binds_comandaitemcancel )
				->getResultArray();
			$error_comandaitemcancel = $conn_comandaitemcancel->error();
			$affectedrows = $conn_comandaitemcancel->affectedRows();

			if ($affectedrows == 0) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Dados informados inválido.',
					'data' => [ ]
				] );
			}
			// $sql_reqcancel = <<<SQL
			// update requisicao_procedimento
			// set status_id = 3,
			// atualizado_por = :usuario_id:,
			// data_atualizacao = curdate(),
			// hora_atualizacao = curtime()
			// where
			// id = :requisicao_id:
			// and id_medico = :medico_id:
			// and status_id = 1
			// SQL;

			// $binds_reqcancel = [
			// 'usuario_id' => $usuarioId,
			// 'requisicao_id' => $requisicaoId,
			// 'medico_id' => $medico->medico_id
			// ];

			// $conn_reqcancel = db_connect();
			// $result_reqcancel = $conn_reqcancel->query( $sql_reqcancel, $binds_reqcancel )
			// ->getResultArray();
			// $error_reqcancel = $conn_reqcancel->error();
			// $affectedrows = $conn_reqcancel->affectedRows();
			// $conn_reqcancel->close();

			return $this->response->setStatusCode( 200 )
				->setJSON( [ 
				'message' => 'Requisiao cancelada com sucesso.',
				'data' => [ ]
			] );
		} catch ( Exception $e ) {
			return $this->response->setStatusCode( 460 )
				->setJSON( [ 
				'message' => 'operação falhou.',
				'data' => [ ],
				'error' => [ 
					'code' => $e->getCode(),
					'msg' => $e->getMessage()
				]
			] );
		}

	}

	public function CancelarRequisicaoExameByAssistente(int $requisicaoId) {

		try {

			$usuarioId = UsuarioLogado::getUsuarioId();
			$data_atz = DateUtils::today();
			$hora_atz = DateUtils::now_time();

			$sql_req_det = <<<SQL
				select 
					rp.id, rp.id_convenio_procedimento , rp.status_id ,ci.id as comanda_item_id,
					ci.comanda_item_status_id, tc.id as tipo_convenio_id, tc.descricao as tipo_convenio
				from requisicao_procedimento rp, convenio_procedimento cp , convenio c, tipo_convenio tc ,comanda_item ci  
				where 
					rp.id = :requisicao_id:
					and rp.id = ci.id_requisicao_procedimento 
					and rp.id_convenio_procedimento = cp.id 
					and cp.id_convenio = c.id
					and c.id_tipo_convenio = tc.id 
			SQL;

			$binds_req_det = [ 
				'requisicao_id' => $requisicaoId
			];

			$conn_req_det = db_connect();
			$result_req_det = $conn_req_det->query( $sql_req_det, $binds_req_det )
				->getResultArray();
			$error_req_det = $conn_req_det->error();

			if ($error_req_det ['code'] != 0) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Dados informados inválido.',
					'error' => $error_req_det
				] );
			}

			if ((intval( $result_req_det [0] ['comanda_item_status_id'] ) != 1) && (intval( $result_req_det [0] ['tipo_convenio_id'] ) != 1)) {
				return $this->response->setStatusCode( 403 )
					->setJSON( [ 
					'message' => 'Requisição não pode ser excluida por esse perfil.'
				] );
			}

			/* recupera id do medico */
			$sql_assistente = <<<SQL
				select distinct
					u.id, u.email, p.id as pessoa_id, prf.id as profissional_id, a.id as assitente_id
				from
					usuario u, pessoa p, profissional prf, assistente a
				where
					u.id = :usuario_id:
					and u.id_pessoa = p.id
					and p.id = prf.id_pessoa
					and prf.id = a.id_profissional
			SQL;

			$binds_assistente = [ 
				'usuario_id' => $usuarioId
			];
			/* ************************************************* */

			$result_assistente = db_connect()->query( $sql_assistente, $binds_assistente )
				->getResult();

			if (count( $result_assistente ) == 0) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Dados informados inválido.',
					'data' => [ ]
				] );
			}

			$assistente = ( object ) $result_assistente [0];

			$sql_reqassistente = <<<SQL
				select id
				from requisicao_procedimento rp
				where
					rp.id  = :requisicao_id:
					and id_requisitante = :usuario_id:
					and status_id = 1
			SQL;

			$binds_reqassistente = [ 
				'requisicao_id' => $requisicaoId,
				'usuario_id' => $usuarioId
			];

			$result_reqassistente = db_connect()->query( $sql_reqassistente, $binds_reqassistente )
				->getResult();

			if (count( $result_reqassistente ) == 0) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Dados informados inválido.',
					'data' => [ ]
				] );
			}

			$sql_comandaitem = <<<SQL
				select
					ci.id , ci.comanda_item_status_id
				from
					comanda_item ci
				where
					id_requisicao_procedimento = :requisicao_id:
			SQL;

			$bind_comandaitem = [ 
				'requisicao_id' => $requisicaoId
			];

			$conn_comandaitem = db_connect();
			$result_comandaitem = $conn_comandaitem->query( $sql_comandaitem, $bind_comandaitem )
				->getResultArray();

			/* query cancelar requisicao */
			$sql_reqcancel = <<<SQL
				update requisicao_procedimento
					set status_id = 3,
						atualizado_por = :usuario_id:,
						data_atualizacao = :data_atz:,
						hora_atualizacao = :hora_atz:
				where
					id = :requisicao_id:
					and id_requisitante = :assistente_id:
					and status_id = 1
			SQL;

			$binds_reqcancel = [ 
				'usuario_id' => $usuarioId,
				'requisicao_id' => $requisicaoId,
				'data_atz' => $data_atz,
				'hora_atz' => $hora_atz,
				'assistente_id' => $usuarioId
			];
			/* ************************************************** */

			if (count( $result_comandaitem ) == 0) {
				$conn_reqcancel = db_connect();
				$result_reqcancel = $conn_reqcancel->query( $sql_reqcancel, $binds_reqcancel )
					->getResultArray();
				$error_reqcancel = $conn_reqcancel->error();
				$affectedrows = $conn_reqcancel->affectedRows();
				$conn_reqcancel->close();
				if ($affectedrows == 0) {
					return $this->response->setStatusCode( 400 )
						->setJSON( [ 
						'message' => 'Dados informados inválido.',
						'data' => [ ]
					] );
				} else {
					return $this->response->setStatusCode( 200 )
						->setJSON( [ 
						'message' => 'Requisiao cancelada com sucesso.',
						'data' => [ ]
					] );
				}
			}

			$conn_reqcancel = db_connect();
			$result_reqcancel = $conn_reqcancel->query( $sql_reqcancel, $binds_reqcancel )
				->getResultArray();
			$error_reqcancel = $conn_reqcancel->error();
			$affectedrows_reqcancel = $conn_reqcancel->affectedRows();
			$conn_reqcancel->close();

			if ($affectedrows_reqcancel == 0) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Dados informados inválido.',
					'data' => [ ]
				] );
			}

			$sql_comandaitemcancel = <<<SQL
				update comanda_item
					set comanda_item_status_id = 3,
						atualizado_por = :usuario_id:,
						data_atualizacao = :data_atz:,
						hora_atualizacao = :hora_atz:
				where
					id_requisicao_procedimento = :requisicao_id:
					and comanda_item_status_id = 1
			SQL;

			$binds_comandaitemcancel = [ 
				'usuario_id' => $usuarioId,
				'requisicao_id' => $requisicaoId,
				'data_atz' => $data_atz,
				'hora_atz' => $hora_atz
			];

			$conn_comandaitemcancel = db_connect();
			$result_comandaitemcancel = $conn_comandaitemcancel->query( $sql_comandaitemcancel, $binds_comandaitemcancel )
				->getResultArray();
			$error_comandaitemcancel = $conn_comandaitemcancel->error();
			$affectedrows = $conn_comandaitemcancel->affectedRows();

			if ($affectedrows == 0) {
				return $this->response->setStatusCode( 400 )
					->setJSON( [ 
					'message' => 'Dados informados inválido.',
					'data' => [ ]
				] );
			}
			// $sql_reqcancel = <<<SQL
			// update requisicao_procedimento
			// set status_id = 3,
			// atualizado_por = :usuario_id:,
			// data_atualizacao = curdate(),
			// hora_atualizacao = curtime()
			// where
			// id = :requisicao_id:
			// and id_medico = :medico_id:
			// and status_id = 1
			// SQL;

			// $binds_reqcancel = [
			// 'usuario_id' => $usuarioId,
			// 'requisicao_id' => $requisicaoId,
			// 'medico_id' => $medico->medico_id
			// ];

			// $conn_reqcancel = db_connect();
			// $result_reqcancel = $conn_reqcancel->query( $sql_reqcancel, $binds_reqcancel )
			// ->getResultArray();
			// $error_reqcancel = $conn_reqcancel->error();
			// $affectedrows = $conn_reqcancel->affectedRows();
			// $conn_reqcancel->close();

			return $this->response->setStatusCode( 200 )
				->setJSON( [ 
				'message' => 'Requisiao cancelada com sucesso.',
				'data' => [ ]
			] );
		} catch ( Exception $e ) {
			return $this->response->setStatusCode( 460 )
				->setJSON( [ 
				'message' => 'operação falhou.',
				'data' => [ ],
				'error' => [ 
					'code' => $e->getCode(),
					'msg' => $e->getMessage()
				]
			] );
		}

	}

	public function requisicaoProcedimentoTeleconsulta() {

		$usr = UsuarioLogado::getUsuarioId();
		// CAPTURA CONVENIO PROCEDIMENTO DE UMA UNIDADE TELEVET COM CONVENIO PUBLICO
		$sqlConvenioProcedimento = <<<SQL
		   select 
		        cp.id as id_convenio_procedimento, 
		        cp.id_convenio, 
		        ep.id_procedimento, 
		        ep.id_especialidade  
		    from convenio_procedimento cp , convenio c , especialidade_procedimento ep 		       
		    where
		        c.id_tipo_convenio = 2 
		        and cp.id_unidade = :id_unidade: 
		        and cp.id_procedimento = :id_procedimento:
				and cp.id_convenio = c.id
				and cp.id_procedimento = ep.id_procedimento
				and ep.id_especialidade = :id_especialidade:	
		SQL;

		$conn = db_connect();

		$especialidadeProcedimento = $conn->query( $sqlConvenioProcedimento,
			[ 
				'id_unidade' => 24,
				'id_procedimento' => $_POST ['id_procedimento'],
				'id_especialidade' => $_POST ['id_especialidade']
			] )
			->getResultArray();
		$convenioProceimentoId = count( $especialidadeProcedimento ) ? $especialidadeProcedimento [0] ['id_convenio_procedimento'] : 0;
		$convenioId = count( $especialidadeProcedimento ) ? $especialidadeProcedimento [0] ['id_convenio'] : 0;
		$especialidadeId = count( $especialidadeProcedimento ) ? $especialidadeProcedimento [0] ['id_especialidade'] : 0;
		$conn->transBegin();

		// Cria a requisição do procedimento
		$sql = <<<SQL
		    INSERT INTO requisicao_procedimento 
			(id_medico, id_convenio_procedimento, id_consulta, status_id, usuario_executor, id_requisitante, data_requisicao, hora_requisicao, data_execucao, hora_execucao, id_pet)
		    VALUES (
		        :id_medico:,
		        :id_convenio_procedimento:,
		        :id_consulta:,
		        :status_id:,
		        :usuario_executor:,
				:id_requisitante:,
		        :data_requisicao:,
		        :hora_requisicao:,
		        :data_execucao:,
		        :hora_execucao:,
		        :id_pet:
		    )
		SQL;

		$conn->query( $sql,
			[ 
				'id_medico' => null,
				'id_convenio_procedimento' => ( int ) $convenioProceimentoId,
				'id_consulta' => null,
				'status_id' => 1, // CRIADO
				'usuario_executor' => null,
				'id_requisitante' => $usr,
				'data_requisicao' => date( 'Y-m-d' ),
				'hora_requisicao' => date( 'H:i:s' ),
				'data_execucao' => '1900-01-01',
				'hora_execucao' => '00:00:00',
				'id_pet' => ( int ) $_POST ['id_pet']
			] )->numRows;
		$requisicaoId = $conn->insertID();
		$error = $conn->error();

		if ($error ['code']) {
			die( 'Ocorreu um erro ao criar a requisição' );
		}

		// Finaliza criação da requisição de um procedimento

		// Cria a comanda e gera item pra comanda
		$requisicaoProcedimentoId = $requisicaoId;

		$consultaName = 'Consulta-' . $this->generateRandomString();

		// CRIAÇÃO DE SALA PARA REQUISICAO PROCEDIMENTO
		$curl = curl_init();
		curl_setopt_array( $curl,
			array (
				CURLOPT_URL => 'https://televplay.eadmeeting.com/api/v2/Meeting',
				CURLOPT_RETURNTRANSFER => true,
				CURLOPT_ENCODING => '',
				CURLOPT_MAXREDIRS => 10,
				CURLOPT_TIMEOUT => 0,
				CURLOPT_FOLLOWLOCATION => true,
				CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
				CURLOPT_CUSTOMREQUEST => 'POST',
				CURLOPT_POSTFIELDS => 'url=' . $consultaName . '&name=Participante&description=Teleconsulta&tipo=meeting',
				CURLOPT_HTTPHEADER => array (
					'Authorization: OTRhNWQ3YjY1NzRmZDU0Y2I4OTY4NDRlMjk2NGQ4M2QwYTRlYjM3Yw==',
					'Content-Type: application/x-www-form-urlencoded',
					'Cookie: PHPSESSID=thc4lcitp13cb16c0qduumqod5'
				)
			) );
		$video = json_decode( curl_exec( $curl ), true );

		curl_close( $curl );
		if ($video ['status'] == "success") {
			$sql = 'INSERT INTO requisicao_sala_video (
                    id_requisicao_procedimento,
                    id_meeting,
                    name_meeting,
                    description_meeting,
                    url_meeting,
                    tipo_meeting,
                    status_meeting,
                    tipoacesso_meeting,
                    stream_name_meeting,
                    live_stream_id_meeting
                ) VALUES ();
        ';
			$today = DateUtils::today();

			$values = "(
            {$requisicaoProcedimentoId},   
            {$video['meeting']['id']},   
            '{$video['meeting']['name']}',   
            '{$video['meeting']['description']}',   
            '{$video['meeting']['url']}',   
            '{$video['meeting']['tipo']}',   
            '{$video['meeting']['status']}',   
            '{$video['meeting']['tipoacesso']}',   
            '{$video['meeting']['stream_name']}',   
            '{$video['meeting']['live_stream_id']}'
        )";
			$sql = str_replace( 'VALUES ()', "VALUES $values", $sql );
			$query = $conn->query( $sql );
		}

		// CRIAÇÃO DE FILA DE ATENDIMENTO INSERTANDO O AGENDAMENTO ESPECIALIDADE NO PRÓXIMO HORÁRIO LIVRE
		$sql = <<<SQL
		    insert agendamento_especialidade set 
		        id_agenda_especialidade = (select ae.id from agenda_especialidade ae 
		        	left join agendamento_especialidade ae2 on ae.id = ae2.id_agenda_especialidade 
		        	where ae.id_unidade = 24 and ae.id_especialidade = :id_especialidade: 
						and ae.`data` = CURRENT_DATE() and ae.hora_inicio >= CURRENT_TIME() 
						and ae2.id is null limit 1), 
		        id_requisicao_procedimento = :id_requisicao_procedimento:,
				id_pet = :id_pet: ,
				id_procedimento = :id_procedimento:,
				criado_por = :id_usuario: ,
				data_criacao = :data_cr:,
				hora_criacao = :hora_cr:,
				id_status = 2
		SQL;

		$conn->query( $sql,
			[ 
				'id_especialidade' => ( int ) $especialidadeId,
				'id_requisicao_procedimento' => ( int ) $requisicaoProcedimentoId,
				'id_pet' => $_POST ['id_pet'],
				'id_procedimento' => $_POST ['id_procedimento'],
				'id_usuario' => UsuarioLogado::getUsuarioId(),
				'data_cr' => DateUtils::today(),
				'hora_cr' => DateUtils::now_time()
			] )->numRows;

		$filaId = $conn->insertID();
		$error = $conn->error();

		if ($error ['code']) {
			die( 'Ocorreu um erro ao criar a fila de atendimento, possivelmente nao existe horario disponível para a sua especialide.' );
		}

		$sqlInserirComanda = <<<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;
		$bindsInserirComanda = [ 
			'data_criada' => date( 'Y-m-d' ),
			'hora_criada' => date( 'H:i:s' ),
			'criado_por' => UsuarioLogado::getUsuarioId(),
			'data_fechada' => '1900-01-01',
			'hora_fechada' => '00:00:00',
			'id_cliente' => ( int ) $_POST ['id_cliente'],
			'id_pet' => ( int ) $_POST ['id_pet'],
			'id_unidade' => 24,
			'fechado_por' => null
		];

		$sqlComandaAtiva = <<<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;
		$comandaAtiva = $conn->query( $sqlComandaAtiva,
			[ 
				'cliente_id' => ( int ) $_POST ['id_cliente'],
				'id_pet' => ( int ) $_POST ['id_pet'],
				'id_unidade' => 24
			] )
			->getResultArray();
		$comandaAtivaId = count( $comandaAtiva ) ? $comandaAtiva [0] ['comanda_id'] : 0;
		$usuarioId = UsuarioLogado::getUsuarioId();

		// $conn->transBegin();
		if ($comandaAtivaId) {
			$comandaId = $comandaAtivaId;
		} else {
			$conn->query( $sqlInserirComanda, $bindsInserirComanda );
			$comandaId = $conn->insertID();
		}

		$sqlInserirComandaItem = <<<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)
		    select
		        $comandaId as id_comanda
		        ,cp.id_procedimento as id_procedimento
		        ,cp.id_convenio as id_convenio
		        ,pv.valor as valor
		        ,0 as status_item 
		        ,$usuarioId as criado_por
		        ,1 as comanda_item_status_id                
		        ,now() as data_criacao
		        ,now() as hora_criacao
		        ,$requisicaoProcedimentoId as id_requisicao_procedimento
		    from procedimento_valor pv
		    inner join convenio_procedimento cp on pv.id_convenio_procedimento = cp.id
		    where
		        pv.id_convenio_procedimento = :convenio_procedimento_id:
		        and ((NOW() BETWEEN pv.data_inicio and pv.data_fim) or (pv.data_inicio <= now() and pv.data_fim ='1900-01-01') ) 	
		    limit 1
		SQL;
		$bindsInserirComandaItem = [ 
			'convenio_procedimento_id' => ( int ) $convenioProceimentoId
		];
		$conn->query( $sqlInserirComandaItem, $bindsInserirComandaItem );
		// $conn->query( $sql, $binds );
		$error = $conn->error();

		if (!$error ['code']) {
			$conn->transCommit();
		}

		// Finaliza a criação da comanda e do item da comanda

		return $this->response->setStatusCode( $error ['code'] ? 400 : 200 )
			->setJSON( 
			[ 
				'message' => $error ['code'] ? 'Falha na operação' : 'Requisição cadastrada com sucesso.',
				'data' => $requisicaoId,
				'error' => $error
			] );

	}

	public function generateRandomString($length = 10): string {

		$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
		$charactersLength = strlen( $characters );
		$randomString = '';
		for($i = 0; $i < $length; $i++) {
			$randomString .= $characters [rand( 0, $charactersLength - 1 )];
		}
		return $randomString;

	}

}
