<?php

class RegrasNegocio extends GxActiveRecord
{
    public $valores;
    public $CONDICOES;
    public $ACOES;
    public $EXCECOES;

    public $CONTROLLER;

    const PRIVILEGIO = 1;
    const PROJETO = 2;
    const USUARIO = 3;
    const MOTIVO = 4;
    const ORIGEM_ANTERIOR = 5;
    const AUTOR = 6;
    public $TIPOS_CONDICOES_EXCECOES = array(
        self::PRIVILEGIO      => 'Função',
        self::PROJETO         => 'Projeto',
        self::USUARIO         => 'Usuário',
        self::MOTIVO          => 'Motivo',
        self::ORIGEM_ANTERIOR => 'Origem anterior',
        self::AUTOR           => 'Usuário é o autor',
    );

    const ACAO_MOVIMENTAR = 9;
    const ACAO_EXIBIR = 10;
    const ACAO_LISTAR = 11;
    public $TIPOS_ACOES = array(
        self::ACAO_MOVIMENTAR => 'Movimentar para',
        // self::ACAO_EXIBIR     => 'Exibir',
        // self::ACAO_LISTAR     => 'Listar',
    );

    /**
     * Returns the static model of the specified AR class.
     * @return CActiveRecord the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'regras_negocio';
    }

    /**
     * @return array validation rules for model attribute.
     */
    public function rules()
    {
        return array(
            array('REN_ORIGEM, REN_ACOES, REN_SITUACAO', 'required'),
            array('CONDICOES, ACOES, EXCECOES, CONTROLLER', 'safe'),
            array('ACOES', 'safe', 'on' => 'search'),

            array('CONDICOES, ACOES, EXCECOES', 'validaCampos'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        return array(
            'Grupo' => array(self::BELONGS_TO, 'RegrasGrupos', 'REN_GRUPO', 'joinType' => 'LEFT JOIN'),

            'LocalOrigem' => array(self::BELONGS_TO, 'Locais', 'REN_ORIGEM', 'joinType' => 'LEFT JOIN'),
            // 'Tela' => array(self::BELONGS_TO, 'AclPermissoes', 'REN_ORIGEM', 'joinType' => 'LEFT JOIN'),
        );
    }

    /**
     * @return array customized attribute labels (name=&gt;label)
     */
    public function attributeLabels()
    {
        return array(
            'REN_ID'       => 'Código',
            'REN_ORIGEM'   => 'Origem',
            'REN_SITUACAO' => 'Situação',

            'Grupo'        => 'Grupo',
            'LocalOrigem'  => 'Local de Origem',
            'Descricao'    => 'Descrição'
        );
    }

    public function validaCampos($attribute, $params)
    {
        if (!empty($this->{$attribute}) && is_array($this->{$attribute})) {
            foreach ($this->{$attribute} as $key => $value) {
                $valido = true;
                if (empty($value['tipo']) && empty($value['valor']) && $attribute != "ACOES") {
                    $valido = true;
                    continue;
                }

                if (empty($value['tipo'])) {
                    $this->addError("{$attribute}[{$key}][tipo]", 'Campo obrigatório!');
                    $valido = false;
                }
                if (empty($value['valor'])) {
                    if (!isset($value['valor']) || (isset($value['valor']) && $value['valor'] != 0)) {
                        $this->addError("{$attribute}[{$key}][valor][]", 'Campo obrigatório!');
                        $valido = false;
                    }
                }
            }
            return $valido;
        } else {
            if ($attribute == "ACOES") {
                $this->addError($attribute, $this->getAttributeLabel($attribute) . ' é obrigatório(a)!');
                return false;
            }
        }

        return true;
    }

    public function search()
    {
        $criteria = new CDbCriteria;

        if (!empty($this->REN_ID)) {
            $criteria->compare('REN_ID', $this->REN_ID);
        }
        if (!empty($this->REN_GRUPO)) {
            $criteria->compare('REN_GRUPO', $this->REN_GRUPO);
        }
        if (!empty($this->REN_ORIGEM)) {
            $criteria->compare('REN_ORIGEM', $this->REN_ORIGEM);
        }
        if (!empty($this->REN_SITUACAO)) {
            $criteria->compare('REN_SITUACAO', $this->REN_SITUACAO);
        }

        if (!empty($this->ACOES)) {
            $sql = array();
            if (is_array($this->ACOES)) {
                foreach ($this->ACOES as $tipoAcao) {
                    $json = '["' . $this->ACOES . '"]';
                    $sql[] = "JSON_CONTAINS(JSON_KEYS(REN_ACOES), '" . $json . "')";
                }
            } else {
                $json = '["' . $this->ACOES . '"]';
                $sql[] = "JSON_CONTAINS(JSON_KEYS(REN_ACOES), '" . $json . "')";
            }
            $criteria->addCondition("(" . implode(" OR ", $sql) . ")");
        }

        $sort = new CSort;

        $grupo = RegrasGrupos::model()->findByPk($this->REN_GRUPO);
        if ($grupo->REG_TIPO == RegrasGrupos::TIPO_MOVIMENTACAO) {
            $criteria->with = array(
                'LocalOrigem'  => array(
                    'joinType' => 'LEFT JOIN',
                    'together' => true,
                    'select' => 'LocalOrigem.LOC_DESCRICAO'
                ),
            );

            $sort->defaultOrder = 'LocalOrigem.LOC_DESCRICAO ASC';

            $sort->attributes = array(
                'Origem'=>array(
                  'asc'=>'LocalOrigem.LOC_DESCRICAO',
                  'desc'=>'LocalOrigem.LOC_DESCRICAO desc'
                ),
                '*'
            );
        } else {
            $criteria->with = array(
                'Tela'  => array(
                    'joinType' => 'LEFT JOIN',
                    'together' => true,
                    'select' => array('Tela.ACP_PAGINA', 'Tela.ACP_ACAO')
                ),
            );

            $sort->attributes = array(
                'Origem'=>array(
                  'asc'=>'Tela.ACP_PAGINA asc, Tela.ACP_ACAO asc',
                  'desc'=>'Tela.ACP_PAGINA desc, Tela.ACP_ACAO desc'
                ),
                '*'
            );
        }

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
            'sort' => $sort,
            'pagination' => array(
                'pageSize'  => 50,
            )
        ));
    }

