<?php

namespace App\Modules\Company\Settings;

use App\Models\Company;
use App\Models\CompanySettings;
use App\Models\LoanApproved;
use App\Traits\UserTraits;
use App\Traits\ValidatorTraits;
use App\Traits\ZipcodeTraits;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Traits\CreateUserActionTraits;
use App\Events\Company\PusherNotificationEvent as CompanyNotificationEvent;

class Settings {

    use UserTraits, ValidatorTraits, ZipcodeTraits, CreateUserActionTraits;
    public $userData;

    public function __construct()
    {
        $this->userData = $this->getCurrentUser();
    }

    public function index()
    {
        return CompanySettings::where('company_id', $this->userData->company_id)
        ->get();
    }

    public function enableDisableBorrowSearch($payload)
    {
        // validation
        if (!$payload->password) 
        {
            return response()->json(
                [
                'errors' => ['Please input your password'],
                ], 
                201
            );
        }

        if (!Hash::check($payload->password, $this->userData->password)) 
        {
            return response()->json(
                [
                'errors' => ['The inputted password is incorrect.'],
                ],
                 201
            );
        }

        // Validate if exising active request existing 
        $isForDisabled = $payload->isEnabled? false : true; 
        if($this->checkActiveBorrowWorkerTransaction($this->userData->company_id) && $isForDisabled){
            return response()->json([
                'errors' => ["Sorry, can't proceed in disabling the borrow and loan functionality. Active borrowed or loaned worker is existing."],
            ], 201);
        }

        $companyData = [
            'enable_borrowing' => $payload->isEnabled? 'true' : 'false',
        ];
        $updateCompanyTransaction = $this->updateCompany($this->userData->company_id, $companyData);

        if ($updateCompanyTransaction) {
            return response()->json([
                'success' => [($payload->isEnabled) ? 'Successfully enabled.' : 'Successfully disabled.'],
            ], 201);
        }

    }

    public function checkActiveBorrowWorkerTransaction($companyID)
    {
        return LoanApproved::select(
            'loan_approved_histories.loaner_company_id',
            'loan_approved_histories.borrower_company_id',
            'loan_approved_histories.date_from',
            'loan_approved_histories.date_to',
            'loan_approved_histories.worker_id',
        )
        ->whereRaw('loan_approved_histories.date_to >= CURDATE()')
        ->whereRaw("(loan_approved_histories.loaner_company_id = " . $companyID . " or loan_approved_histories.borrower_company_id = ". $companyID . ")")  //used whereRaw because orWhere has a bugs
        ->distinct()
        ->first();
    }

    public function updateCompany($companyID, $data)
    {
        return Company::where('id', $companyID)->update($data);
    }

    public function update($payload)
    {
        $companyId  = $this->userData->company_id;
        $key        = null; 
        $value      = null; 

        switch ($payload->key)
        {
            case 'subscribedZipCode': 
                
                $rules = 
                [
                    'subscribedZipCode' => 'required', 
                ]; 

                $validate = $this->validateRequest($payload, $rules);
            
                if ($validate) 
                {
                    return $validate;
                }

                $validate = $this->validateZipcodeIfExisting($payload->subscribedZipCode);
        
                if ($validate) 
                {
                    return response()->json(['errors' => ["Sorry, you have subcribed a ZIP code that is unsupported in our current US ZIP code database."]])->setStatusCode(201);
                }

                $key   = "subscribed_zipcode";
                $value = $payload->subscribedZipCode;

                break; 

            case 'zipCodeRadius' : 

                $rules = 
                [
                    'zipCodeRadius' => 'required', 
                ]; 

                $validate = $this->validateRequest($payload, $rules);
            
                if ($validate) 
                {
                    return $validate;
                }

                $key   = "subscribed_zipcode_radius";
                $value = $payload->zipCodeRadius;

                break; 

            default :
                
                return response()->json(['errors' => ["Something went wrong while updating settings. Please try again later."]])->setStatusCode(201);
                
                break; 
        }

        $companySettingsTransaction = CompanySettings::updateOrCreate(
            [
                'company_id' => $companyId,
                'key'        => $key,
            ],
            [
                'value'     => $value
            ]
        );

        if($companySettingsTransaction){

            $triggerFetchNotification = array(
                'company_id' => $companyId,
            );
            event(new CompanyNotificationEvent($triggerFetchNotification));
        }

        $user = $this->getCurrentUser();
        if($payload->key == "subscribedZipCode"){
            $this->createUserAction($user->first_name." ".$user->last_name." updated the subscribed zip code to ".$payload->subscribedZipCode);
        }
        elseif($payload->key == "zipCodeRadius"){
            $this->createUserAction($user->first_name." ".$user->last_name." updated the subscribed zip code radius to ".$payload->zipCodeRadius." miles");
        }
        
        
        return response()->json(['success' => ["Company settings successfully updated."]])->setStatusCode(201);
        

        
    }

    public function updateCompanySettings($companyID, $key, $data)
    {
        // if exist update, if settings not exist create
        return CompanySettings::updateOrCreate(
            // data indentification - company id and the settings key
            [
                'company_id' => $companyID, 
                'key' => $key
            ],
            $data  // data to be saved
        );
    }

    public function updateEmailNotification($payload)
    {
        $rules = array(
            'worker_request_email_notification' => 'required|in:enabled,disabled',
        );
        $validate = $this->validateRequest($payload, $rules);
        if ($validate) {
            return $validate;
        }

        $key = 'worker_request_email_notification'; //key of company settings subject to be updated
        $companyID = $this->userData->company_id;

        DB::beginTransaction();
        $settingsData = [
            'company_id' => $companyID,
            'key' => $key,
            'value' => $payload[$key],
        ];

        $settingsTransaction = $this->updateCompanySettings($companyID, $key, $settingsData);
        if(!$settingsTransaction){
            DB::rollBack();
            return response()->json(['errors' => ["Something went wrong while updating settings. Please try again later."]])->setStatusCode(201);
        }

        DB::commit();

        $user = $this->getCurrentUser();
        $this->createUserAction($user->first_name." ".$user->last_name." ".$payload[$key]." the employee request email notification");
        return response()->json(['success' => ["Worker request email notification successfully updated."]])->setStatusCode(201);
    }

}