<?php
/*
Author: Jaypee M. Sanchez
Project: G.D.P.R
Date: June 2018
*/

namespace App\Http\Controllers;

use Laravel\Lumen\Routing\Controller as BaseController;
use Illuminate\Http\Request;
use App\Http\Controllers\CrmMailController;
use Illuminate\Support\Facades\Crypt;
use Carbon\Carbon;
use Exception;
use App\Login;
use App\Settings;

class CrmController extends BaseController
{

    private $client = "";
    private const LOGICAL_NAME = 'contact'; //contact, account --> forbidden
    public function __construct(){ 
      $this->client = \AlexaCRM\WebAPI\ClientFactory::createOnlineClient(
        config('custom.ad_instance_uri'),
        config('custom.ad_app_id'),
        config('custom.ad_app_secret')
      );
      ini_set('max_execution_time', 300);
    }

    public function option(){
      return response()->json(['option']);
    }
    private function _system_return($param, $statuscode=200)
    {
        if ($statuscode != 200) return response()->json(['message' => $param], $statuscode);
        else return response()->json( ['message' => $param] );
    }

    public function settings($param) {
      switch($param) {
        case 'insert':

          return  $this->_system_return('insert');
          break;
        case 'get':
          $val = Settings::get_email_pass();
          return  $this->_system_return($val);
          break;
        default:
        return  $this->_system_return('no param');
        break;
      }
    }

    public function connect(Request $request = NULL){
      echo 'TESTTTTT';
      die('error test');
      if ($request->has('email') && $request->has('fname') && $request->has('lname')){
        try {
          $cols = true; //array('firstname', 'lastname', 'fullname', 'emailaddress1');
          $query = new \AlexaCRM\Xrm\Query\QueryByAttribute( static::LOGICAL_NAME );
          $query->AddAttributeValue( 'firstname', $request->fname );
          $query->AddAttributeValue( 'lastname', $request->lname );
          $query->AddAttributeValue( 'emailaddress1', $request->email );
          $query->AddOrder( 'firstname', \AlexaCRM\Xrm\Query\OrderType::Descending() );
          $query->ColumnSet = new \AlexaCRM\Xrm\ColumnSet( $cols );
          $collection = $this->client->RetrieveMultiple( $query );  // error
          
          if (isset($collection->Entities[0]->Id)) {
            $hash_key = base64_encode( date('Y-m-d h:m:s') . $collection->Entities[0]->Id );
            $hash_key = str_replace('=', 'J', $hash_key);
            $loginModel = new Login;
            $loginModel->hash_key = $hash_key;
            $loginModel->client_id = $collection->Entities[0]->Id;
            $loginModel->status = 'A';
            $loginModel->date_create = strtotime(date('Y-m-d h:m:s'));
            $loginModel->date_update = strtotime(date('Y-m-d h:m:s'));
            $loginModel->save();

            $op = array(
              'subject' => '[ERNI Privacy Center] Access to your account',
              'receiver' => app()->environment('production') ? $request->email : config('custom.admin_email'),
              'hash' => $hash_key,
              'from' => config('mail.from')
            );
            $model = new CrmMailController( $op );
            $model->send('login_attempt');
            return  $this->_system_return('An email has been sent to your account');

          }
          return  $this->_system_return('Client Not Found', 404);

        } catch (Exception $e) {
            if ($e->getMessage() == "User Not Found") return $this->_system_return($e->getMessage(), 404);
            return $this->_system_return($e->getMessage(). ' Please try again', 500);
        }

      } else if ($request->has('appid') ) {
        // jms make sure to return items deffined in the frontend user-modify.component.ts line 226 - 230
        /*$this->client->Update( $record );
          $retrievedContact = $this->client->Retrieve( static::LOGICAL_NAME, $id, new \AlexaCRM\Xrm\ColumnSet( true ));
          return response()->json( $this->client->Update( $record ) );
          return $this->_system_return($retrievedContact);*/
        try {
            $record = $this->client->Retrieve( static::LOGICAL_NAME, $request->appid, new \AlexaCRM\Xrm\ColumnSet( true ));
            return  $this->_system_return( $record );
          } catch (Exception $e) {
            if ($e->getMessage() == "User Not Found") return $this->_system_return($e->getMessage(), 404);
            return $this->_system_return($e->getMessage(). ' Please try again', 500);
          }
          
      } else if ( $request->has('bylastname') ) {
          $query = new \AlexaCRM\Xrm\Query\QueryByAttribute( static::LOGICAL_NAME );
          $query->AddAttributeValue( 'lastname', $request->bylastname );
          $query->AddOrder( 'firstname', \AlexaCRM\Xrm\Query\OrderType::Descending() );
          $query->ColumnSet = new \AlexaCRM\Xrm\ColumnSet( true );
          $collection = $this->client->RetrieveMultiple( $query );
          return  $this->_system_return($collection);
      }
      return $this->_system_return('Server Error', 500);
    }

