<?php

namespace App\Modules\Company\Employees;

use App\Modules\Company\Employees\Worker as WorkerModule;
use App\Models\AssignedAvailability;
use App\Models\Availabilities;
use App\Models\BorrowPendingWorkers;
use App\Models\CompanyCart;
use App\Models\CompanyUser;
use App\Models\JobseekerApplicant;
use App\Models\JobseekerCompanyRefs;
use App\Models\JobseekerNotification;
use App\Models\WorkAreaLists;
use App\Models\Worker;
use App\Models\WorkerExperience;
use App\Models\Search;
use Illuminate\Support\Facades\DB;
use App\Traits\CreateUserActionTraits;

class DeleteWorker extends WorkerModule
{
    use CreateUserActionTraits;

    public function delete($payload, $id)
    {
        $companyId = $this->getCurrentUser()->company_id;
        $name = $payload->name;

        // check if employee has record on borrow_pending_workers table then decline releasing him/her
        $validate = $this->validateIfEmployeeHasBorrowPendingRequest($id);
        if ($validate) {
            return response()->json(['error' => ['Unable to release employee due to data added on borrow request data.']])->setStatusCode(201);
        }

        // check if employee has record on company_carts table then decline releasing him/her
        $validate = $this->validateIfEmployeeHasDataOnCart($id);
        if ($validate) {
            return response()->json(['error' => ['Unable to release employee due to data added on other company\'s cart.']])->setStatusCode(201);
        }

        // check if employee has record on assigned_availability and assigned_workers table then decline releasing him/her
        $validate = $this->validateIfEmployeeHasDataOnAssignedAvailability($id);
        if ($validate) {
            return response()->json(['error' => ['Unable to release due to employee was assigned to a project.']])->setStatusCode(201);
        }

        $currentContract = $this->checkConnection($id);

        if ($currentContract) {
            DB::beginTransaction();

            // update jobseeker company ref
            $companyRefs = JobseekerCompanyRefs::where('worker_id', $id)->update(['date_end' => date("Y-m-d")]);

            // update worker data
            $workerData = array(
                'worker_id' => null,
                'rate' => null,
            );
            $workerTransaction = $this->update_worker($id, $workerData);

            // delete company worker/user
            $companyUser = $this->delete_worker($id);

            // delete worker worker area list
            $worker_area = $this->deleteWorkerArea($id);

            // delete availabilities
            $availabilities = Availabilities::where('worker_id', $id)->delete();

            // create a user report
            $reports = $this->addUserReports($name);

            // remove an applicant if currently existed
            $applicant = JobseekerApplicant::where('worker_id', $id)->delete();

            $updateSearchData = $this->updateSearchData($id); //Hault the search data

            // add an applicant release notification
            $applicantNotif = array(
                'company_id' => $companyId,
                'worker_id' => $id,
                'type' => 'added-applicant',
                'is_read' => 0,
                'description' => $this->getCurrentUserCompanyName()->name . ' release you as an applicant',
            );
            $applicantNotif = $this->createApplicantNotif($applicantNotif);

            // delete worker
            if (!$companyRefs ||
                !$workerTransaction ||
                !$companyUser ||
                !$availabilities ||
                !$updateSearchData ||
                !$reports) {
                DB::rollBack();
                return response()->json(['error' => ['Unable to release employee.'], 'db-transaction' => [
                    'companyRefs' => $companyRefs,
                    'workerTransaction' => $workerTransaction,
                    'companyUser' => $companyUser,
                    'availabilities' => $availabilities,
                    'reports' => $reports,
                    'applicant' => $applicant,
                ]])->setStatusCode(201);
            } else {
                DB::commit();
                return response()->json(['success' => 'Data deleted successfully.'])->setStatusCode(201);
            }
        } else {
            DB::beginTransaction();

            // release worker
            $companyUser = $this->delete_worker($id);

            // create a user report
            $reports = $this->addUserReports($name);

            if (!$companyUser || !$reports) {
                DB::rollBack();
                return response()->json(['error' => ['Unable to release employee.']])->setStatusCode(201);
            } else {
                DB::commit();
                return response()->json(['success' => 'Data deleted successfully.'])->setStatusCode(201);
            }
        }
    }

    public function validateIfEmployeeHasBorrowPendingRequest($id)
    {
        $employeeData = BorrowPendingWorkers::where('worker_id', $id)->limit(1)->get();
        if ($employeeData->isEmpty()) {
            return false;
        } else {
            return true;
        }
    }

    public function validateIfEmployeeHasDataOnCart($id)
    {
        $employeeData = CompanyCart::where('worker_id', $id)->limit(1)->get();
        if ($employeeData->isEmpty()) {
            return false;
        } else {
            return true;
        }
    }

    public function validateIfEmployeeHasDataOnAssignedAvailability($id)
    {
        $employeeData = AssignedAvailability::join('assigned_workers', 'assigned_workers.id', '=', 'assigned_availability.assigned_worker_id')
            ->where('assigned_workers.worker_id', $id)
            ->limit(1)
            ->get();
        if ($employeeData->isEmpty()) {
            return false;
        } else {
            return true;
        }
    }

    public function checkConnection($id)
    {
        return JobseekerCompanyRefs::where('worker_id', $id)->where('date_end', null)->first();
    }

    public function addUserReports($name)
    {
        return $this->createUserAction("Released " . $name . " as an employee");
    }

    public function update_worker($workerId, $data)
    {
        return Worker::where('id', '=', $workerId)->update($data);
    }

    public function delete_worker($workerId)
    {
        return CompanyUser::where(['worker_id' => $workerId, 'role_id' => 5])->delete();
    }

    public function deleteWorkerExpe($workerId)
    {
        return WorkerExperience::where(['worker_id' => $workerId, 'is_worker' => 'true'])->delete();
    }

    public function deleteWorkerArea($workerId)
    {
        return WorkAreaLists::where(['worker_id' => $workerId, 'worker_type' => 'worker'])->delete();
    }

    public function createApplicantNotif($data)
    {
        return JobseekerNotification::create($data);
    }

    public function updateSearchData($workerId){
        return Search::where('worker_id', $workerId)->update(['status' => 'Haulted']);
    }
}
