<?php

namespace App\Models;

use App\Entities\CEP\CEP;
use App\Entities\Endereco\Endereco;
use App\Entities\Pessoa\Pessoa;
use App\ViewModels\Paciente\PacienteUpdateViewModel\PacienteUpdateViewModel;
use CodeIgniter\Model;
use App\Models\CEPModel;

class EnderecoModel extends ModelEntity {
	protected $table = 'endereco';
	protected $primaryKey = 'id';
	protected $returnType = 'array';
	protected $allowedFields = [ 
		'cep',
		'numero',
		'complemento',
		'referencias'
	];
	protected $useSoftDeletes = false;
	protected $useTimestamps = false;
	protected $skipValidation = true;

	public function registerEndereco(Endereco &$endereco): void {

		$endereco_data = $endereco->toArray();
		unset( $endereco_data ['id'] );
		$id_new_endereco = $this->insert( $endereco_data );
		$endereco->setId( $id_new_endereco );

	}

	public function getEnderecoByUsuarioId($usuario_id) {

		$sql = "
                SELECT endereco.* FROM endereco, pessoa, usuario WHERE
                endereco.id = pessoa.id_endereco AND
                usuario.id_pessoa = pessoa.id AND
                usuario.id = :usuario_id:
          ";

		$binds = [ 
			"usuario_id" => $usuario_id
		];
		$query = $this->db->query( $sql, $binds );
		$result_array = $query->getResultArray();

		return $result_array;

	}

	public function updateEnderecoByPacienteID(int $id_paciente, Endereco $endereco): bool {

		$data = $endereco->toArray( true );
		if (count( $data ) > 0) {
			$binds = [ 
				'id_paciente' => $id_paciente
			];
			$sql = "
                UPDATE endereco
                INNER JOIN pessoa ON endereco.id = pessoa.id_endereco
                INNER JOIN paciente ON paciente.id_pessoa = pessoa.id
            ";
			$sql .= $this->generateUpdateSets( $data, $binds );
			$sql .= 'WHERE paciente.id = :id_paciente:';
			$query = $this->db->query( $sql, $binds );
			$errors = $this->errors();
			return !$errors;
		} else {
			return true;
		}

	}

	public function updateEnderecoByAssistenteID(int $id_assistente, Endereco $endereco): bool {

		$data = $endereco->toArray( true );
		if (count( $data ) > 0) {
			$binds = [ 
				'id_assistente' => $id_assistente
			];
			$sql = "
                UPDATE endereco
                INNER JOIN pessoa ON endereco.id = pessoa.id_endereco
                INNER JOIN profissional ON pessoa.id = profissional.id_pessoa
                INNER JOIN assistente ON profissional.id = assistente.id_profissional
            ";
			$sql .= $this->generateUpdateSets( $data, $binds );
			$sql .= 'WHERE assistente.id = :id_assistente:';
			$query = $this->db->query( $sql, $binds );
			$errors = $this->errors();
			return !$errors;
		} else {
			return true;
		}

	}

	public function updateEnderecoByAdministrativoID(int $id_administrativo, Endereco $endereco): bool {

		$data = $endereco->toArray( true );
		if (count( $data ) > 0) {
			$binds = [ 
				'id_administrativo' => $id_administrativo
			];
			$sql = "
                UPDATE endereco
                INNER JOIN pessoa ON endereco.id = pessoa.id_endereco
                INNER JOIN profissional ON pessoa.id = profissional.id_pessoa
                INNER JOIN administrativo ON profissional.id = administrativo.id_profissional
            ";
			$sql .= $this->generateUpdateSets( $data, $binds );
			$sql .= 'WHERE administrativo.id = :id_administrativo:';
			$query = $this->db->query( $sql, $binds );
			$errors = $this->errors();
			return !$errors;
		} else {
			return true;
		}

	}

