<?php

namespace App\Controllers;

use App\DAO\Pagination\Pagination;
use App\Services\JWT\UsuarioLogado;
use App\Services\ServiceResponse\ServiceResponseInterface;
use CodeIgniter\HTTP\Response;
use CodeIgniter\HTTP\ResponseInterface;
use Exception;

class ConvenioController extends BaseController {

	public function registerConvenio(): Response {

		$sql = <<<SQL
		    insert into convenio (codigo, descricao, id_tipo_convenio) 
		    values (
		        :codigo:
		        ,:descricao:
		        ,:id_tipo_convenio:
		    );
		SQL;
		$conn = db_connect();
		$conn->query( $sql, [ 
								'codigo' => $_POST ['codigo'],
								'descricao' => $_POST ['descricao'],
								'id_tipo_convenio' => $_POST ['id_tipo_convenio']
		] )->numRows;
		$convenioId = $conn->insertID();
		return $this->response->setStatusCode( 200 )
			->setJSON( [ 
							'message' => 'Convênio cadastrado com sucesso.',
							'data' => $convenioId
		] );

	}

	public function getConvenioList(): Response {

		$page = $_GET ['page'];
		$per_page = $_GET ['per_page'];
		$search = $_GET ['search'] ?? "";
		$offset = ($page - 1) * $per_page;
		$sql = <<<SQL
		    select 
		        c.id as convenio_id,
		        c.codigo as codigo,
		        c.descricao as convenio_descricao,
		        c.id_tipo_convenio as tipo_convenio_id,
		        tc.descricao as tipo_descricao
		    from convenio c
		    inner join tipo_convenio tc on tc.id = c.id_tipo_convenio
		    where 1=1
		SQL;
		$conn = db_connect();
		if ($search) {
			$search = $conn->escapeLikeString( $search );
			$sql .= " and c.descricao LIKE \"%$search%\"";
		}
		$sql .= " limit $per_page offset $offset";
		$query = $conn->query( $sql )
			->getResultArray();
		$paginationSql = <<<SQL
		    select count(*) c from convenio c
		    inner join tipo_convenio tc on tc.id = c.id_tipo_convenio
		SQL;
		$paginationQuery = db_connect()->query( $paginationSql )
			->getResultArray();
		$pagination = Pagination::builder()->setCurrentPage( $page )
			->setNumRows( $paginationQuery [0] ['c'] )
			->setPerPage( $per_page )
			->build();
		$result = [ 
						'convenios' => $query,
						'pagination' => $pagination->toResponseArray()
		];
		return $this->response->setStatusCode( 200 )
			->setJSON( [ 
							'message' => 'Dados encontrados com sucesso.',
							'data' => $result
		] );

	}

	public function searchConvenioByID(int $idConvenio): Response {

		$sql = <<<SQL
		    select 
		        c.id as convenio_id,
		        c.codigo as codigo,
		        c.descricao as convenio_descricao,
		        c.id_tipo_convenio as tipo_convenio_id,
		        tc.descricao as tipo_descricao
		    from convenio c
		    inner join tipo_convenio tc on tc.id = c.id_tipo_convenio 
		    where
		        c.id = :convenio_id:
		SQL;
		$query = db_connect()->query( $sql, [ 
												'convenio_id' => $idConvenio
		] )
			->getResult();
		return $this->response->setStatusCode( 200 )
			->setJSON( [ 
							'message' => 'Dados encontrados com sucesso.',
							'data' => $query
		] );

	}

