<?php

namespace App\DAO;

use App\DAO\DAO;
use App\DAO\DAOResponse\DAOResponse;
use App\DAO\DAOResponse\DAOResponseInterface;
use App\DAO\Pagination\Pagination;
use App\Services\JWT\UsuarioLogado;
use App\Utils\Collections\QueryFilterCollection;
use App\Utils\Collections\QueryOrderCollection;
use App\ViewModels\Extorno\ExtornoRegistrationViewModel\ExtornoRegistrationViewModel;
use App\Entities\Extorno\Extorno;
use App\Mappers\ExtornoMapper;
use App\Models\ExtornoModel;
use Exception;
use App\Services\RequisicaoService;

class ExtornoDAO extends DAO {

	public function persistExtornoRegistrationVM(ExtornoRegistrationViewModel $extorno_registration_vm, $data_request): DAOResponse {

		$dao_response = new DAOResponse();
		try {
			$this->db->transStart();
			$req_service = new RequisicaoService();
			$extorno = $this->persistExtornoFromExtornoRegistrationVM( $extorno_registration_vm );
			$error = $this->db->error();
			if ($error && $error ['code']) {
				$this->setDatabaseErrorsForExtornoRegistration( $dao_response, $error );
			} else {
                // salva o itens do estorno na tabela extorno_iten

                foreach ($data_request->itens as $item) {
                    $extorno_item = $this->persistExtornoItem($item, $extorno->getId());
                    if($extorno_item->getStatus() == DAOResponseInterface::SUCESS) {
                    	$req_response = $req_service->setItemExtornadoToExcluirRequisicao($item);
                    }
                }

                if($extorno_item->getStatus() == DAOResponseInterface::SUCESS) {
                    $dao_response->setStatus( DAOResponseInterface::SUCESS );
                    $dao_response->setData( $extorno );                    
                    $this->db->transComplete();
                } else {
                    $dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
				    $dao_response->setData( $extorno );
//                    $this->db->transComplete();
                }

			}
		} catch ( Exception $exception ) {
			$this->setDatabaseErrorsForExtornoRegistration( $dao_response, $this->db->error() );
		}

		return $dao_response;

	}

    private function persistExtornoItem($extorno_item, $extorno_id){
        try {
            $dao_response = new DAOResponse();

            $usuario_logado = UsuarioLogado::getUsuarioId();
            $sql_insert = '
            insert into extorno_item (extorno_id, comanda_item_id, valor, criado_por, data_criacao, hora_criacao)
            values (:extorno_id:, :comanda_item_id:, :valor:, :criado_por:, :data_criacao:, :hora_criacao:)
            ';
            $conn = db_connect();
            $binds_insert = [
                "extorno_id" => $extorno_id,
                "comanda_item_id" => $extorno_item->comanda_item_id,
                "valor" => $extorno_item->valor,
                "criado_por" => $usuario_logado,
                "data_criacao" => date('Y-m-d'),
                "hora_criacao" => date('H:i:s'),
            ];
            $query = $conn->query($sql_insert, $binds_insert);
            $errors_insert = $conn->error();
            $extorno_item_id = $conn->insertID();

            $sql_update = '
                update
                    comanda_item
                set
                    comanda_item_status_id = 4
                    ,atualizado_por = :atualizado_por:
                    ,data_atualizacao = :data_atualizacao:
                    ,hora_atualizacao = :hora_atualizacao:
                where
                    id = :comanda_item_id:
            ';

            $binds_update = [
                "comanda_item_id" => $extorno_item->comanda_item_id,
                "atualizado_por" => $usuario_logado,
                "data_atualizacao" => date('Y-m-d'),
                "hora_atualizacao" => date('H:i:s'),
            ];

            $query = $conn->query($sql_update, $binds_update);
            $errors_update = $conn->error();
            $extorno_item_id = $conn->insertID();


            if ($errors_update && $errors_update ['code']) {
                $dao_response = $this->setDatabaseErrorsForExtornoItemRegistration( $dao_response, $errors_update );
                return $dao_response;
            }

            $dao_response->setStatus(DAOResponseInterface::SUCESS);
            return $dao_response;
        } catch(Exception $e) {
            $exception = $e->getMessage();
        }
    }

	public function getExtornosByComanda(int $comanda_id): DAOResponse {

		$sql = <<<SQL
			select
				e.id ,e.id_comanda, c.id_unidade , un.descricao as nome_unidade,
				e.id_tipo_extorno,te.descricao as tipo_estorno,	e.valor,
				e.criado_por, pf.nome,
				e.data_criacao, e.hora_criacao, e.observacao
			from
				extorno e , tipo_extorno te , usuario u , pessoa_fisica pf, comanda c, unidade un
			where
				e.id_comanda = :comandaid:
				and e.id_comanda = c.id
				and c.id_unidade = un.id
				and e.id_tipo_extorno  = te.id
				and e.criado_por = u.id
				and u.id_pessoa = pf.id_pessoa 
		SQL;
		$binds = [ 
				'comandaid' => $comanda_id
		];
		return $this->getDAOResponseFromPaginatedSelect( $binds, null, null, null, $sql,
				function (array $result_array) {
					return ExtornoMapper::getExtornoDetailsVMListFromArray( $result_array );
				} );

	}

	private function persistExtornoFromExtornoRegistrationVM(ExtornoRegistrationViewModel &$extorno_registration_vm): Extorno {

		$extorno_model = new ExtornoModel();
		$extorno = ExtornoMapper::getExtornoFromExtornoRegistrationVM( $extorno_registration_vm );
		$extorno_model->registerExtorno( $extorno );
		if (!$extorno->getId()) {
			throw new Exception( 'O cadastro do extorno não teve êxito' );
		}
		return $extorno;

	}

	private function setDatabaseErrorsForExtornoRegistration(DAOResponse $dao_response, array $error): void {

		if ($error ['code']) {
			$dao_response->setStatus( $error ['code'] );
			$dao_response->setErrors( $this->getDatabaseResponseErrorsForPersistence( $error ) );
		} else {
			$dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
		}
		log_message( 'error', json_encode( $error ) );

	}

    private function setDatabaseErrorsForExtornoItemRegistration(DAOResponse $dao_response, array $error) {
        if ($error ['code']) {
            $dao_response->setStatus( $error ['code'] );
            $dao_response->setErrors( $error );
            return $dao_response;
        } else {
            $dao_response->setStatus( DAOResponseInterface::DATABASE_CONNECTION_ERROR );
        }
        log_message( 'error', json_encode( $error ) );
    }

}

