<?php 

use Eae\Transformation\Transformer\BackendUser\BackendUserTransformer;

class AdminUsersController extends Controller {
    
    public function __construct(){
        $this->beforeFilter('csrf', array('on' => 'post')); 
        $this->beforeFilter('backend.auth.permission:users.view', 
            array('only' => array("getIndex", "postList")));
        $this->beforeFilter('backend.auth.permission:users.insert', 
            array('only' => array("postDelete")));    
        
    }
    
    public function getIndex()
    {   
        $loggedUser = BackendUserService::getLoggedUser();
                          
        return View::make(
            'admin/pages/backend_users/admin_users', 
            array(
                'canInsert' => $loggedUser->hasPermission("users.insert")
            ));
    }
    
    public function postList(){
        $page = Input::get("current");
        $sort = Input::get("sort");
        $search = Input::get("searchPhrase");
        
        if (!empty($page)) {
            BackendUser::resolveConnection()->getPaginator()->setCurrentPage($page);
            if (!empty($search)) {
                $query = BackendUser::where(function ($query) use ($search) {
                    $query->orWhere('first_name', 'like', "%{$search}%")
                    ->orWhere('last_name', 'like', "%{$search}%")
                    ->orWhere('email', 'like', "%{$search}%")
                    ->orWhere('role', 'like', "%{$search}%");
                });
            } else {
                $query = BackendUser::query();
            }
            if (empty($sort)) {
                $rows = $query->paginate(Input::get("rowCount"));    
            } else {
                foreach ($sort as $field => $direction) {
                    if(empty($direction) || !str_is(strtolower($direction),"desc")){
                        $order_direction = "asc";    
                    }
                    $rows = $query->orderBy($field, strtolower($direction))->paginate(Input::get("rowCount"));
                    break;
                }
            }

            $result = array(
                "total"             => $rows->getTotal(),
                "current"           => $rows->getCurrentPage(), 
                "rowCount"          => Input::get("rowCount"),
                "rows"              => $rows->getCollection()  
            );
            
            $result["rows"] = TransformService::transformCollection(
                $result["rows"], 
                new BackendUserTransformer)->toArray(); 

            return Response::json($result);            
        } else {
            $users = BackendUser::all();
            return Response::json(TransformService::transformCollection(
                $users, 
                new BackendUserTransformer)->toArray());    
        }
    }
    
    public function postEdit($userId = null)
    {   
        if ($userId !== null && !is_numeric($userId)) {
            App::abort(404);
        }
        
        $loggedUser = BackendUserService::getLoggedUser();
        
        $canManage = $this->_canManage($userId);
        $canEdit   = $this->_canEdit($userId);
        
        if(!$canManage && !$canEdit){
            App::abort(403);    
        }

        $data = array(
            'first_name' => Formatter::transformItem(Input::get('first_name'), "trim|strip_tags|xss_clean"),
        );
        
        if($canManage){
            $data = array(
                'first_name' => Formatter::transformItem(Input::get('first_name'), "trim|strip_tags|xss_clean"),
                'last_name' => Formatter::transformItem(Input::get('last_name'), "trim|strip_tags|xss_clean"),
                'username' => Input::get('username'),
                'email' => Input::get('email'),
                'location' => Formatter::transformItem(Input::get('location'), "trim|strip_tags|xss_clean"),
                'contact_1' => Formatter::transformItem(Input::get('contact_1'), "trim|strip_tags|xss_clean"),
                'contact_2' => Formatter::transformItem(Input::get('contact_2'), "trim|strip_tags|xss_clean"),
                'role' => Formatter::transformItem(Input::get('role'), "trim|strip_tags|xss_clean"),
                'type_id' => Input::get('type_id'),
                'user_permissions' => Input::get('user_permissions', array())
            );

            
            $rules = array(
                'first_name'    => 'required|max:50',
                'last_name'     => 'required|max:50',
                'location'      => 'max:100',
                'contact_1'     => 'max:40',
                'contact_2'     => 'max:40',
                'role'          => 'max:50',
                'type_id'       => 'integer|exists:backend_user_types,id',
                'user_permissions' => 'array'
            );
            
        }else{
            $data = array(
                'username' => Input::get('username')
            ); 
            
            $rules = array();   
        }

        if(Input::has("password")){
            $data['password'] = Input::get('password');
            $data['password_confirmation'] = Input::get('password_confirmation', "");  
        }

        if(!empty($userId)){
            $rules['username'] = 'required|alpha_num|max:20|unique:backend_users,username,' . $userId;
            if($canManage){
                $rules['email'] = 'required|max:100|email|unique:backend_users,email,' . $userId;
            }
            if(Input::has("password")){
                $rules['password'] = 'required|alpha_num|min:6|max:12|confirmed';   
            }
        }else{
            $rules['username'] = 'required|alpha_num|max:20|unique:backend_users';
            $rules['email'] = 'required|max:100|email|unique:backend_users';
            $rules['password'] = 'required|alpha_num|min:6|max:12|confirmed';    
        }
        
        $validator = Validator::make(
            $data,
            $rules
        );
        
        $validator->setAttributeNames(array(
            "type_id" => "type",
            "contact_1" => "contact 1",
            "contact_2" => "contact 2"
        ));
        
        if($canManage){
            $validator->each("user_permissions", array("integer"));
        }
        
        if($validator->fails()){
            Input::flash(); 
            return Redirect::to(Request::path())->withErrors($validator);
        }
        
        if(!empty($userId)){
            $user = BackendUser::find($userId);    
        }else{
            $user = new BackendUser();
        }

        if(empty($user)){
            App::abort(404);    
        }
        
        $user->username = $data["username"];
        
        if($canManage){
            $user->first_name = $data["first_name"];
            $user->last_name = $data["last_name"];
            $user->name = $data["first_name"] . " " . $data["last_name"];
            $user->email = $data['email'];    
            $user->location = $data['location'];
            $user->contact_1 = $data["contact_1"];
            $user->contact_2 = $data["contact_2"];
            $user->role = $data["role"];
            $user->type_id = $data['type_id'];  
        }  

        if(isset($data["password"])){
            $user->password = $data["password"];    
        } 

        DB::transaction(function () use ($user, $canManage, $data) {
            $user->save();
            if($canManage){
                $user->permissions()->sync($data["user_permissions"]);    
            }
        });

        $message = Lang::get('backend.updated_successfully', 
            array('entity' => Lang::get('backend.user')));
            
        
        return Redirect::to('/admin/admin_users/edit/' . $user->id)
            ->with("message", $message);
    }
                                     