	public function deleteConvenio(int $idConvenio) {

		$sql = "delete from convenio where id = :idConvenio:";
		try {
			db_connect()->query( $sql, [ 
											'idConvenio' => $idConvenio
			] );
			return $this->response->setStatusCode( 200 )
				->setJSON( [ 
								'message' => 'O convênio foi deletado com sucesso.',
								'data' => ''
			] );
		} catch ( Exception $exception ) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
								'message' => 'Esse convênio não pode ser deletado.',
								'data' => ''
			] );
		}

	}

	public function updateConvenio(int $idConvenio): Response {

		$sql = <<<SQL
		    update convenio 
		    set
		        codigo = :codigo:,
		        descricao = :descricao:,
		        id_tipo_convenio = :id_tipo_convenio:
		    WHERE
		        id = :convenio_id:
		SQL;

		$unidadeId = $_POST ['unidade_id'] ?? 0;
		$procedimentosRequest = $_POST ['procedimentos'] ?? [ ];

		if (!$unidadeId) {
			die( 'Informe uma unidade' );
		}

		$binds = [ 
					'codigo' => $_POST ['codigo'],
					'descricao' => $_POST ['descricao'],
					'id_tipo_convenio' => $_POST ['id_tipo_convenio'],
					'convenio_id' => $idConvenio
		];

		$sql_procedimentosExistentesNoConvenio = <<<SQL
			SELECT
				cp.id_procedimento as procedimento_id
			from convenio_procedimento cp
			WHERE
				cp.id_convenio = :convenio_id:
				and cp.id_unidade = :unidade_id: 
			GROUP by cp.id_procedimento
		SQL;

		$bind_procedimentosExistentesNoConvenio = [ 
														'convenio_id' => $idConvenio,
														'unidade_id' => $unidadeId
		];

		$conn = db_connect();

		$procedimentosExistentesNoConvenio = $conn->query( $sql_procedimentosExistentesNoConvenio, $bind_procedimentosExistentesNoConvenio )
			->getResultArray();

		$procedimentosParaSeremCadastrados = [ ];
		foreach ( $procedimentosRequest as $pid ) {
			foreach ( $procedimentosExistentesNoConvenio as $p ) {
				if ($p ['procedimento_id'] == $pid) {
					continue 2;
				}
			}
			$procedimentosParaSeremCadastrados [] = $pid;
		}
		$procedimentosParaAtivadosDesativadosValues = '(' . implode( ',', $procedimentosRequest ) . ')';

		$sqlDesativarTodosProcedimentos = <<<SQL
		    update 
		        convenio_procedimento 
		    set
		        desativado_em = now()
		        ,desativado_por = :usuario_id:
		    where 1=1
		        and id_convenio = :convenio_id:
		        and id_unidade = :unidade_id:
		SQL;

		$sqlAtivarProcedimentos = <<<SQL
		    update 
		        convenio_procedimento 
		    set
		        desativado_em = null
		        ,desativado_por = null
		    where
		        id_procedimento in $procedimentosParaAtivadosDesativadosValues
		        and id_unidade = :unidade_id:
		        and id_convenio = :convenio_id:
		SQL;

		$sqlCadastrarProcedimento = <<<SQL
		    insert into convenio_procedimento (id_convenio, id_procedimento, criado_em, atualizado_em, desativado_em, criado_por, alterado_por, desativado_por, id_unidade)
		    values (
		        :id_convenio:,
		        :id_procedimento:,
		        :criado_em:,
		        :atualizado_em:,
		        :desativado_em:,
		        :criado_por:,
		        :alterado_por:,
		        :desativado_por:, 
		        :id_unidade:
		    )
		SQL;

		try {
			$conn->transBegin();
			$conn->query( $sqlDesativarTodosProcedimentos,
					[ 
						'usuario_id' => UsuarioLogado::getUsuarioId(),
						'unidade_id' => $unidadeId,
						'convenio_id' => $idConvenio
					] );
			$conn->query( $sqlAtivarProcedimentos, [ 
														'unidade_id' => $unidadeId,
														'convenio_id' => $idConvenio
			] );
			foreach ( $procedimentosParaSeremCadastrados as $p ) {
				$conn->query( $sqlCadastrarProcedimento,
						[ 
							'id_convenio' => $idConvenio,
							'id_procedimento' => $p,
							'criado_em' => date( 'Y-m-d H:i:s' ),
							'atualizado_em' => date( 'Y-m-d H:i:s' ),
							'desativado_em' => null,
							'criado_por' => UsuarioLogado::getUsuarioId(),
							'alterado_por' => date( 'Y-m-d H:i:s' ),
							'desativado_por' => null,
							'id_unidade' => $unidadeId
						] );
			}
			$conn->query( $sql, $binds );
			$error = $conn->error();
			$success = $error ['code'] === 0;
			if ($success) {
				$conn->transCommit();
			}
			return $this->response->setStatusCode( $success ? 200 : 400 )
				->setJSON( [ 
								'message' => $success ? 'Os dados foram atualizados com sucesso.' : 'Erro.',
								'error' => $error
			] );
		} catch ( Exception $exception ) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
								'message' => 'Erro na atualização dos dados do convênio.',
								'data' => $exception->getMessage()
			] );
		}

	}

	public function getConvenioProcedimentoFilteredByUnidadeAndProcedimento(int $unidade_id, int $procedimento_id) {

		// $uri = explode('/', $_SERVER['REQUEST_URI']);
		$unidadeId = $unidade_id ?? 0;
		$procedimentoId = $procedimento_id ?? 0;
		if (!$unidadeId || !$procedimentoId) {
			return $this->response->setStatusCode( 404 );
		}
		// $sql = <<<SQL
		// select
		// cp.id as convenio_procedimento_id
		// ,c.id as convenio_id
		// ,c.codigo as convenio_codigo
		// ,c.descricao as convenio_descricao
		// ,tc.id as tipo_convenio_id
		// ,tc.descricao as tipo_convenio_descricao
		// ,cp.id_procedimento as procedimento_id
		// ,cp.id_unidade as unidade_id
		// from convenio_procedimento cp
		// inner join convenio c on c.id = cp.id_convenio
		// inner join tipo_convenio tc on tc.id = c.id_tipo_convenio
		// WHERE
		// cp.id_procedimento = :procedimento_id:
		// and cp.id_unidade = :unidade_id:
		// and cp.desativado_em is null
		// and cp.desativado_por is null
		// order by tc.id, c.descricao
		// SQL;

		$sql = <<<SQL
		    select distinct
		        cp.id as convenio_procedimento_id ,c.id as convenio_id
		        ,c.codigo as convenio_codigo ,c.descricao as convenio_descricao
		        ,tc.id as tipo_convenio_id ,tc.descricao as tipo_convenio_descricao
		        ,cp.id_procedimento as procedimento_id ,cp.id_unidade as unidade_id
		        ,pv.valor
		    from
		        convenio_procedimento cp ,procedimento_valor pv, procedimento p
		        , convenio c, tipo_convenio tc
		    where
		        cp.id_unidade = :unidade_id:
		        and cp.id_procedimento = :procedimento_id:
		        and cp.id = pv.id_convenio_procedimento
		        and cp.id_procedimento = p.id
		        and cp.id_convenio = c.id
		        and c.id_tipo_convenio = tc.id 
		SQL;

		$data = db_connect()->query( $sql, [ 
												'unidade_id' => $unidadeId,
												'procedimento_id' => $procedimentoId
		] )
			->getResultArray();

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

	}

}
