<?php

namespace App\Controllers;

use App\DAO\UnidadeDAO;
use App\DAO\Filter\QueryFilterTranslator;
use App\DAO\Order\QueryOrderTranslator;
use App\DAO\Pagination\Pagination;
use App\Services\UnidadeService;
use App\Services\ServiceResponse\ServiceResponseInterface;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\Validations\UnidadeUFValidation;
use App\Validations\UnidadeValidation;
use CodeIgniter\HTTP\Response;
use CodeIgniter\HTTP\ResponseInterface;

class UnidadeController extends BaseController {

	public function register(): Response {

		if (!$this->validate( UnidadeValidation::register() )) {
			return $this->response->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => $this->validation->getErrors()
			] );
		}
		$data_post = $_POST;
		if (!$data_post ['complemento']) {
			$data_post ['complemento'] = '';
		}
		if (!$data_post ['referencias']) {
			$data_post ['referencias'] = '';
		}
		$unidade_service_response = (new UnidadeService())->registerUnidade( $data_post );
		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'A unidade foi cadastrada com sucesso.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $unidade_service_response, $response_messages );

	}

	public function getUnidadeList(): Response {

		$pagination = $this->getPaginationFromRequest();
		if ($_GET ['sort'] === null) {
			$_GET ['sort'] = "nome_fantasia";
		}
		$query_filter_collection = new QueryFilterCollection( $_GET, QueryFilterTranslator::unidade() );
		$query_order_collection = new QueryOrderCollection( $_GET, QueryOrderTranslator::unidade() );
		$unidade_service_response = (new UnidadeService())->getUnidadeList( $pagination, $query_filter_collection, $query_order_collection );
		$response_messages = [ 
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados dos unidade foram encontrados com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_PARTIAL_CONTENT,
				'message' => 'Nenhum registro foi encontrado.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			],
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $unidade_service_response, $response_messages );

	}

	public function updateUnidadeData(int $id_unidade, int $id_pessoa_juridica): Response {

		if (!$this->validate( UnidadeValidation::update( $id_unidade ) )) {
			return $this->response->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => $this->validation->getErrors()
			] );
		}
		$unidade_dao = new UnidadeDAO();
		$validation = $unidade_dao->getUnidadeFromId( $id_unidade );
		if ($validation == null) {
			return $this->response->setJSON( [ 
				'message' => 'A unidade não está registrada.',
				'errors' => $this->validation->getErrors()
			] );
		}
		$unidade_service_response = (new UnidadeService())->updateUnidadeData( $id_unidade, $id_pessoa_juridica, $_POST );
		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados do unidade foram atualizados com sucesso.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $unidade_service_response, $response_messages );

	}

	public function getDadosUnidade(int $id_unidade): Response {

		$unidade_service_response = (new UnidadeService())->getDadosUnidadeById( $id_unidade );
		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados do unidade foram atualizados com sucesso.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro interno do servidor.'
			]
		];
		return $this->getResponse( $unidade_service_response, $response_messages );

	}

	// lista todas as unidades fisicas e seus estados
	public function getListUnidadeFisicasAllUF(): Response {

		$unidade_service = new UnidadeService();
		$unidade_service_response = $unidade_service->getListUnidadeFisicasAllUF();

		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'A consulta foi realizada com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_NO_CONTENT,
				'message' => 'Nenhum Dado foi encontrado.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			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.'
			]
		];

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

	}

	public function getListUFWithUnidadeFisica(): Response {

		$service = new UnidadeService();
		$service_response = $service->getListUFWithUnidadesFisicas();

		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'A consulta foi realizada com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_NO_CONTENT,
				'message' => 'Nenhum Dado foi encontrado.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			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.'
			]
		];

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

	}

	public function getListUnidadeFisicaByUF(int $uf): Response {

		$service = new UnidadeService();
		$service_response = $service->getListUnidadeFisicaByUF( $uf );

		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'A consulta foi realizada com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_NO_CONTENT,
				'message' => 'Nenhum Dado foi encontrado.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			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.'
			]
		];

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

	}

	public function registerUnidadeUF(): Response {

		$request = $this->getDataPost();

		if (count( UnidadeUFValidation::register( $request ) ) > 0) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => UnidadeUFValidation::register( $request )
			] );
		}

		$service = new UnidadeService();
		$service_response = $service->registerUnidadeUF( $request );

		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados foram incluídos com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_NO_CONTENT,
				'message' => 'Nenhum Dado foi encontrado.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			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.'
			]
		];

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

	}

	public function updateUnidadeUF(): Response {

		$request = $this->getDataPost();

		if (count( UnidadeUFValidation::update( $request ) ) > 0) {
			return $this->response->setStatusCode( 400 )
				->setJSON( [ 
				'message' => 'Informe os dados corretamente.',
				'errors' => UnidadeUFValidation::update( $request )
			] );
		}

		$service = new UnidadeService();
		$service_response = $service->upateUnidadeUF( $request );

		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados foral alterados com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_NO_CONTENT,
				'message' => 'Nenhum Dado foi encontrado.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			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.'
			]
		];

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

	}

	public function getListUF(): Response {

		$service = new UnidadeService();
		$service_response = $service->getListUF();

		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados foral alterados com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_NO_CONTENT,
				'message' => 'Nenhum Dado foi encontrado.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			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.'
			]
		];

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

	}

	public function getListUnidadesAllUF(): Response {

		$pagination = $this->getPaginationFromRequest();

		if (is_null( $pagination )) {
			$pagination = Pagination::builder()->setCurrentPage( 1 )
				->setPerPage( 15 )
				->build();
		}

		$service = new UnidadeService();
		$service_response = $service->getListUnidadesAllUF( $pagination );

		$response_messages = [ 
			ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [ 
				'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
				'message' => 'Erro de conexão com o banco de dados.'
			],
			ServiceResponseInterface::SUCESS => [ 
				'code' => ResponseInterface::HTTP_OK,
				'message' => 'Os dados foral alterados com sucesso.'
			],
			ServiceResponseInterface::RECORD_NOT_FOUND => [ 
				'code' => ResponseInterface::HTTP_NO_CONTENT,
				'message' => 'Nenhum Dado foi encontrado.'
			],
			ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [ 
				'code' => ResponseInterface::HTTP_BAD_REQUEST,
				'message' => 'Informe os dados corretamente.'
			],
			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.'
			]
		];

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

	}
	
	public function changeStatusByUnidadeId(int $id_unidade): Response {
		
		$dados = $this->getDataPost();
		
		if (!intval( $dados ['ativo'] )) {
			return $this->response->setStatusCode( 400 )
			->setJSON( [
					'message' => 'Informe os dados corretamente.',
					'errors' => ''
			] );
		}
		$service = new UnidadeService();
		$service_response = $service->changeStatusByUnidadeId($id_unidade, intval( $dados ['ativo'] ));
		
		$response_messages = [
				ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [
						'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
						'message' => 'Erro de conexão com o banco de dados.'
				],
				ServiceResponseInterface::SUCESS => [
						'code' => ResponseInterface::HTTP_OK,
						'message' => 'Os dados foram alterados com sucesso.'
				],
				ServiceResponseInterface::RECORD_NOT_FOUND => [
						'code' => ResponseInterface::HTTP_NO_CONTENT,
						'message' => 'Nenhum Dado foi encontrado.'
				],
				ServiceResponseInterface::VALIDATION_PARAMS_ERROR => [
						'code' => ResponseInterface::HTTP_BAD_REQUEST,
						'message' => 'Informe os dados corretamente.'
				],
				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.'
				]
		];
		
		return $this->getResponse( $service_response, $response_messages );
		
	}
	
	public function getUnidadesAtivasList(): Response {
		
		$pagination = $this->getPaginationFromRequest();
		if ($_GET ['sort'] === null) {
			$_GET ['sort'] = "nome_fantasia";
		}
		$query_filter_collection = new QueryFilterCollection( $_GET, QueryFilterTranslator::unidade() );
		$query_order_collection = new QueryOrderCollection( $_GET, QueryOrderTranslator::unidade() );
		$unidade_service_response = (new UnidadeService())->getUnidadesAtivasList( $pagination, $query_filter_collection, $query_order_collection );
		$response_messages = [
				ServiceResponseInterface::SUCESS => [
						'code' => ResponseInterface::HTTP_OK,
						'message' => 'Os dados dos unidade foram encontrados com sucesso.'
				],
				ServiceResponseInterface::RECORD_NOT_FOUND => [
						'code' => ResponseInterface::HTTP_PARTIAL_CONTENT,
						'message' => 'Nenhum registro foi encontrado.'
				],
				ServiceResponseInterface::SERVICE_INTERNAL_ERROR => [
						'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
						'message' => 'Erro interno do servidor.'
				],
				ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [
						'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
						'message' => 'Erro interno do servidor.'
				]
		];
		return $this->getResponse( $unidade_service_response, $response_messages );
		
	}

}