    public function encodeJson()
    {
        if (!empty($this->CONDICOES) || !empty($this->ACOES) || !empty($this->EXCECOES)) {
            if (!empty($this->CONDICOES)) {
                $condicoes = array();
                foreach ($this->CONDICOES as $key => $condicao) {
                    if (isset($condicao['tipo']) && isset($condicao['valor'])) {
                        $condicoes[$condicao['tipo']] = $condicao['valor'];
                    }
                }
                $this->REN_CONDICOES = CJSON::encode($condicoes);
            } else {
                $this->REN_CONDICOES = null;
            }

            if (!empty($this->ACOES)) {
                $acoes = array();
                foreach ($this->ACOES as $key => $acao) {
                    if (isset($acao['tipo']) && isset($acao['valor'])) {
                        $acoes[$acao['tipo']] = $acao['valor'];
                    }
                }
                $this->REN_ACOES = CJSON::encode($acoes);
            }

            if (!empty($this->EXCECOES)) {
                $excecoes = array();
                foreach ($this->EXCECOES as $key => $excecao) {
                    if (isset($excecao['tipo']) && isset($excecao['valor'])) {
                        $excecoes[$excecao['tipo']] = $excecao['valor'];
                    }
                }
                $this->REN_EXCECOES = CJSON::encode($excecoes);
            } else {
                $this->REN_EXCECOES = null;
            }

            return true;
        }
        return false;
    }

    public function decodeJson($toForm = false)
    {
        if (!$this->isNewRecord) {
            if (!empty($this->REN_CONDICOES)) {
                $this->CONDICOES = CJSON::decode($this->REN_CONDICOES);
                if ($toForm) {
                    $condicoes = array();
                    foreach ($this->CONDICOES as $tipo => $valores) {
                        $condicoes[$tipo]['tipo'] = $tipo;
                        $condicoes[$tipo]['valor'] = $valores;
                    }
                    $this->CONDICOES = $condicoes;
                }
            }
            if (!empty($this->REN_ACOES)) {
                $this->ACOES = CJSON::decode($this->REN_ACOES);
                if ($toForm) {
                    $acoes = array();
                    foreach ($this->ACOES as $tipo => $valores) {
                        $acoes[$tipo]['tipo'] = $tipo;
                        $acoes[$tipo]['valor'] = $valores;
                    }
                    $this->ACOES = $acoes;
                }
            }
            if (!empty($this->REN_EXCECOES)) {
                $this->EXCECOES = CJSON::decode($this->REN_EXCECOES);
                if ($toForm) {
                    $excecoes = array();
                    foreach ($this->EXCECOES as $tipo => $valores) {
                        $excecoes[$tipo]['tipo'] = $tipo;
                        $excecoes[$tipo]['valor'] = $valores;
                    }
                    $this->EXCECOES = $excecoes;
                }
            }
            return true;
        }
        return false;
    }

