<?php

abstract class Agro_Db_Table_Abstract extends Zend_Db_Table_Abstract {
	protected $_insertDefaultValues = true;
	public $executeJsAfterDelete;
	public $executeJsValueAfterDelete;
	protected $profiler = '';
	protected $_schema = '';
	protected $_name = '';
	protected $_log = false;
	protected $_view = '';
	protected $_primary = '';
	protected $limit = '';
	protected $offset = '';
	protected $_pairs = array();
	private $_msg = array();
	public $_order = '';
	public $_request = false;
	public $_user = null;
    protected bool $salvarUsuarioDataAlteracao = true;

	public function init() {

	    //Em conjunto com a extensao firephp do Firefox,
     	//todos SQL utilizados são listados no firebug
     	//para habilitar basta setar a constante ENABLE_SQL_DEBUG
     	//para true no seu ambiente no arquivo application.ini
	    if (ENABLE_SQL_DEBUG) {
            $profiler = new Zend_Db_Profiler_Firebug('All DB Queries');
            $profiler->setEnabled(true);
            $this->getDefaultAdapter()->setProfiler($profiler);
		}

		$this->_request = Zend_Controller_Front::getInstance()->getRequest()->getParams();
		$this->_user = Zend_Auth::getInstance()->getIdentity();
	}

	/**
	 * @method 	getMetadata
	 * @desc 	Busca os matedados da tabela
	 * @author 	Renato Dehnhardt <renato@fullsystem.com.br>
	 * @since 	12/10/2011
	 */
	public function getMetadata() {
		if (!$this->_metadata) {
			$this->_setupMetadata();
		}

		return $this->_metadata;
    }

	public function getRow($id='') {
		$Row = false;

		if ($id) {
			$Row = $this->find(trim($id))->current();
		}

		if (!$Row) {
			$Row = $this->createRow();
		}

		return $Row;
	}

	public function getCombo($first=true,$field=null) {
		$Rs = $this->fetchAll('fl_ativo = true', $this->_order)->toArray();

		$options = array();
		if (is_array($Rs)) {
			if ($first) {
				$options[''] = '';
			}

			$field = $field ? $field : $this->_order;
			foreach ($Rs as $row) {
				$options[$row['id']] = $row[$field];
			}

			return $options;
		} else {
			return false;
		}
	}

	public function getComboStatus($tipo, array $cdStatus = []) {
		$Select = $this->select()->setIntegrityCheck(false);
		$Select->from(array('s' => 'sistema.status'), array('id', 'ds_status'));
		$Select->join(array('t' => 'sistema.tipo_status'), 's.id_tipo_status = t.id', false);
		$Select->where('t.ds_chave = ?', $tipo);
		$Select->where('s.fl_ativo is true');
		$Select->where('s.fl_del is false');

        if (!empty($cdStatus)) {
            $Select->where('s.cd_status in (' . implode(', ', $cdStatus) . ')');
        }

		$Select->order('ds_status');

		return $this->getDefaultAdapter()->fetchPairs($Select);
	}

	public function getData($where=false) {
		$select = $this->select();

		if ($this->_view) {
			$select->setIntegrityCheck(false);
			$select->from("{$this->_schema}.{$this->_view}");
		}

		if ($this->_order) {
			$select->order($this->_order);
		}

		$this->getWhere($select, $where);

		return $select;
	}

	public function fetchAllPaginator($where, $pageNumber=false, $itemCountPerPage = 10, $paginator='') {
        if ($paginator) {
			return $this->getPaginator($this->getData($where), $pageNumber, $itemCountPerPage, $paginator);
        } else {
            return $this->getPaginator($this->getData($where), 1, null, false);
        }
    }

    public function getPaginator($Select, $pageNumber=0, $itemCountPerPage=10, $paginator='') {
    	Zend_View_Helper_PaginationControl::setDefaultViewPartial('paginator.phtml');
        $Paginator = Zend_Paginator::factory($Select);
        $Paginator->setItemCountPerPage($itemCountPerPage);
        $Paginator->setCurrentPageNumber($pageNumber);
        $Paginator->setPageRange(20);

        return $Paginator;
    }

	public function delete($id, $field='id') {
		$this->beforeDelete($id, $field);

		if (!$field && !is_array($this->_primary)) { $field = $this->_primary; }
		if (!is_array($id)) { $id = array($id); }
		$id = implode(',', $id);

		$this->afterDelete($id, $field);

		return parent::delete("$field in ($id)");
	}

	public function getViewId($id) {
		if ($id) {
			$select = $this->select();
			$select->setIntegrityCheck(false);
			$select->from("{$this->_schema}.{$this->_view}");
			$select->where("id = ?", $id);

			return $this->fetchRow($select);
		}
	}

	public function insert(array $data) {
		if (!$data['dt_criacao']) {
			$data['dt_criacao'] = date('Y-m-d H:i:s');
		}

		if (empty($data['id_usuario_criacao'])) {
			$data['id_usuario_criacao'] = Zend_Auth::getInstance()->getIdentity()->id;
		}

		if (!$data['id_usuario_criacao']) {
			throw new Exception('Usuário de criação ausente.');
		}

		$insert = parent::insert($data);

		return $insert;
	}

