<?php

namespace App\Modules\Company\Whiteboard\Project;

use App\Http\Resources\Company\Projects as ProjectsResource;
use App\Http\Resources\Company\ProjectDetails as ProjectDetailsResource;
use App\Models\Projects;
use App\Models\AssignedWorkers;
use App\Traits\SearchTraits;
use App\Traits\UserTraits;
use Illuminate\Support\Facades\DB;


class Project
{
    use SearchTraits, UserTraits;

    public function getData($payload)
    {
        // searching
        $nameSearch = $payload->name;
        $startDate = date('Y-m-d', strtotime($payload->start_date));
        $endDate = date('Y-m-d', strtotime($payload->end_date));

        $companyId = $this->getCurrentUser()->company_id;
        $userId = $this->getCurrentUser()->id;
        return ProjectsResource::collection(
            Projects::select(
                'projects.id',
                'projects.project_manager_id',
                'project_manager.profile_picture',
                'project_manager.first_name',
                'project_manager.last_name',
                'projects.name',
                'projects.description',
                'projects.worker_items',
                'projects.additional_info',
                'projects.location',
                'projects.clock_in',
                'projects.clock_out',
                'projects.date_start',
                'projects.date_end')
                ->join('workers as project_manager', 'project_manager.id', '=', 'projects.project_manager_id')
                ->with(['project_supervisors' => function ($query) {
                    $query->select('project_id', 'user_id', 'date_from', 'date_to', 'profile_picture', 'first_name', 'last_name');
                }])
                ->with(['assigned_employees' => function ($query) use ($startDate, $endDate) {
                    $query->select(
                        'project_id',
                        'availability_id as id',
                        'worker.id as worker_id',
                        'assigned_worker_id',
                        'start_date',
                        'end_date',
                        'worker.profile_picture',
                        'worker.first_name',
                        'worker.last_name',
                        'assigned_availability.worker_type',
                        'assigned_availability.rate',
                        'assigned_availability.is_draft',
                        'company_experiences.id as experience_id',
                        'company_experiences.name as experience_name')
                        ->where(function ($query) use ($startDate, $endDate) {
                            $query->where('start_date', $startDate)
                                ->orWhere('end_date', $endDate)
                                ->orWhereBetween('start_date', [$startDate, $endDate])
                                ->orWhereBetween('end_date', [$startDate, $endDate])
                                ->orWhereRaw('? BETWEEN start_date and end_date', [$startDate])
                                ->orWhereRaw('? BETWEEN start_date and end_date', [$endDate]);
                        })
                        ->whereNull('assigned_availability.deleted_at')
                        ->orderBy('start_date', 'asc')
                        ->orderBy('worker.first_name', 'asc');
                }])
                ->where('projects.company_id', $companyId)
                //->where('projects.created_by', $userId)
                ->where(function ($query) use ($startDate, $endDate) {
                    $query->where('projects.date_start', $startDate)
                        ->orWhere('projects.date_end', $endDate)
                        ->orWhereBetween('projects.date_start', [$startDate, $endDate])
                        ->orWhereBetween('projects.date_end', [$startDate, $endDate])
                        ->orWhereRaw('? BETWEEN projects.date_start and projects.date_end', [$startDate])
                        ->orWhereRaw('? BETWEEN projects.date_start and projects.date_end', [$endDate]);
                })
                ->when(!empty($nameSearch), function ($query) use ($nameSearch) {
                    return $query->where(function ($query) use ($nameSearch) {
                        $query->where('projects.name', 'LIKE', $nameSearch . '%');
                    });
                })
                ->paginate(9)
        )->response()->setStatusCode(201);
    }

    public function getDetails($id)
    {
        // DB::listen(function ($query) {
        //     logger($query->sql);
        // });
        $companyId = $this->getCurrentUser()->company_id;
        return ProjectDetailsResource::collection(
            Projects::select(
                'projects.id',
                'projects.project_manager_id',
                'project_manager.profile_picture',
                'project_manager.first_name',
                'project_manager.last_name',
                'projects.name',
                'projects.description',
                'projects.worker_items',
                'projects.additional_info',
                'projects.location',
                'projects.clock_in',
                'projects.clock_out',
                'projects.date_start',
                'projects.date_end')
                ->join('workers as project_manager', 'project_manager.id', '=', 'projects.project_manager_id')
                // ->with(['project_supervisors' => function ($query) {
                //     $query->select('project_id', 'project_supervisors.id as id', 'user_id', 'date_from', 'date_to', 'first_name', 'last_name');
                // }])
                // ->with(['project_supervisors' => function ($query) {
                //     $query->select('project_id', 'project_supervisors.id as id', 'user_id', 'date_from', 'date_to', 'profile_picture', 'first_name', 'last_name', 'workers.flat_rate', 'workers.rate');
                // }])
                ->with([
                    'project_supervisors.worker.workerBillableRate',
                    'assigned_employees.worker.workerBillableRate',
                    // 'assigned_employees' => function ($query) {
                        // $query->select(
                        //     'project_id',
                        //     'availability_id as id',
                        //     'worker.id as worker_id',
                        //     'assigned_worker_id',
                        //     'start_date',
                        //     'end_date',
                        //     'worker.profile_picture',
                        //     'worker.first_name',
                        //     'worker.last_name',
                        //     'worker.rate',
                        //     'assigned_availability.worker_type',
                        //     'company_experiences.id as experience_id',
                        //     'company_experiences.name as experience_name')
                        //     ->where('assigned_availability.is_draft', 0);
                    // }
                ])
                ->where('projects.company_id', $companyId)
                ->where('projects.id', $id)
                ->limit(1)
                ->get()
            )
            ->response()
            ->setStatusCode(201);
    }


