<?php

namespace App\Modules\Jobseeker\Engagement;

use App\Models\JobseekerInvitation;
use App\Models\Notifications;
use App\Traits\SearchTraits;
use App\Traits\SortingTraits;
use App\Traits\ValidatorTraits;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use App\Events\Jobseeker\CompanyNotificationEvent;

class Engagement
{
    use SortingTraits, SearchTraits, ValidatorTraits;
    public $userData;

    public function __construct()
    {
        $this->userData = Auth::user();
    }

    public function fetchAllEngagement($payload)
    {
        $jobseeker_id = $this->userData->id;

        // return $payload;
        $sortField = $this->sortField($payload, 'created_at'); // created_at = default column to search
        $sortOrder = $this->sortOrder($payload, 'desc');

        $company_name = $this->searchField($payload->company_name);
        // $invitation_id = $this->searchField($payload->id);
        $invitation_id = $payload->id;

        return JobseekerInvitation::select(
            'jobseeker_notifications.invitation_id',
            'jobseeker_notifications.company_id',
            'jobseeker_notifications.worker_id',
            'jobseeker_invitations.id',
            'jobseeker_invitations.date_invited',
            'jobseeker_invitations.status',
            'jobseeker_invitations.message',
            'jobseeker_invitations.notes',
            'jobseeker_invitations.created_at',
            DB::raw('CONCAT(workers.first_name, " ", workers.last_name) as jobseeker_name'),
            'companies.id as company_id',
            'companies.name as company_name',
            'companies.company_tel as phone_num',
            'companies.company_tel2 as tel_num',
            DB::raw('CONCAT(companies.street_address, ", ", companies.city, ", ", companies.state, ", ", companies.zipcode) as company_address'),
        )
            ->join('jobseeker_notifications', 'jobseeker_notifications.invitation_id', '=', 'jobseeker_invitations.id')
            ->join('workers', 'workers.id', '=', 'jobseeker_notifications.worker_id')
            ->join('companies', 'companies.id', '=', 'jobseeker_notifications.company_id')
            ->when(!empty($company_name), function ($query) use ($company_name) {
                return $query->where(function ($query) use ($company_name) {
                    $query->where('companies.name', 'LIKE', '%' . $company_name . '%');
                });
            })
            ->when(!empty($invitation_id), function ($query) use ($invitation_id) {
                return $query->where(function ($query) use ($invitation_id) {
                    $query->where('jobseeker_invitations.id', $invitation_id);
                });
            })
            ->where('jobseeker_notifications.worker_id', $jobseeker_id)
            ->orderBy($sortField, $sortOrder)
            ->paginate(20);
    }

    public function viewEnagementDetails($payload)
    {
        $id = $payload->id;
        // return JobseekerInvitation::where('id', $id)->get();
        return JobseekerInvitation::select(
            'jobseeker_notifications.invitation_id',
            'jobseeker_notifications.id as notif_id',
            'jobseeker_invitations.id',
            'jobseeker_invitations.date_invited',
            'jobseeker_invitations.message',
            'jobseeker_invitations.notes',
            'jobseeker_invitations.status',
            DB::raw('CONCAT(workers.first_name, " ", workers.last_name) as jobseeker_name'),
            'companies.name as company_name',
            'companies.id as company_id',
            'companies.company_tel as phone_num',
            'companies.company_tel2 as tel_num',
            DB::raw('CONCAT(companies.street_address, ", ", companies.city, ", ", companies.state, ", ", companies.zipcode) as company_address'),
        )
            ->join('jobseeker_notifications', 'jobseeker_notifications.invitation_id', '=', 'jobseeker_invitations.id')
            ->join('workers', 'workers.id', '=', 'jobseeker_notifications.worker_id')
            ->join('companies', 'companies.id', '=', 'jobseeker_notifications.company_id')
            ->where('jobseeker_invitations.id', $id)
            ->get();

    }

    public function removeEngagement($id)
    {
        $data = JobseekerInvitation::where('id', $id)->delete();

        if ($data) {
            return response(['success' => 'Invitation Successfully Deleted']);
        } else {
            return response(['error' => 'Something went wrong in deleting the invitation']);
        }
    }

    public function declineEngagement($payload)
    {
        $jobseeker_id = $this->userData->id;
        $id = $payload->id;

        DB::beginTransaction();

        $data = JobseekerInvitation::updateOrCreate(
            ['id' => $id],
            ['status' => 'Declined']
        );

        $notification = $this->add_company_info($payload->jobseeker_name, $payload->company_id);
        $declined_application = $this->declined_applicant($jobseeker_id, $payload->company_id);

        if ($data && $notification && $declined_application) {
            DB::commit();
            return array(
                'status' => 'success',
            );
        } else {
            DB::rollBack();
            return array(
                'status' => 'error',
            );
        }
    }

    public function add_company_info($name, $company_id)
    {
        $notification = Notifications::create([
            'type' => 'Jobseeker Transaction',
            'company_id' => $company_id,
            'link' => '/company/job-seeker-applicant',
            'message' => $name . " declined your invitation.",
            'is_read' => 0,
        ]);
        event(new CompanyNotificationEvent($notification)); //Event for realtime notif
        return $notification;
    }

    public function declined_applicant($jobseeker_id, $company_id)
    {
        $data = DB::table('jobseeker_applicants')
            ->where('worker_id', '=', $jobseeker_id)
            ->where('company_id', '=', $company_id)
            ->update(['status' => 'Declined']);

        if ($data) {
            return true;
        } else {
            return true;
        }
    }
}
