<?php

namespace App\Modules\Company\Jobseeker;

use App\Models\Worker;
use App\Models\Company;
use App\Models\CompanyUser;
use App\Models\JobseekerApplicant;
use App\Traits\SearchTraits;
use App\Traits\SortingTraits;
use App\Traits\UserTraits;
use App\Traits\ValidatorTraits;
use App\Traits\ZipcodeTraits;
use App\Http\Resources\Company\JobSeekerResume;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;

class ResumeSearch
{
    use SortingTraits, SearchTraits, ValidatorTraits, ZipcodeTraits, UserTraits;
    public $companyId;

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

    public function searchJobseekerResume($payload)
    {
        // sorting
        $sortField = $this->sortField($payload, 'first_name'); // first_name = default column to search
        $sortOrder = $this->sortOrder($payload);

        $nameSearch = $this->searchField($payload->name);
        // Arrays
        $expertises = $payload->expertise;
        $experiences = $payload->experience;
        $areaOfWorkSearch = $payload->work_area_lists;

        $applicants = $this->added_applicant($this->companyId);

        // advance search
        $zipcode = $payload->zipcode;
        $zipcodeRange = $payload->zipcodeRange;
        if (!isset($zipcode)) {
            $zipcode = $this->getCurrentCompanyZipcode();
        }
        if (!isset($zipcodeRange)) {
            $zipcodeRange = 2;
        }

        $zipcodeRangeSearch = $this->getZipcodesByRadius($zipcode, $zipcodeRange);

        // https://stackoverflow.com/questions/18861186/eloquent-eager-load-order-by
        return JobSeekerResume::collection(
            Worker::select(
                'workers.id',
                DB::raw('CONCAT(first_name, " ", last_name) as name'),
                DB::raw('CONCAT(street_address, ", ", city, ", ", state, ", " , zipcode) as address'),
                DB::raw('DATE_FORMAT(workers.created_at, "%Y-%m-%d") as date_uploaded'),
                'workers.zipcode',
                'workers.distance',
                'workers.email_address',
                'workers.resume_file_name as resume',
                'jobseeker_subscriptions.duration'
            )
                ->leftJoin('jobseeker_subscriptions', 'jobseeker_subscriptions.worker_id', '=', 'workers.id')
                ->with('files')
                ->with('jobseeker_work_area_lists')->whereHas('jobseeker_work_area_lists', function ($query) use ($areaOfWorkSearch) {
                    $query->when(!empty($areaOfWorkSearch), function ($query) use ($areaOfWorkSearch) {
                        return $query->whereIn('jobseeker_work_area_lists.work_area_id', $areaOfWorkSearch);
                    });
                })
                ->with('get_jobseeker_experiences')->whereHas('get_jobseeker_experiences', function ($query) use ($expertises) {
                    $query->when(!empty($expertises), function ($query) use ($expertises) {
                        return $query->whereIn('expertise_id', $expertises);
                    });
                })
                ->with('get_jobseeker_experiences')->whereHas('get_jobseeker_experiences', function ($query) use ($experiences) {
                    $query->when(!empty($experiences), function ($query) use ($experiences) {
                        return $query->whereIn('experience_id', $experiences);
                    });
                })
                ->when(str_contains($sortField, 'expertise') || str_contains($sortField, 'experience'), function ($query) {
                    $query
                        ->join('worker_experiences', 'workers.id', '=', 'worker_experiences.worker_id')
                        ->leftJoin('experiences', 'experiences.id', '=', 'worker_experiences.experience_id')
                        ->leftJoin('expertises', 'expertises.id', '=', 'worker_experiences.expertise_id')
                        ->addSelect(
                            'experience_id',
                            'expertise_id',
                            'experiences.name as experience_name',
                            'expertises.name as expertise_name',
                            'worker_experiences.experience as other_experience',
                            'worker_experiences.expertise as other_expertise',
                        )
                        ->where('worker_experiences.is_worker', 'LIKE', 'false');
                })
                ->when(!empty($nameSearch), function ($query) use ($nameSearch) {
                    return $query->where(function ($query) use ($nameSearch) {
                        $query->where('workers.first_name', 'LIKE', $nameSearch . '%')
                            ->orWhere('workers.last_name', 'LIKE', $nameSearch . '%');
                    });
                })
                ->when(count($applicants) > 0, function ($query) use ($applicants) {
                    return $query->whereNotIn('workers.id', $applicants);
                })
                ->when(!empty($zipcodeRangeSearch), function ($query) use ($zipcodeRangeSearch) {
                    return $query->whereIn('workers.zipcode', $zipcodeRangeSearch);
                })
                ->where('jobseeker_subscriptions.duration', '>=', Carbon::now())
                ->where('workers.worker_id', '=', null)
                ->whereNotNull('workers.email_verified_at')
                ->orderBy($sortField, $sortOrder)
                ->paginate(20)
        )->response()->setStatusCode(201);
    }

    public function added_applicant($company_id)
    {
        $hold = array();
        $datas = JobseekerApplicant::select('worker_id')->where('company_id', $company_id)->get();
        foreach ($datas as $data) {
            array_push($hold, $data->worker_id);
        }
        return $hold;
    }

    public function getCurrentCompanyZipcode()
    {
        $user_data = Company::select('companies.zipcode')
            ->where('companies.id', $this->companyId)
            ->limit(1)
            ->get();
        return $user_data[0]->zipcode;
    }

    public function fetchJobseekerDetails($id)
    {
        $isWorker = CompanyUser::where('role_id', 5)->where('worker_id', $id)->first();
        $getExperiences = $isWorker? 'get_worker_experiences': 'get_jobseeker_experiences';

        $jobseeker = Worker::select(
            'workers.id',
            'workers.email_address',
            'workers.first_name',
            'workers.last_name',
            DB::raw('CONCAT(first_name, " ", last_name) as name'),
            DB::raw('CONCAT(street_address, ", ", city, ", ", state, ", " , zipcode) as address'),
            'workers.street_address',
            'workers.city',
            'workers.state',
            'workers.zipcode',
            'workers.distance',
            'workers.phone_num',
            'workers.profile_picture',
            'workers.availability_start_date',
            'workers.availability_end_date',
            'workers.resume_file_name as resume',
            'workers.email_verified_at',
            'workers.created_at',
        )
            ->with('files')
            ->with('jobseeker_work_area_lists')
            ->with($getExperiences) // work data: experiences and expertise
            ->where('workers.id', $id)
            ->get();

            return JobSeekerResume::collection($jobseeker)->response()->setStatusCode(201);
            
    }

    public function getFileURL($payload)
    {
        return $file = Storage::get($payload->name);
    }
}