    public function getTipoCondicao($tipo)
    {
        if (!empty($tipo)) {
            return $this->TIPOS_CONDICOES_EXCECOES[$tipo];
        }
        return "";
    }

    public function getTipoAcao($tipo)
    {
        return $this->TIPOS_ACOES[$tipo];
    }

    private function getModelDoTipo($tipo, $grupo = false)
    {
        switch ($tipo) {
            case RegrasGrupos::RESTRICAO_PRIVILEGIO:
                return 'Privilegios';
                break;
            case RegrasGrupos::RESTRICAO_PROJETO:
                return 'Projetos';
                break;
            case RegrasGrupos::RESTRICAO_USUARIO:
                return 'Funcionarios';
                break;
            case RegrasGrupos::RESTRICAO_MOTIVO:
                return 'Motivos';
                break;
            case RegrasGrupos::RESTRICAO_LOCAL_ATUAL:
                $restricoesGrupo = CJSON::decode($grupo->REG_RESTRICOES);
                $restricaoLocalAtual = $restricoesGrupo[RegrasGrupos::RESTRICAO_LOCAL_ATUAL];
                if ($restricaoLocalAtual == RegrasGrupos::ORIGEM_LOCAL) {
                    return 'Locais';
                } elseif ($restricaoLocalAtual == RegrasGrupos::ORIGEM_MOTIVO) {
                    return 'Motivos';
                } else {
                    return false;
                }
                break;
            case RegrasGrupos::RESTRICAO_ORIGEM_ANTERIOR:
                if ($grupo->REG_TIPO_ORIGEM == RegrasGrupos::ORIGEM_LOCAL) {
                    return 'Locais';
                } elseif ($grupo->REG_TIPO_ORIGEM == RegrasGrupos::ORIGEM_MOTIVO) {
                    return 'Motivos';
                } else {
                    return false;
                }
                break;
            default:
                return false;
                break;
        }
    }

    private function getModelAcao($tipo)
    {
        switch ($tipo) {
            case self::ACAO_MOVIMENTAR:
            case self::ACAO_LISTAR:
                $grupo = $this->Grupo;
                if (!empty($grupo)) {
                    if ($grupo->REG_TIPO_ORIGEM == RegrasGrupos::ORIGEM_LOCAL) {
                        return 'Locais';
                    } elseif ($grupo->REG_TIPO_ORIGEM == RegrasGrupos::ORIGEM_MOTIVO) {
                        return 'Motivos';
                    }/* else {
                        return 'AclPermissoes';
                    }*/
                } else {
                    return 'Locais';
                }
                break;

            default:
                return false;
                break;
        }
    }

