<?php

namespace App\Modules\Company\Users;

use App\Http\Resources\Company\CompanyUser as CompanyUserResource;
use App\Traits\SearchTraits;
use App\Traits\SortingTraits;
use App\Traits\UserTraits;
use App\Models\Worker;
use Illuminate\Support\Facades\DB;

class Users
{
    use SortingTraits, SearchTraits, UserTraits;

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

        // searching
        $nameSearch = $this->searchField($payload->first_name);
        $emailSearch = $this->searchField($payload->email_address);
        $phoneNumSearch = $this->searchField($payload->phone_num);
        $roleSearch = $payload->roles;

        $status = $payload->status;
        $emailVerifiedAt = '';
        if ($status == 'active') {
            $emailVerifiedAt = 1;
        }

        $companyId = $this->getCurrentUser()->company_id;
        return CompanyUserResource::collection(
            Worker::select(
                'workers.id',
                'workers.first_name',
                'workers.last_name',
                'workers.email_address',
                'workers.profile_picture',
                'workers.phone_num',
                'workers.is_account_disabled',
                'workers.email_verified_at',
                DB::raw('(CASE WHEN workers.email_verification_code like "%admin_verified" THEN 1 ELSE 0 END) AS admin_verified')
            )
                ->join('company_users', 'company_users.worker_id', '=', 'workers.id')
                ->with('roles')->whereHas('roles', function ($query) use ($roleSearch) {
                    $query->when(!empty($roleSearch), function ($query) use ($roleSearch) {
                        return $query->join('roles', 'roles.id', '=', 'company_users.role_id')
                            ->whereIn('roles.id', $roleSearch);
                    });
                })
                ->where('company_users.company_id', $companyId)
                ->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 . '%')
                            ->orWhere(DB::raw('CONCAT(workers.first_name, " ", workers.last_name)'), 'LIKE', $nameSearch . '%');
                    });
                })
                ->when(!empty($emailSearch), function ($query) use ($emailSearch) {
                    return $query->where('workers.email_address', 'LIKE', $emailSearch . '%');
                })
                ->when(!empty($phoneNumSearch), function ($query) use ($phoneNumSearch) {
                    return $query->where('workers.phone_num', 'LIKE', $phoneNumSearch . '%');
                })
                ->when(empty($emailVerifiedAt), function ($query) {
                    return $query->whereNull('workers.email_verified_at');
                })
                ->when(!empty($emailVerifiedAt), function ($query) {
                    return $query->whereNotNull('workers.email_verified_at');
                })
                ->orderBy($sortField, $sortOrder)
                ->groupBy('company_users.worker_id')
                ->paginate(20)
        )->response()->setStatusCode(201);
    }

    public function getDetails($id)
    {
        $companyId = $this->getCurrentUser()->company_id;
        return CompanyUserResource::collection(
            Worker::select(
                'workers.id',
                'workers.worker_id',
                'workers.email_address',
                'workers.phone_num',
                'workers.first_name',
                'workers.last_name',
                'workers.profile_picture',
                'workers.street_address',
                'workers.city',
                'workers.state',
                'workers.zipcode',
                'workers.flat_rate',
                'workers.date_hired',
                'workers.distance',
                'workers.resume_file_name as resume',
                'company_users.availability_status',
                'workers.additional_details',
                'worker_experiences.experience_id',
                'company_experiences.name as experience_name',
                'worker_experiences.experience as experience',
                'worker_experiences.expertise_id',
                'worker_experiences.expertise as expertise',
                'expertises.name as expertise_name')
                ->join('company_users', 'company_users.worker_id', '=', 'workers.id')
                ->leftJoin('worker_experiences', 'worker_experiences.worker_id', '=', 'workers.id')  //left join - to get data even user doesnt have experience
                ->leftJoin('company_experiences', 'company_experiences.id', '=', 'worker_experiences.experience_id')
                ->leftJoin('expertises', 'expertises.id', '=', 'worker_experiences.expertise_id')
                ->with('work_area_lists:work_area_id,worker_id,name')
                ->with('roles:worker_id,role_id,name')
                ->with('files')
                ->where('workers.id', $id)
                ->where('company_users.company_id', $companyId)
                ->limit(1)
                ->get()
        )->response()->setStatusCode(201);
    }

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

        // searching
        $nameSearch = $this->searchField($payload->first_name);
        $emailSearch = $this->searchField($payload->email_address);
        $phoneNumSearch = $this->searchField($payload->phone_num);
        $roleSearch = $payload->roles;

        $companyId = $this->getCurrentUser()->company_id;
        return CompanyUserResource::collection(
            Worker::select(
                'workers.id',
                'workers.first_name',
                'workers.last_name',
                'workers.email_address',
                'workers.profile_picture',
                'workers.phone_num',
                'workers.is_account_disabled',
                DB::raw("IFNULL(workers.email_verified_at,false)"))
                ->join('company_users', 'company_users.worker_id', '=', 'workers.id')
                ->with('roles')->whereHas('roles', function ($query) use ($roleSearch) {
                    $query->when(!empty($roleSearch), function ($query) use ($roleSearch) {
                        return $query->join('roles', 'roles.id', '=', 'company_users.role_id')
                            ->whereIn('roles.id', $roleSearch);
                    });
                })
                ->where('company_users.company_id', $companyId)
                ->whereNull('workers.email_verified_at')
                ->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(!empty($emailSearch), function ($query) use ($emailSearch) {
                    return $query->where('workers.email_address', 'LIKE', $emailSearch . '%');
                })
                ->when(!empty($phoneNumSearch), function ($query) use ($phoneNumSearch) {
                    return $query->where('workers.phone_num', 'LIKE', $phoneNumSearch . '%');
                })
                ->when(!empty($emailVerifiedAt), function ($query) {
                    return $query->whereNotNull('workers.email_verified_at');
                })
                ->orderBy($sortField, $sortOrder)
                ->groupBy('company_users.worker_id')
                ->paginate(20)
        )->response()->setStatusCode(201);
    }
}