	public function updateEnderecoByMedicoID(int $id_medico, Endereco $endereco): bool {

		$data = $endereco->toArray( true );
		if (count( $data ) > 0) {
			$binds = [ 
				'id_medico' => $id_medico
			];
			$sql = "
                UPDATE endereco
                INNER JOIN pessoa ON endereco.id = pessoa.id_endereco
                INNER JOIN profissional ON pessoa.id = profissional.id_pessoa
                INNER JOIN medico ON profissional.id = medico.id_profissional
            ";
			$sql .= $this->generateUpdateSets( $data, $binds );
			$sql .= 'WHERE medico.id = :id_medico:';
			$query = $this->db->query( $sql, $binds );
			$errors = $this->errors();
			return !$errors;
		} else {
			return true;
		}

	}

	public function updateEnderecoByUnidadeID(int $id_unidade, Endereco $endereco): bool {

		$data = $endereco->toArray( true );
		if (count( $data ) > 0) {
			$binds = [ 
				'id_unidade' => $id_unidade
			];
			$sql = "
                UPDATE endereco
                INNER JOIN pessoa ON endereco.id = pessoa.id_endereco
                INNER JOIN pessoa_juridica ON pessoa.id = pessoa_juridica.id_pessoa
            ";
			$sql .= $this->generateUpdateSets( $data, $binds );
			$sql .= 'WHERE pessoa_juridica.id = :id_unidade:';
			$query = $this->db->query( $sql, $binds );
			$errors = $this->errors();
			return !$errors;
		} else {
			return true;
		}

	}

	public function updateEnderecoByUsuarioID(int $id_usuario, Endereco $endereco): bool {

		$data = $endereco->toArray( true );
		$sucess = true;
		$enderecoAtual = $this->getEnderecoByUsuarioId( $id_usuario );

		if (count( $data ) > 0) {
			$cep = (new CEPModel())->getCep( $_POST ["cep"] );
			if (!$cep) {
				$cep = new CEP();
				$cep->setCep( $_POST ['cep'] ?? "");
				$cep->setEstado( $_POST ['estado'] ?? "");
				$cep->setCidade( $_POST ['cidade'] ?? "");
				$cep->setLogradouro( $_POST ['logradouro'] ?? "");
				$cep->setBairro( $_POST ['bairro'] ?? "");

				$cepInsert = (new CEPModel())->registerCep( $cep );
			}
			$bindsCep = [ 
				'id_usuario' => $id_usuario,
				'cep_id' => $cep->getId()
			];

			if ($_POST ["cep"]) {
				$enderecoAtual ['cep'] = $cep->getId();
				# $endereco ['cep'] = $cep->getId();
				$enderecoNovo = new Endereco();

				$enderecoAtual = $enderecoAtual [0];
				$enderecoNovo->setCep( $enderecoAtual ['cep'] );
				$enderecoNovo->setNumero( $data ['numero'] );
				if (isset( $data ['complemento'] )) {
					$enderecoNovo->setComplemento( $data ['complemento'] );
				} else {
					$enderecoNovo->setComplemento( '' );
				}
				if (isset( $data ['referencias'] )) {
					$enderecoNovo->setReferencias( $data ['referencias'] );
				} else {
					$enderecoNovo->setReferencias( '' );
				}

				$this->registerEndereco( $enderecoNovo );

				$sqlCep = <<<SQL
					UPDATE pessoa
					INNER JOIN usuario ON usuario.id_pessoa = pessoa.id
					SET pessoa.id_endereco = :id_endereco:
					WHERE usuario.id = :id_usuario:
				SQL;
				$bindsCep = [ 
					"id_usuario" => $id_usuario,
					"id_endereco" => $enderecoNovo->getId()
				];

				$query = $this->db->query( $sqlCep, $bindsCep );
			} else {
				$binds = [ 
					'id_usuario' => $id_usuario
				];
				$sql = <<<SQL
				    UPDATE endereco
				    INNER JOIN pessoa ON endereco.id = pessoa.id_endereco
				    INNER JOIN usuario ON usuario.id_pessoa = pessoa.id
				SQL;
				$sql .= $this->generateUpdateSets( $data, $binds );
				$sql .= 'WHERE usuario.id = :id_usuario:';
				$query = $this->db->query( $sql, $binds );
			}

			$errors = $this->errors();
			$sucess = !$errors;
		}

		return $sucess;

	}

}