    public function getDescricao($newLine = "<br>")
    {
        $descricao = "";
        if (!$this->isNewRecord) {
            $this->decodeJson();
            if (!empty($this->REN_CONDICOES)) {
                $descricao .= "<b>Condições:</b>" . $newLine;
                foreach ($this->CONDICOES as $tipo => $valores) {
                    $nomeModel = $this->getModelDoTipo($tipo, $this->Grupo);
                    $nomeTipo = $this->Grupo->getTipoRestricao($tipo);

                    $descricao .= "Se {$nomeTipo} é: {$newLine}";
                    $descricao .= '"';

                    if (is_array($valores)) {
                        $nomes = array();
                        foreach ($valores as $key => $valor) {
                            if ($nomeModel) {
                                $model = new $nomeModel;
                                $representingColumn = $model->representingColumn();
                                $temp = $model->findByPk($valor);
                                if ($temp) {
                                    $nomes[$key] = $temp->{$representingColumn};
                                }
                            } elseif (in_array($tipo, array_keys($this->Grupo->getSingleRestricoes()))) {
                                $descricao .= ($valor) ? 'Sim' : 'Não';
                            }
                        }
                        if (count($nomes) > 1) {
                            $ultimo = $nomes[$key];
                            unset($nomes[$key]);

                            $descricao .= implode("\", \"", $nomes) . "\" ou \"" . $ultimo;
                        } else {
                            $descricao .= implode("\", \"", $nomes);
                        }
                    } else {
                        if ($nomeModel) {
                            $model = new $nomeModel;
                            $representingColumn = $model->representingColumn();
                            $temp = $model->findByPk($valores);

                            $descricao .= $temp->{$representingColumn};
                        } elseif (in_array($tipo, array_keys($this->Grupo->getSingleRestricoes()))) {
                            $descricao .= ($valores) ? 'Sim' : 'Não';
                        }
                    }
                    $descricao .= '"'. $newLine;
                }
            }

            if (!empty($this->REN_ACOES)) {
                $descricao .= "<b>Ação:</b>" . $newLine;
                foreach ($this->ACOES as $tipo => $valores) {
                    $nomeModel = $this->getModelAcao($tipo);
                    // var_dump($nomeModel);
                    $descricao .= "{$this->getTipoAcao($tipo)}: {$newLine}";
                    $descricao .= '"';

                    $nomes = array();
                    if ($nomeModel) {
                        foreach ($valores as $key => $valor) {
                            $model = new $nomeModel;
                            $representingColumn = $model->representingColumn();
                            $temp = $model->findByPk($valor);
                            if ($temp) {
                                $nomes[] = $temp->{$representingColumn};
                            }
                        }
                    } else {
                        /*if ($tipo == RegrasNegocio::ACAO_EXIBIR) {
                            $aclPermissao = AclPermissoes::model()->findByPk($this->REN_ORIGEM);
                            $model = new $aclPermissao->ACP_PAGINA;
                            $colunas = $model->getColumnList();
                            foreach ($valores as $key => $valor) {
                                $nomes[] = $colunas[$valor];
                            }
                        } else {*/
                            $nomes = $valores;
                        // }
                    }
                    $separador = "ou";
                    /*if ($tipo == RegrasNegocio::ACAO_EXIBIR) {
                        $separador = "e";
                    }*/
                    if (count($nomes) > 1) {
                        $ultimo = $nomes[$key];
                        unset($nomes[$key]);

                        $descricao .= implode("\", \"", $nomes) . "\" {$separador} \"" . $ultimo;
                    } else {
                        $descricao .= implode("\", \"", $nomes);
                    }
                    $descricao .= '"'. $newLine;
                }
            }

            if (!empty($this->REN_EXCECOES)) {
                $descricao .= "<b>Exceções: </b>" . $newLine;
                foreach ($this->EXCECOES as $tipo => $valores) {
                    $nomeModel = $this->getModelDoTipo($tipo, $this->Grupo);
                    $nomeTipo = $this->Grupo->getTipoRestricao($tipo);

                    $descricao .= "Se {$nomeTipo} é: {$newLine}";
                    $descricao .= '"';

                    if (is_array($valores)) {
                        $nomes = array();
                        foreach ($valores as $key => $valor) {
                            if ($nomeModel) {
                                $model = new $nomeModel;
                                $representingColumn = $model->representingColumn();
                                $temp = $model->findByPk($valor);
                                $nomes[$key] = $temp->{$representingColumn};
                            } elseif (in_array($tipo, array_keys($this->Grupo->getSingleRestricoes()))) {
                                $descricao .= ($valor) ? 'Sim' : 'Não';
                            }
                        }
                        if (count($nomes) > 1) {
                            $ultimo = $nomes[$key];
                            unset($nomes[$key]);

                            $descricao .= implode("\", \"", $nomes) . "\" ou \"" . $ultimo;
                        } else {
                            $descricao .= implode("\", \"", $nomes);
                        }
                    } else {
                        if ($nomeModel) {
                            $model = new $nomeModel;
                            $representingColumn = $model->representingColumn();
                            $temp = $model->findByPk($valores);
                            $descricao .= $temp->{$representingColumn};
                        } elseif (in_array($tipo, array_keys($this->Grupo->getSingleRestricoes()))) {
                            $descricao .= ($valores) ? 'Sim' : 'Não';
                        }
                    }
                    $descricao .= '"'. $newLine;
                }
            }
        }
        return $descricao;
    }

    public function getOrigem()
    {
        if (!empty($this->REN_ORIGEM)) {
            switch ($this->Grupo->REG_TIPO_ORIGEM) {
                case RegrasGrupos::ORIGEM_LOCAL:
                    $nomeModel = "Locais";
                    break;
                case RegrasGrupos::ORIGEM_MOTIVO:
                    $nomeModel = "Motivos";
                    break;
                default:
                    // $nomeModel = "AclPermissoes";
                    break;
            }

            $model = new $nomeModel;
            return $model->findByPk($this->REN_ORIGEM);
        }
        return false;
    }
    //////