	public function update(array $data, $where) {
		if ($this->salvarUsuarioDataAlteracao) {
			$data['id_usuario_alteracao'] = Zend_Auth::getInstance()->getIdentity()->id;
			$data['dt_alteracao'] = date('Y-m-d H:i:s');
		}

		if ((array_key_exists('id_usuario_criacao', $data) && !$data['id_usuario_criacao']) && (array_key_exists('id_usuario_alteracao', $data) && !$data['id_usuario_alteracao'])) {
			throw new Exception('Usuário de criação ausente.');
		}

		$update = parent::update($data, $where);

		return $update;
	}

	public function getNextSequence($schema='', $name='') {
		if (empty($schema)) {
			$schema = $this->_schema;
		}

		if (empty($name)) {
			$name = $this->_name."_id_seq";
		}

		return $this->getAdapter()->nextSequenceId("$schema.$name");
	}

	public function fetchPairs($id='', $label='', $parentField=false, $parentValue=false, $count=1, $where=false, $first=true, $order='ASC') {
		if (empty($id)) {
			$id = $this->_pairs['key'];
		}

		if (empty($label)) {
			$label = $this->_pairs['field'];
		}

		if ($first) {
			$this->pairs[0] = '';
		}
		$select = $this->select();
   		$select->where('fl_ativo = true');

		if ($parentField && $parentValue !== false) {
			$select->where("$parentField = ?", $parentValue);
		} elseif ($parentField && !$parentValue) {
	   		$User = Zend_Auth::getInstance()->getIdentity();
	   		//gambi para filtrar o perfil de adm quando não for adm editando os funcionários
	   		if($User->id_role != 12){
				if($User->id_role == 16){
					$select->where("ds_chave ilike 'VISTORIADOR'");
				}else{
	   				$select->where("ds_chave ilike 'ADMIN'");
				}
			}else{
				$select->where("$parentField is null", false);
			}
		}

		if ($where) {
			$select->where($where, '');
		}

		$select->order($label.' '.$order);
		$Rs = $this->fetchAll($select);
		if ($Rs) {
			foreach ($Rs as $row) {
				if($row[$label] != '') {
					$this->pairs[$row[$id]] = ($count > 1 ? str_repeat('. ', $count) : '').$row[$label];

					if ($parentField) {
						$this->fetchPairs($id, $label, $parentField, $row[$id], ($count*2) , false, false);
					}
				}
			}
		}

		return $this->pairs;
	}

	public function getMessages() {
		if (count($this->_msg) == 1) {
			return $this->_msg[0];
		} elseif (count($this->_msg) > 1) {
			$html  = "<ul>";

			foreach ($this->_msg as $msg) {
				$html .= "<li>$msg</li>";
			}

			$html .= "</ul>";

			return $html;
		}
	}

	public function setMessage($msg) {
		$this->_msg[] = $msg;
	}

	public function beforeDelete($params, $field='') { return true; }
	public function afterDelete($params, $field='') { return true; }

	public function getIdStatus($chave, $tipo = null) {
		$Select = $this->select()->setIntegrityCheck(false);
		$Select->from(array('s' => 'sistema.status'), 'id');
		$Select->join(array('ts' => 'sistema.tipo_status'), 'ts.id = s.id_tipo_status', null);
		$Select->where('upper(s.ds_chave) = ?', strtoupper($chave));

		if ($tipo) {
			$Select->where('upper(ts.ds_chave) = ?', strtoupper($tipo));
		}
		
		return $this->getAdapter()->fetchOne($Select);
	}

	public function getWhere(&$Select, $where) {
		if (is_array($where)) {
            foreach ($where as $clause) {
                if (is_array($clause)) {
                    $field = $clause['field'];
                    $operator = $clause['operator'];
                    $value = $clause['value'];

                    if ($operator == 'in') {
                    	$Select->where("$field $operator $value");
                    } else {
	                    if (strpos($field, 'fl_ativo')) {
	                   		$Select->where("$field is $value");
	                    } elseif (is_numeric($value)) {
	                        $Select->where("$field $operator ?", $value);
	                    } else {
	                    	if ($field != 'fl_ativo' && $field != 'fl_ressegurador' && strpos($field, 'fl_') === false) {
		                        $Select->where("normalize($field) $operator normalize(?)", $value);
	                    	} else {
	                    		$Select->where("$field $operator ?", $value);
	                    	}
	                    }
                    }
                } else {
                    $Select->where($clause, '');
                }
            }
        } elseif ($where != '') {
            $Select->where($where);
        }
	}


	public function quoteInto($text, $value){
		if (!is_array($value)) {
			$value = array($value);
		}
		$qmpos = 0;
		foreach ( $value as $replacement ){
			// pega sempre a ? mais da esquerda
			$qmpos = strpos($text, '?', $qmpos);
			if ( $qmpos === false ) break;
			// substitui o ? pelo valor
			$text = substr_replace($text, $replacement, $qmpos, 1);
		}
		return $text;
	}

    public function setSalvarUsuarioDataAlteracao(bool $salvarUsuarioDataAlteracao): void
    {
        $this->salvarUsuarioDataAlteracao = $salvarUsuarioDataAlteracao;
    }
}
