<?php

namespace App\Controller;

use App\Controller\AppController;
use Alt3\Tokens\RandomBytesToken;
use Cake\Network\Exception\UnauthorizedException;
use Cake\ORM\TableRegistry;

class UsersController extends AppController
{
    // allow Everyone to access
    static $allowed = ['accountLogin', 'signUp', 'getAuth', 'forgetPassword', 'resetPassword'];
    
    //restricted to own only
    static $restricted = ['edit'];
    
    // permitted to logged in user
    static $permitted = ['logout', 'myAccount'];
    
    public function initialize()
    {
        parent::initialize();
        // Allowed to
        $this->Auth->allow(self::$allowed);
//        $this->Crud->disable(['add', 'delete']);
    }
    
    public function isAuthorized($user)
    {
        // Permitted to
        if (in_array($this->request->action, self::$permitted)) {
            return true;
        }
        
        // Restricted to
        if (in_array($this->request->action, self::$restricted)) {
            $id = $this->request->params['pass'][0];
            if ($user['id'] !== $id) {
                return false;
            }
            return true;
        }
        
        // Default deny
        return false;
    }
    
    public function beforeFilter(\Cake\Event\Event $event)
    {
        parent::beforeFilter($event);
        $this->Crud->mapAction('signUp', 'Crud.Add');
    }
    
    public function myAccount()
    {
    }
    
    public function accountLogin()
    {
        if ($this->request->session()->read('Auth.User')) {
            return $this->redirect($this->Auth->redirectUrl());
        }
        if ($this->request->is('post')) {
            $user = $this->Auth->identify();
            if ($user) {
                $user = $this->Users->get($user['id'], [
                    "contain" => ['Addresses']
                ]);
                $this->Auth->setUser($user);
                return $this->redirect($this->Auth->redirectUrl());
            }
            $this->Flash->error(__('Invalid email or password'));
        }
    }
    
    public function signUp()
    {
        
        if ($this->request->session()->read('Auth.User')) {
            return $this->redirect($this->Auth->redirectUrl());
        }
        
        
        $email = $this->request->query['email'];
        $leads = TableRegistry::get('Leads');
        $user = $leads->find("all")->where(['email' => $email, 'type' => 'IMPORT'])->first();
        
        if ($this->request->is('post')) {
            
            // start - remove after 8
            $this->Crud->on('beforeSave', function (\Cake\Event\Event $event) use ($user) {
                $event->subject->entity->email = $user->email;
            });
            // end - remove after 8
            
            $this->Crud->on('afterSave', function (\Cake\Event\Event $event) {
                if ($event->subject->success) {
                    $user = $event->subject->entity;
                    $this->Auth->setUser($user);
                    return $this->redirect($this->Auth->redirectUrl());
                }
            });
            
        }
        
        if (!$user) {
            $this->Flash->error(__('Opps! Account sign up currently only open for pre-registered customer.'));
            return $this->redirect(['controller' => 'leads', 'action' => 'registerInterest']);
        }
        
        $this->set('pre_registered_email', $user->email);
        
        return $this->Crud->execute();
    }
    
    public function logout()
    {
        return $this->redirect($this->Auth->logout());
    }
    
    public function forgetPassword()
    {
        if ($this->request->is('post')) {
            $email = $this->request->data['email'];
            $generateToken = new RandomBytesToken();
            $token = $generateToken->getToken();
            $user = $this->Users->find("all")->where(['email' => $email])->first();
            
            if ($user) {
                $user->token = $token;
                $this->Users->save($user);
                $this->set([
                    'success' => true,
                    'message' => 'Password reset email sent.',
                    '_serialize' => ['success', 'message']
                ]);
            } else {
                throw new UnauthorizedException('Associated email is not found in our system.');
            }
        }
    }
    
    public function resetPassword($token = null)
    {
    
    }
    
    public function edit($id = null)
    {
        if ($this->request->is('put')) {
            
            $this->Crud->on('afterSave', function (\Cake\Event\Event $event) use ($id) {
                
                if ($event->subject->success) {
                    
                    $address = $this->Users->Addresses->find("all")->where(["user_id" => $id])->first();
                    
                    if (!empty($address)) {
                        $address->postal_code = $this->request->data['addresses']['postal_code'];
                        $address->unit_no = $this->request->data['addresses']['unit_no'];
                        $address->address = $this->request->data['addresses']['address'];
                        $this->Users->Addresses->save($address);
                        $event->subject->entity->addresses [] = $address;
                    }
    
                    $this->Auth->setUser($event->subject->entity);
                    
                    $this->set([
                        'success' => true,
                        'data' => $event->subject->entity,
                        'message' => 'Profile update successfully.',
                        '_serialize' => ['success', 'message', 'data']
                    ]);
                } else {
                    throw new UnauthorizedException('Fail to update profile, please try again later.');
                }
            });
        }
        return $this->Crud->execute();
    }
    
    public function getAuth()
    {
        $authUser = $this->request->session()->read('Auth.User');
        if ($authUser) {
            $this->set([
                'authUser' => $authUser,
                '_serialize' => ['authUser']
            ]);
        } else {
            $this->set([
                'authUser' => false,
                '_serialize' => ['authUser']
            ]);
        }
    }
    
}
