<?php

namespace App\Controllers;

use App\DAO\Filter\QueryFilter;
use App\DAO\Filter\QueryFilterTranslator;
use App\DAO\Order\QueryOrderTranslator;
use App\DAO\CentroCustoDAO;
use App\Services\CentroCustoService;
use App\Services\ServiceResponse\ServiceResponseInterface;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\Validations\CentroCustoValidation;
use CodeIgniter\HTTP\Response;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Model;

class CentroCustoController extends BaseController {

	public function registerCentroCusto(): Response {

		if (! $this->validate( CentroCustoValidation::register() )) {
			return $this->response->setJSON( [
					'message' => 'Informe os dados corretamente.',
					'errors' => $this->validation->getErrors() ] );
		}
		$data_post = $_POST;
		$centro_custo_service_response = (new CentroCustoService())->registerCentroCusto( $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' => 'O centro de custo foi cadastrado 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( $centro_custo_service_response, $response_messages );

	}

	public function getCentroCustoList(): Response {

		$pagination = $this->getPaginationFromRequest();

		if ($_GET ['sort'] === null) {
			$_GET ['sort'] = "descricao";
		}

		$query_filter_collection = new QueryFilterCollection( $_GET, QueryFilterTranslator::centro_custo() );
		$query_order_collection = new QueryOrderCollection( $_GET, QueryOrderTranslator::centro_custo() );
		$centro_custo_service_response = (new CentroCustoService())->getCentroCustoList( $pagination, $query_filter_collection, $query_order_collection );
		$response_messages = [
				ServiceResponseInterface::SUCESS => [
						'code' => ResponseInterface::HTTP_OK,
						'message' => 'Os dados dos centros de custos 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( $centro_custo_service_response, $response_messages );

	}

	public function searchCentroCustoByID(int $id_centro_custo): Response {
        $query_filter = QueryFilter::builder()
            ->setTable('centro_custo')
            ->setNameParam('id')
            ->setValue($id_centro_custo)
            ->setIsExact(true)
            ->build();

		$centro_custo_service_response = (new CentroCustoService())->getCentroCusto( $query_filter );
		$response_messages = [
				ServiceResponseInterface::SUCESS => [
						'code' => ResponseInterface::HTTP_OK,
						'message' => 'Os dados do centro de custo 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( $centro_custo_service_response, $response_messages );
	}

	public function updateCentroCusto(int $id_centro_custo): Response {

		if (! $this->validate( CentroCustoValidation::update() )) {
			return $this->response->setJSON( [
					'message' => 'Informe os dados corretamente.',
					'errors' => $this->validation->getErrors() ] );
		}

		$centro_custo_dao = new CentroCustoDAO();
		$validation = $centro_custo_dao->getCentroCustoFromId( $id_centro_custo );

		if ($validation == null) {
			return $this->response->setJSON( [
					'message' => 'O centro de custo não está registrado.',
					'errors' => $this->validation->getErrors() ] );
		}

		$centro_custo_service_response = (new CentroCustoService())->updateCentroCustoData( $id_centro_custo, $_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 centro de custo 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( $centro_custo_service_response, $response_messages );
	}

    public function deleteCentroCusto(int $id_erro) {
        $erro_service_response = (new CentroCustoService())->deleteCentroCusto($id_erro);
        $response_messages = [
            ServiceResponseInterface::SUCESS => [
                'code' => ResponseInterface::HTTP_OK,
                'message' => 'A exclusão foi efetuda com sucesso.'
            ],
            ServiceResponseInterface::RECORD_NOT_FOUND => [
                'code' => ResponseInterface::HTTP_PARTIAL_CONTENT,
                'message' => 'Nenhum registro foi encontrado.'
            ],
            ServiceResponseInterface::RECORD_IS_LINKED => [
                'code' => ResponseInterface::HTTP_BAD_REQUEST,
                'message' => 'Esse exame está vinculado a outros cadastros do sistema. Portanto, não pode ser excluído.'
            ],
            ServiceResponseInterface::DATABASE_CONNECTION_ERROR => [
                'code' => ResponseInterface::HTTP_INTERNAL_SERVER_ERROR,
                'message' => 'Erro interno do servidor.'
            ],
        ];
        return $this->getResponse($erro_service_response, $response_messages);
    }
}
