<?php

class Sistema_Model_Acoes extends Agro_Db_Table_Abstract
{
    const TIPO_RELATORIO = 'R';

	protected $_schema = 'sistema';
	protected $_primary = 'id';
	protected $_name = 'acao';
	public $_paginator = false;
	public $_order = 'nr_ordem';
	
	public function save(array $data) {
		try {
			$Row = $this->getRow($data['id']);

			$Row->ds_label = $data['ds_label'];
			$Row->ds_module = $data['ds_module'];
			$Row->ds_controller = ($data['ds_controller'] ? $data['ds_controller'] : null);
			$Row->id_parent = ($data['id_parent'] ? $data['id_parent'] : null);
			$Row->ds_action = ($data['ds_action'] ? $data['ds_action'] : null);
			$Row->ds_image = ($data['ds_image'] ? $data['ds_image'] : null);
			$Row->ds_param = ($data['ds_param'] ? $data['ds_param'] : null);
			$Row->fl_tipo = ($data['fl_tipo'] ? $data['fl_tipo'] : null);;
			$Row->ds_descricao = ($data['ds_descricao'] ? $data['ds_descricao'] : null);;

			if ($Row->save()) {
				if ($data['defaultActions'] && $Row->ds_controller && $Row->ds_action == 'index') {
					$defaultActions = array(
						0 => array(
							'image' => 'edit.png',
							'label' => 'Editar',
							'action' => 'form',
							'param' => 'id'
						),
						1 => array(
							'image' => 'active.png',
							'label' => 'Ativar/Desativar',
							'action' => 'active',
							'param' => 'id'
						),
						2 => array(
							'image' => 'delete.png',
							'label' => 'Deletar',
							'action' => 'delete',
							'param' => 'id'
						)
					);

					foreach ($defaultActions as $ordem => $icon) {
						$Action = $this->fetchRow("ds_action = '{$icon['action']}' and id_parent = {$Row->id}");
						if (!$Action) {
							$Action = $this->createRow();
						}

						$Action->id_parent = $Row->id;
						$Action->ds_label = $icon['label'];
						$Action->ds_module = $Row->ds_module;
						$Action->ds_controller = $Row->ds_controller;
						$Action->ds_action = $icon['action'];
						$Action->ds_image = $icon['image'];
						$Action->ds_param = $icon['param'];
						$Action->nr_ordem = $ordem;
						$Action->fl_tipo = 'L';

						$Action->save();
					}
				}
			}

			return true;
		} catch (Exception $e) {
			die($e);
		}
	}