    public function getAcoes($tipos)
    {
        $acoesDisponiveis = array();
        if (is_array($tipos)) {
            foreach ($tipos as $tipo => $label) {
                switch ($tipo) {
                    case RegrasNegocio::ACAO_MOVIMENTAR:
                    case RegrasNegocio::ACAO_LISTAR:
                        $options = array();
                        if ($this->Grupo->REG_TIPO_ORIGEM == RegrasGrupos::ORIGEM_LOCAL) {
                            $locais = Locais::model()->findAll('LOC_SITUACAO = 1 ORDER BY LOC_DESCRICAO ASC');
                            $options = CHtml::listData($locais, 'LOC_IDLOCAL', 'LOC_DESCRICAO');
                        } else {
                            $motivos = Motivos::model()->findAll('MOT_TIPO = 6 AND MOT_SITUACAO = "A"');
                            $options = CHtml::listData($motivos, 'MOT_IDMOTIVO', 'MOT_DESCRICAO');
                        }

                        $acoesDisponiveis[$tipo]['label'] = $label;
                        $acoesDisponiveis[$tipo]['options'] = $options;
                        break;
                    default:
                        $acoesDisponiveis[$tipo]['label'] = $label;
                        $acoesDisponiveis[$tipo]['options'] = array();
                        break;
                }
            }
        }

        return $acoesDisponiveis;
    }

    /*static public function getColunasModel($aclPermissao, $full = false)
    {
        $permissao = AclPermissoes::model()->findByPk($aclPermissao);
        if ($permissao) {
            $models = scandir("./protected/models");
            unset($models[0]);
            unset($models[1]);

            $nomeModel = $permissao->ACP_PAGINA;

            $colunas = array();
            if (in_array($nomeModel.".php", $models)) {
                $model = new $nomeModel;
                if (method_exists($model, 'getColumnList')) {
                    $colunas = $model->getColumnList($full);
                }
            }

            return $colunas;
        } else {
            return false;
        }
    }

    static public function getColunasPermitidas($aclPermissao)
    {
        $colunasPermitidas = array();

        $grupo = RegrasGrupos::model()->find("REG_KEY = 'TelasListagem'");
        $regras = RegrasNegocio::model()->findAll("
            REN_GRUPO = '{$grupo->REG_ID}' AND
            REN_ORIGEM = {$aclPermissao->ACP_ID} AND
            REN_SITUACAO = 1
        ");
        if (!empty($regras)) {
            foreach ($regras as $regra) {
                $regra->decodeJson();

                $addAcao = false;
                if (!empty($regra->CONDICOES)) {
                    $inConditions = false;
                    foreach ($regra->CONDICOES as $tipo => $condicoes) {
                        if ($tipo == RegrasGrupos::RESTRICAO_PRIVILEGIO) {
                            $funcaoFuncionario = CrmAuthenticator::getFuncao(true);
                            $funcao = AclFuncionariosFuncoes::model()->findByPk($funcaoFuncionario);
                            if ($funcao) {
                                if (in_array($funcao->AFF_IDFUNCAO, $condicoes)) {
                                    $inConditions = true;
                                } else {
                                    $inConditions = false;
                                }
                            }
                        } elseif ($tipo == RegrasGrupos::RESTRICAO_USUARIO) {
                            if (in_array(User::getId(), $condicoes)) {
                                $inConditions = true;
                            } else {
                                $inConditions = false;
                            }
                        }
                    }

                    $addAcao = $inConditions;
                } else {
                    $addAcao = true;
                }

                if (!empty($regra->EXCECOES)) {
                    $original = $addAcao;
                    foreach ($regra->EXCECOES as $tipo => $excecoes) {
                        if ($tipo == RegrasGrupos::RESTRICAO_PRIVILEGIO) {
                            $funcaoFuncionario = CrmAuthenticator::getFuncao(true);
                            $funcao = AclFuncionariosFuncoes::model()->findByPk($funcaoFuncionario);
                            if ($funcao) {
                                if (in_array($funcao->AFF_IDFUNCAO, $excecoes)) {
                                    $addAcao = false;
                                } else {
                                    $addAcao = $original;
                                }
                            } elseif ($tipo == RegrasGrupos::RESTRICAO_USUARIO) {
                                if (in_array(User::getId(), $excecoes)) {
                                    $addAcao = false;
                                } else {
                                    $addAcao = $original;
                                }
                            }
                        }
                    }
                }

                if ($addAcao && !empty($regra->ACOES)) {
                    foreach ($regra->ACOES as $tipo => $acoes) {
                        if ($tipo == RegrasNegocio::ACAO_EXIBIR) {
                            foreach ($acoes as $acao) {
                                $colunasPermitidas[] = $acao;
                            }
                        }
                    }
                }
            }

            $colunas = RegrasNegocio::getColunasModel($aclPermissao->ACP_ID, true);
            $retornoColunas = array();
            foreach ($colunas as $coluna) {
                $name = $coluna;
                if (isset($coluna['name'])) {
                    $name = $coluna['name'];
                }

                if (in_array($name, $colunasPermitidas)) {
                    $retornoColunas[] = $coluna;
                }
            }

            return $retornoColunas;
        }

        return false;
    }*/
}