    public function login(Request $request = NULL){

      try {
        if (!$request->has('hash')) throw new Exception('Hash is required');
        $loginModel = new Login;
        
        if ($r = $loginModel->where('hash_key', '=', $request->hash)->where('status', '=', 'A')->orderBy('id', 'desc')->first()){
          if ($r->created_at < Carbon::now()->subMinutes(15)->toDateTimeString()){
            throw new Exception('Unique string has expired. Please try to request again');
          } else if (true){
            //check if the otp is one time used only
          }

          $retrievedContact = $this->client->Retrieve( static::LOGICAL_NAME, $r->client_id, new \AlexaCRM\Xrm\ColumnSet( true ));
          return response()->json( $retrievedContact );
        } else {
          throw new Exception('Invalid Login String');
        }
        
      } catch (Exception $e) {
        if ($e->getMessage() == "Invalid Login String") return $this->_system_return($e->getMessage(), 404);
        return $this->_system_return($e->getMessage(), 500);
      }

      return $this->_system_return('Client ID is required', 401);
    }

    /*
    List of editable fields:
    followemail :: boolean
    fullname::string
    preferredcontactmethodcode::int 1-5 (1==Any, 2=Email, 3=phone, 4=fax, 5=Mail)
    followemail::boolean
    donotemail::boolean  (donotemail == email)
    donotbulkemail::boolean
    donotphone::boolean (donotphone == phone)
    donotfax::boolean (donotfax == fax)
    donotpostalmail::boolean (donotpostalmail == mail)

    */
    public function save($id, Request $request = NULL) {

      try {
        if (!$this->_checkTokenValidity($request->header('Authorization'))) {
          throw new Exception('Token Sent has Expired');
        }
        if (isset($id) && $id){
        
          $record = new \AlexaCRM\Xrm\Entity( 'contact', $id );
          
          if ($request->has('contactmethod')){
            $record['preferredcontactmethodcode'] = (int)$request->contactmethod;
          }
          if ($request->has('followemail')){
            $record['followemail'] = $request->followemail=='true' ? true : false;
          }
          if ($request->has('email')){
            $record['donotemail'] = $request->email=='true' ? true : false;
          }
          if ($request->has('bulkemail')){
            $record['donotbulkemail'] = $request->bulkemail=='true' ? true : false;
          }
          if ($request->has('phone')){
            $record['donotphone'] = $request->phone=='true' ? true : false;
          }
          if ($request->has('fax')){
            $record['donotfax'] = $request->fax=='true' ? true : false;
          }
          if ($request->has('mail')){
            $record['donotpostalmail'] = $request->mail=='true' ? true : false;
          }
          
          return $this->_system_return($this->client->Update( $record ));
        }
      } catch (Exception $e) {
        if ($e->getMessage() == "Invalid Login String") return $this->_system_return($e->getMessage(), 404);
        return $this->_system_return($e->getMessage(), 500);
      }    
    }

    public function checkConnect($id = NULL){

      return $this->_system_return(Login::find($id));
    }

    private function _checkTokenValidity($token = '') {
      $token = explode(' ', $token);
      $newModel = new Login();
      if ($r = $newModel->where('hash_key', '=', $token[1])->where('status', '=', 'A')->orderBy('id', 'desc')->first()){
        if ($r->created_at < Carbon::now()->subMinutes(60)->toDateTimeString()) {
          return false;
        }
      };
      return true;
    }


}