    public function getAssignedEmployeesData($payload, $id)
    {
        // searching
        $nameSearch = $payload->name;
        $startDate = date('Y-m-d', strtotime($payload->start_date));
        $endDate = date('Y-m-d', strtotime($payload->end_date));
        $employeeNameSearch = $payload->employee_name;

        $companyId = $this->getCurrentUser()->company_id;
        $userId = $this->getCurrentUser()->id;
        return ProjectsResource::collection(
            Projects::select(
                'projects.id',
                'projects.project_manager_id',
                'project_manager.profile_picture',
                'project_manager.first_name',
                'project_manager.last_name',
                'projects.name',
                'projects.description',
                'projects.worker_items',
                'projects.additional_info',
                'projects.location',
                'projects.clock_in',
                'projects.clock_out',
                'projects.date_start',
                'projects.date_end')
                ->join('workers as project_manager', 'project_manager.id', '=', 'projects.project_manager_id')
                ->with(['project_supervisors' => function ($query) {
                    $query->select('project_id', 'user_id', 'date_from', 'date_to', 'profile_picture', 'first_name', 'last_name');
                }])
                ->with(['assigned_employees' => function ($query) use ($startDate, $endDate, $employeeNameSearch) {
                    $query->select(
                        'project_id',
                        'availability_id as id',
                        'worker.id as worker_id',
                        'assigned_worker_id',
                        'start_date',
                        'end_date',
                        'worker.profile_picture',
                        'worker.first_name',
                        'worker.last_name',
                        'assigned_availability.worker_type',
                        'assigned_availability.rate',
                        'assigned_availability.is_draft',
                        'company_experiences.id as experience_id',
                        'company_experiences.name as experience_name')
                        ->where(function ($query) use ($startDate, $endDate) {
                            $query->where('start_date', $startDate)
                                ->orWhere('end_date', $endDate)
                                ->orWhereBetween('start_date', [$startDate, $endDate])
                                ->orWhereBetween('end_date', [$startDate, $endDate])
                                ->orWhereRaw('? BETWEEN start_date and end_date', [$startDate])
                                ->orWhereRaw('? BETWEEN start_date and end_date', [$endDate]);
                        })
                        ->when(!empty($employeeNameSearch), function ($query) use ($employeeNameSearch) {
                            return $query->where(function ($query) use ($employeeNameSearch) {
                                $query->where('worker.first_name', 'LIKE', $employeeNameSearch . '%')
                                    ->orWhere('worker.last_name', 'LIKE', $employeeNameSearch . '%');
                            });
                        })
                        ->orderBy('start_date', 'asc')
                        ->orderBy('worker.first_name', 'asc');
                }])
                ->where('projects.company_id', $companyId)
                ->where('projects.created_by', $userId)
                ->where('projects.id', $id)
                ->where(function ($query) use ($startDate, $endDate) {
                    $query->where('projects.date_start', $startDate)
                        ->orWhere('projects.date_end', $endDate)
                        ->orWhereBetween('projects.date_start', [$startDate, $endDate])
                        ->orWhereBetween('projects.date_end', [$startDate, $endDate])
                        ->orWhereRaw('? BETWEEN projects.date_start and projects.date_end', [$startDate])
                        ->orWhereRaw('? BETWEEN projects.date_start and projects.date_end', [$endDate]);
                })
                ->when(!empty($nameSearch), function ($query) use ($nameSearch) {
                    return $query->where(function ($query) use ($nameSearch) {
                        $query->where('projects.name', 'LIKE', $nameSearch . '%');
                    });
                })
                ->paginate(9)
        )->response()->setStatusCode(201);
    }

    public function totalSumOfWorkerRatesAssignedOnProject($projectID){
        $data = AssignedWorkers::select(
            DB::raw('SUM(workers.rate) as total_rate'),
        )
        ->join('workers', 'workers.id', 'assigned_workers.worker_id')
        ->where('project_id', $projectID)
        // ->where('assigned_workers.deleted_at', '!=', null)
        ->first();

        if(!$data->total_rate){
            return 0;
        }

        return $data->total_rate;
    }

    public function count($key, $data) {
        $count = 0;
        foreach($data as $val) {
            if(!property_exists($key, $val)) {
                $count++;
            }
        }
        return $count;
    }
}
