<?php

namespace App\Modules\Company\Notification;

use App\Http\Resources\Company\Tasks as TasksResource;
use App\Models\WorkerRequestNotification;
use App\Models\CompanySettings;
use App\Models\Company;
use App\Models\CompanySubscriptions;
use App\Models\ZipcodeRange;
use App\Traits\SortingTraits;
use App\Traits\UserTraits;
use App\Traits\ZipcodeTraits;
use Illuminate\Support\Facades\Log;



class WorkerRequest
{
    use SortingTraits, UserTraits, ZipcodeTraits;
    public $userData;

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

    public function getData($payload)
    {
       
        $companyID = $this->userData->company_id;
        // sorting
        $sortField = $this->sortField($payload, 'created_at');
        $sortOrder = $this->sortOrder($payload, 'desc');

        $notificationSettings = $this->getNotificationSettings($companyID);
        $subscribedZipcode = $notificationSettings->zipcode;
        $subscribedRadius = $notificationSettings->radius;
        $availability =  $notificationSettings->availability;

        $subscribedZipcodeID = $this->getZipcodeID($subscribedZipcode); //coverting zip code to id for id validation purposes
        Log::info($subscribedRadius);
        $listOfSubscribedZipcode = $this->getListOfZipcodeByRadius($subscribedZipcode, $subscribedRadius );
        $listOfSubscribedZipcodeId = $this->getListOfZipcodeID($listOfSubscribedZipcode); //coverting list of zip codes to id for id validation purposes
    
    

        return TasksResource::collection(
            WorkerRequestNotification::select(
                'zipcode_notifications.id',
                'zipcode_notifications.company_id',
                'zipcode_notifications.worker_request_id',
                'zipcode_notifications.state_radius',
                'zipcode_notifications.zipcode_range_id',
                'zipcode_notifications.message',
                'zipcode_notifications.created_at')
                ->join('companies', 'companies.id', '=', 'zipcode_notifications.company_id')
                ->join('worker_requests', 'worker_requests.id', '=', 'zipcode_notifications.worker_request_id')
                ->where('companies.id', '!=', $companyID)
                ->where('worker_requests.status', '=','active')
                ->when($availability == 'disabled', function ($query) use ($notificationSettings){
                    return $query->where('zipcode_notifications.created_at', '<', $notificationSettings->disabled_date);
                })
                ->whereIn('worker_requests.zipcode_range_id', $listOfSubscribedZipcodeId)
                ->where('zipcode_notifications.zipcode_range_id', $subscribedZipcodeID)
                ->where('zipcode_notifications.created_at', '>', $this->getCompanyDateSubscribed())
                ->distinct()
                ->groupBy('zipcode_notifications.worker_request_id')
                ->orderBy($sortField, $sortOrder)
                ->paginate(20)
        )->additional(['meta' => [
            'total_unread_tasks' => $this->getTotalUnreadTasks($availability, $notificationSettings, $subscribedZipcodeID, $listOfSubscribedZipcodeId, $companyID),
            'last_read_worker_request' => $this->userData->last_read_request_notifications_at,
        ]])->response()->setStatusCode(201);
    }

    public function getTotalUnreadTasks($availability, $notificationSettings, $subscribedZipcodeID, $listOfSubscribedZipcodeId, $companyID){

        return WorkerRequestNotification::select()
            ->join('companies', 'companies.id', '=', 'zipcode_notifications.company_id')
            ->join('worker_requests', 'worker_requests.id', '=', 'zipcode_notifications.worker_request_id')
            ->where('worker_requests.status', '=','active')
            ->where('zipcode_notifications.created_at', '>=', $this->userData->last_read_request_notifications_at)
            ->where('zipcode_notifications.zipcode_range_id', $subscribedZipcodeID)
            ->where('zipcode_notifications.created_at', '>', $this->getCompanyDateSubscribed())
            ->when($availability == 'disabled', function ($query) use ($notificationSettings){
                return $query->where('zipcode_notifications.created_at', '<', $notificationSettings->disabled_date);
            })
            ->where('companies.id', '!=', $companyID)
            ->whereIn('worker_requests.zipcode_range_id', $listOfSubscribedZipcodeId)
            ->distinct()
            ->groupBy('zipcode_notifications.worker_request_id')
            ->get()
            ->count();
    }

    public function readWorkerRequest($payload){
        return Company::where('id', $this->userData->company_id)
            ->update(['last_read_request_notifications_at' => now()]);

        return response()->json(201);
    }

    
    public function getNotificationSettings($companyID){
        
        //Getting zip code
        $subscribedZipcode = CompanySettings::where('company_id', $companyID)
            ->where('key', 'subscribed_zipcode')
            ->first();

        $subscribedRadius = CompanySettings::where('company_id', $companyID)
            ->where('key', 'subscribed_zipcode_radius')
            ->first();

        $notificationAvailability = CompanySettings::where('company_id', $companyID)
            ->where('key', 'worker_request_email_notification')
            ->first(); 
     
        $notificationSettings = (object)[
            "zipcode" => $subscribedZipcode? $subscribedZipcode->value: $this->userData->zipcode, 
            "radius" => $subscribedRadius? $subscribedRadius->value: 2,
            "availability" => $notificationAvailability? $notificationAvailability->value: "enabled",
        ];

        if($notificationSettings->availability == "disabled"){
            $notificationSettings->disabled_date = $notificationAvailability->updated_at;
        }
        
        return $notificationSettings;

        // return $this->getZipcodeID($this->userData->zipcode);
    }

    public function getListOfZipcodeByRadius($subscribedZipcode, $subscribedRadius){
        $zipcodeRadius = [2, 5, 10, 15, 20, 25, 50, 100];
        $listOfZipcode = [];   //list of zipcode within the zipcode range

        // Get all the zipcodes within the zipcode range
        foreach($zipcodeRadius as $radius){
            if($radius <= $subscribedRadius ){
                $zipcodeListByRadius = $this->getZipcodesByRadius($subscribedZipcode, $radius);
                $listOfZipcode = [...$listOfZipcode, ...$zipcodeListByRadius];
            }else{
                break;
            }
        }
        return $listOfZipcode;
    }

    public function getZipcodeID($zipcode){
        $data = ZipcodeRange::select('id')->where('zipcode', $zipcode)->first();

        return $data->id;
    }

    public function getCompanyDateSubscribed(){
        $dateSubscribed = CompanySubscriptions::select('date_subscribed')
            ->where('company_subscriptions.company_id', $this->userData->company_id)
            ->first()
            ->date_subscribed;
        Log::info($dateSubscribed);
        return $dateSubscribed;
    }

    public function getListOfZipcodeID($listOfZipcode){
        $data = ZipcodeRange::select('id')->whereIn('zipcode', $listOfZipcode);
        return $data;
    }

}