    public function getEdit($userId = null)
    {                                        
        if ($userId !== null && !is_numeric($userId)) {
            App::abort(404);
        }

        
        
        $loggedUser = BackendUserService::getLoggedUser(); 
       
        if(!empty($userId) && $loggedUser->id != $userId 
            && !$loggedUser->hasPermission("users.view") &&
            !$loggedUser->hasPermission("users.insert")){
            App::abort(403);    
        }

        $canManage = $this->_canManage($userId);
        $canEdit   = $this->_canEdit($userId);  
        
        RequestContext::set('selected_menu', 'admin');
        RequestContext::set('selected_menu_option', 'list_users');
        
        if (!empty($userId)) {
            $user = BackendUser::find($userId);    
        } else {
            $user = new BackendUser();
        }
        
        if(empty($user)){
            App::abort(404);    
        }
        
        $user->load(array("permissions" => function($query){
            $query->select("id");    
        }));
        
        $userTypes = BackendUserType::orderBy("name", "asc")->lists("name", "id");
        $permissions = BackendPermissionGroup::orderBy("position", "asc")
            ->with(array("permissions" => function($query){
                $query->orderBy("position", "asc");        
            }))->get();

        return View::make('admin/pages/backend_users/user_form')
            ->with(array(
                'user'          => $user,
                'userTypes'     => $userTypes,
                'permissions'   => $permissions,
                'canManage'     => $canManage,
                'canEdit'       => $canEdit,
                'canView'       => $loggedUser->hasPermission("users.view")
            )); 
        
    }
    
    public function postDelete()
    {                                        
        $userId = Input::get('id');
        if (!is_numeric($userId)) {
            return Response::json(array(
                "error" => "bad_syntax",
                "description" => Lang::get("http_status.400")),
                400);
        }
        
        $logged_user = BackendUserService::getLoggedUser();

        if($this->_isOwner($userId)){
            return Response::json(array(
                "error" => "forbidden",
                "description" => "You cannot delete your own user"),
                403);    
        }
        
        $user = BackendUser::find($userId);
        
        if(!empty($user)){
            $user->delete(); 
        }
        
        return Response::json(array("success" => true));
    }
    
    //if the logged user edit. It happens if he can manage or is the owner 
    private function _canEdit($userId){
        if($this->_canManage($userId)){
            return true;    
        }

        return $this->_isOwner($userId);       
    }
    
    //if the logged user has full control. Can change all users
    private function _canManage($userId){
        $loggedUser = BackendUserService::getLoggedUser();
        
        if($loggedUser->hasPermission("users.insert")){
            return true;    
        }
        
        return false;    
    }
    
    private function _isOwner($userId){
        $loggedUser = BackendUserService::getLoggedUser();
        return $loggedUser->id == $userId;    
    } 
    
}
