<?php

namespace App\Modules\Admin\Libraries;

use App\Events\System\UpdateSystemLiblariesEvent;
use App\Http\Resources\Admin\AreasOfWork as AreasOfWorkResource;
use App\Models\WorkAreaExpertise;
use App\Models\WorkAreas;
use App\Models\WorkAreaLists;
use App\Models\WorkerRequestWorkArea;

use Illuminate\Support\Facades\DB;

class WorkAreaModule
{
    public function getData($payload)
    {
        //! Sorting
        $sortField = $payload['sortField'] ?? 'name';
        $sortOrder = $payload['sortOrder'] ?? 'asc';

        //! Searching
        $nameSearch = $payload['name'] ?? null; 

        return AreasOfWorkResource::collection(
            WorkAreas::select(
                'work_areas.id',
                'work_areas.name'
                )
                ->when(!empty($nameSearch), function ($query) use ($nameSearch) 
                    {
                        return $query->where(function ($query) use ($nameSearch) 
                            {
                                $query->where('work_areas.name', 'LIKE', $nameSearch . '%');
                            }
                        );
                    }
                )
                ->orderBy($sortField, $sortOrder)
                ->paginate(20)
        )
        ->response()
        ->setStatusCode(200);
    }

    public function getDetails($id)
    {
        return AreasOfWorkResource::collection(
            WorkAreas::select(
                    'work_areas.id',
                    'work_areas.name'
                )
                ->with('expertises')
                ->where('work_areas.id', $id)
                ->limit(1)
                ->get()
        )
        ->response()
        ->setStatusCode(200);
    }

    public function storeData($payload)
    {
        DB::beginTransaction();
        
        //! Preparing data to be saved on database
        $areaOfWorkData =
        [
            'name' => $payload['name'],
        ];

        $workArea = WorkAreas::create($areaOfWorkData);

        foreach ($payload['expertises'] as $expertise)
        {
            $newWorkAreaExpertise = WorkAreaExpertise::create(
                [
                    'expertise_id' => $expertise,
                    'work_area_id' => $workArea->id,
                ]
            );

            if (!$newWorkAreaExpertise)
            {
                DB::rollBack();
            
                return response()->json(['errors' => 'Something went wrong. Please try again later.'])->setStatusCode(201); 
            }
        }

        if ($workArea)
        {
            DB::commit();
        
            $this->notifyCompaniesSystemData(); //realtime event
        
            return response()->json(['success' => 'Data added successfully.'])->setStatusCode(201); 
        }
        else
        {
            DB::rollBack();

            return response()->json(['errors' => 'Something went wrong. Please try again later.'])->setStatusCode(201); 
        }
    }

    public function updateData($payload, $id)
    {
        DB::beginTransaction();

        //! Preparing data to be saved on database
        $areaOfWorkData = 
        [
            'name' => $payload['name'],
        ];

        $workArea = WorkAreas::find($id);

        $workArea->update($areaOfWorkData);

        //! Remove the associated expertises
        $this->removeExpertiseWorkAreas($id); 

        foreach ($payload['expertises'] as $expertise)
        {
            $newWorkAreaExpertise = WorkAreaExpertise::create(
                [
                    'expertise_id' => $expertise,
                    'work_area_id' => $workArea->id,
                ]
            );

            if (!$newWorkAreaExpertise)
            {
                DB::rollBack();
            
                return response()->json(['errors' => 'Something went wrong. Please try again later.'])->setStatusCode(500); 
            }
        }

        if ($workArea)
        {
            DB::commit();

            $this->notifyCompaniesSystemData(); 

            return response()->json(['success' => 'Data added successfully.'])->setStatusCode(200); 
        }
        else
        {
            DB::rollBack();

            return response()->json(['errors' => 'Something went wrong. Please try again later.'])->setStatusCode(500); 
        }
    }

    public function deleteData($id)
    {
        $isUsedByWorker        = WorkAreaLists::where('work_area_id', $id)->first();
        $isUsedByWorkerRequest = WorkerRequestWorkArea::where('work_area_id', $id)->first();

        if($isUsedByWorker)
        {
            return response()->json(['errors' => 'Unable to delete area of work. Currently in use by Worker(s).'])->setStatusCode(201); 
        }

        if($isUsedByWorkerRequest)
        {
            return response()->json(['errors' => 'Unable to delete area of work. Currently in use by Employee Request(s).'])->setStatusCode(201); 
        }

        WorkAreas::where('id', $id)->forceDelete();

        WorkAreaExpertise::where('work_area_id', '=', $id)->delete(); 

        //! Real-time event
        $this->notifyCompaniesSystemData(); 

        return response()->json(['success' => 'Data deleted successfully.'])->setStatusCode(200);
    }

    public function removeExpertiseWorkAreas($workAreaID)
    {
        return WorkAreaExpertise::where('work_area_id', $workAreaID)->delete();
    }

    public function notifyCompaniesSystemData()
    {
        //! Create an event, once triggered update the current expertise-workarea datas of company
        $createNotification = 
        [
            'on' => 'expertise-workarea',
        ];
        
        event(new UpdateSystemLiblariesEvent($createNotification));
    }
}