	public function getMenus($idMenu) {
		$select = $this->select();
		$select->from(array('a'=>'sistema.acao'), array('ds_label', 'ds_module', 'ds_controller', 'ds_action', 'ds_descricao', 'ds_nome', 'id', 'ds_param', 'id_parent'));
		$select->where('id_parent '.($idMenu ? "=$idMenu" : "is null") );
		$select->where('fl_tipo = ?', 'M');
		$select->where('fl_ativo = true');
		$select->order('nr_ordem');

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

	public function checkMenuParent($idMenu) {
		$select = $this->select();
		$select->from(array('a'=>'sistema.acao'));

		if ($idMenu) {
			$select->where('id_parent = ?', $idMenu);
		}

		return $this->fetchAll($select)->count();
	}

	public function getActions($module, $controller) {
		$Row = $this->fetchRow("ds_module = '$module' and ds_controller = '$controller' and fl_tipo = 'M'");

		if ($Row->id) {
			$select = $this->select()->setIntegrityCheck(false);
			$select->from(array('a'=>'sistema.acao'));
			$select->where('id_parent = ?', $Row->id);
			$select->where('fl_tipo = ?', 'L');
			$select->order('nr_ordem');

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

	public function reOrder($id, $type) {
		try {
			$Atual = $this->find($id)->current();
			$operator = ($type == 'up' ? '<' : '>');
			$order = ($type == 'up' ? 'desc' : 'asc');

			$select = $this->select()->distinct(true);
			$select->from(array('a' => 'sistema.acao'));

			if ($Atual->id_parent) {
				$select->where('id_parent = ?', $Atual->id_parent);
			} else {
				$select->where('id_parent is null');
			}

			$select->where("nr_ordem $operator ?", $Atual->nr_ordem);
			$select->order("nr_ordem $order");
			$select->limit(1);
			$Row = $this->fetchRow($select);

			$tmp = $Atual->nr_ordem;
			$Atual->nr_ordem = $Row->nr_ordem;
			$Row->nr_ordem = $tmp;

			$Atual->save();
			$Row->save();

			return true;
		} catch (Exception $e) {
			return false;
		}
	}

	public function getRelatorios($module, $controller) {
		$Select = $this->select()->setIntegrityCheck(false)->distinct(true);
		$Select->where('ds_module = ?', $module);
		$Select->where('ds_controller = ?', $controller);
		$Select->where('fl_tipo = ?', 'R');
		$Select->where('fl_del = ?', 'f');
		$Select->order('ds_label');
		return $this->fetchAll($Select);
	}

	public function getRelatoriosByUser($userId, $module=null, $controller=null) {
		$Select = $this->select()->setIntegrityCheck(false)->distinct(true);
		$Select->from(array('a' => 'sistema.acao'));
		$Select->join(array('ua' => 'sistema.usuarios_acao'), 'a.id = ua.id_acao', null);
		$Select->join(array('p' => 'sistema.acao'), 'a.id_parent = p.id', array('ds_label AS parent'));
		if ($module) {
			$Select->where('a.ds_module = ?', $module);
		}
		if ($controller) {
			$Select->where('a.ds_controller = ?', $controller);
		}
		$Select->where('a.fl_tipo = ?', 'R');
		$Select->where('ua.fl_permitido = ?', true);
		$Select->where('ua.id_usuario = ?', $userId);
		$Select->order('p.ds_label, a.ds_label');
		return $this->fetchAll($Select);
	}

	public function getRelatoriosUsuarioSenhaByUser($userId, $module=null, $controller=null, $action=null) {
		$Select = $this->select()->setIntegrityCheck(false)->distinct(true);
		$Select->from(array('a' => 'sistema.acao'));
		$Select->join(array('ua' => 'sistema.usuarios_acao'), 'a.id = ua.id_acao', null);
		$Select->join(array('p' => 'sistema.acao'), 'a.id_parent = p.id', array('ds_label AS parent'));
		$Select->join(array('rus' => 'sistema.relatorio_usuario_senha'), 'a.id = rus.id_acao and ua.id_usuario = rus.id_usuario', array('senha'));
		if ($module) {
			$Select->where('a.ds_module = ?', $module);
		}
		if ($controller) {
			$Select->where('a.ds_controller = ?', $controller);
		}
		if ($action) {
			$Select->where('a.ds_action = ?', $action);
		}
		$Select->where('a.fl_tipo = ?', 'R');
		$Select->where('ua.fl_permitido = ?', true);
		$Select->where('ua.id_usuario = ?', $userId);
		$Select->order('p.ds_label, a.ds_label');
		return $this->fetchAll($Select);
	}

	public function carregaAcoes($parent) {
		$select = $this->select();
		$select->from(array('a'=>'sistema.acao'), array('ds_label', 'ds_module', 'ds_controller', 'ds_action', 'ds_descricao', 'ds_nome', 'id', 'ds_param'));
		$select->where('id_parent '.($parent ? "= $parent" : "is null") );
		$select->order('nr_ordem');

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

	public function fetchResources() {
		$Select = $this->select()->distinct(true);
		$Select->from(array('a' => 'sistema.acao'), array('', 'ds_module', 'ds_controller', 'ds_action'));
		$Select->order(array('ds_module', 'ds_controller', 'ds_action'));

		return $this->fetchAll($Select);
	}

	public function beforeDelete($id, $field) {
		$RolesAcoes = new Sistema_Model_RolesAcao();
		$RolesAcoes->delete($id, 'id_acao');

		$UsuariosAcoes = new Sistema_Model_UsuarioAcao();
		$UsuariosAcoes->delete($id, 'id_acao');
	}

	public function checkRoleAllowed(int $idRole, int $idAcao)
    {
        $select = $this->select()->setIntegrityCheck(false)->distinct(true);
        $select->from(array('a' => 'sistema.roles_acao'));
        $select->where('fl_permitido = true');
        $select->where('id_role = ?', $idRole);
        $select->where('id_acao = ?', $idAcao);

        return $this->fetchAll($select)->count();
    }

	public function checkUserAllowed($idUser, $idAcao) {
		$Select = $this->select()->setIntegrityCheck(false)->distinct(true);
		$Select->from(array('a' => 'sistema.usuarios_acao'));
		$Select->where('id_usuario = ?', $idUser);
		$Select->where('id_acao = ?', $idAcao);
		$Row = $this->fetchRow($Select);

		if ($Row) {
			return $Row->fl_permitido;
		} else {
			return false;
		}
	}

	public function checkUserAllowedWithException($idUser, $idAcao) {
		$Select = $this->select()->setIntegrityCheck(false)->distinct(true);
		$Select->from(array('a' => 'sistema.usuarios_acao'));
		$Select->where('id_usuario = ?', $idUser);
		$Select->where('id_acao = ?', $idAcao);
		$Row = $this->fetchRow($Select);

		if ($Row) {
			return $Row->fl_permitido;
		} else {
			return true;
		}
	}
	
	public function getFilhos($idAcao) {
		$Select = $this->select()->setIntegrityCheck(false)->distinct(true);
		$Select->from(array('a' => 'sistema.acao'));
		$Select->where('id_parent = ?', $idAcao);
	
		return $this->fetchAll($Select)->toArray();
	}

	public function checkUserExcecao($idUser) {
		$Select = $this->select()->setIntegrityCheck(false)->distinct(true);
		$Select->from(array('a' => 'sistema.usuarios_acao'));
		$Select->where('id_usuario = ?', $idUser);
	
		return $this->fetchAll($Select)->count();
	}

	public function getUserExcecao($idUser) {
		$Select = $this->select()->setIntegrityCheck(false)->distinct(true);
		$Select->from(array('a' => 'sistema.usuarios_acao'));
		$Select->where('id_usuario = ?', $idUser);
	
		return $this->fetchAll($Select);
	}
	
	public function temFilhos($id_acao){
		return ($this->fetchAll("id_parent=$id_acao")->count() > 0 ? true : false);
	}
	
	public function acaoPermitida($id_acao){
		$Row = $this->find($id_acao)->current();
		
		$resource = '';
		if ($Row->ds_module && $Row->ds_controller && $Row->ds_action) {
			$resource = "$Row->ds_module:$Row->ds_controller:$Row->ds_action";
		} else if ($Row->ds_module && $Row->ds_controller && !$Row->ds_action) {
			$resource = "$Row->ds_module:$Row->ds_controller";
		} else if ($Row->ds_module && !$Row->ds_controller && !$Row->ds_action) {
			$resource = "$Row->ds_module";
		}
		
		return Agro_Util::checkPermission($resource);
	}

    public function getIdAcao(string $module, string $controller, string $action) : ?int
    {
        $rs = $this->fetchRow([
            "ds_module = '{$module}'",
            "ds_controller = '{$controller}'",
            "ds_action = '{$action}'"
        ]);

        return !empty($rs) ? (int)$rs['id'] : null;
    }
}