<?php

namespace App\Modules\Admin\Libraries;

use App\Events\System\UpdateSystemLiblariesEvent;
use App\Http\Resources\Admin\Expertises as ExpertisesResource;
use App\Models\Expertise;
use App\Models\WorkAreas;
use App\Models\WorkAreaExpertise;
use App\Models\WorkerExperience;

use Illuminate\Support\Facades\DB;

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

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

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

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

    public function storeData($payload)
    {
        DB::beginTransaction();

        $expertiseData = 
        [
            'name' => ucfirst($payload['expertise']),
        ];
        
        $expertise = Expertise::create($expertiseData);

        //! If new work area exist        
        if (isset($payload['newAreas']))
        {
            foreach($payload['newAreas'] as $area)
            {
                $isExist = $this->isWorkAreaExist($area);

                if(!$isExist)
                {

                    //create new area
                    $newWorkArea = WorkAreas::create(
                        [
                            'name' => ucfirst($area)
                        ]
                    );

                    //categorized the new area to the expertise
                    $newWorkAreaExpertise = WorkAreaExpertise::create(
                        [
                            'work_area_id' => $newWorkArea->id,
                            'expertise_id' => $expertise->id,
                        ]
                    );

                    if(!$newWorkArea || !$newWorkAreaExpertise)
                    {
                        DB::rollBack();

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

        //! Select on existing work area
        if( isset($payload['existing_area']) )
        {            
            foreach($payload['existing_area'] as $area)
            {
                $newWorkAreaExpertise = WorkAreaExpertise::create(
                    [
                        'work_area_id' => $area,
                        'expertise_id' => $expertise->id,
                    ]
                );

                if(!$newWorkAreaExpertise)
                {
                    DB::rollBack();

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

            //? $expertise->areas_of_work()->sync($categorizedArea);
        }

        if ($expertise)
        {
            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)
    {
        $this->removeExpertiseWorkAreas($id);

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

        $updateTransaction = Expertise::where('id', $id)
            ->update($expertiseData);
    
        //! Areas of work
        if (isset($payload['areasOfWork']))
        {
            foreach ($payload['areasOfWork'] as $area)
            {
                $newWorkAreaExpertise = WorkAreaExpertise::create(
                    [
                        'work_area_id' => $area,
                        'expertise_id' => $id,
                    ]
                );
    
                if(!$newWorkAreaExpertise)
                {
                    DB::rollBack();
    
                    return response()->json(['errors' => 'Something went wrong. Please try again later.'])->setStatusCode(500); 
                }
            }
        }
        
        if($updateTransaction)
        {
            //! Real-time event
            $this->notifyCompaniesSystemData(); 

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

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

    public function deleteData($id)
    {
        $inUsed = WorkerExperience::where('expertise_id', $id)->first();

        if($inUsed)
        {
            return response()->json(['errors' => 'Unable to delete expertise. Currently in use.'])->setStatusCode(201); 
        }

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

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

        //! Real Time event
        $this->notifyCompaniesSystemData(); 
        
        return response()->json(['success' => 'Data deleted successfully.'])->setStatusCode(200);
    }

    public function isWorkAreaExist($newArea)
    {
        return WorkAreas::where('name', $newArea)->first();
    }

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

        event(new UpdateSystemLiblariesEvent($createNotification)); //Event for realtime notif
    }
}
