<?php

namespace App\Http\Controllers\API\v1;

use App\Http\Controllers\Controller;
use App\Models\PersonnelActionForm;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Throwable;

class PersonnelActionFormController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        $employee = Auth::user();

        //
        $keyword = $request->input('keyword', '');
        $perPage = $request->input('per_page',PHP_INT_MAX);
        $sortBy = $request->input('sortBy', '');
        $sortType = $request->input('sortType', '');
        $data = PersonnelActionForm::with([
                'employee',
                'type_of_movement', 
                'requestor',
                'recommendor',
                'endorser',
                'approver',
            ])
            ->where(function ($query) use ($keyword) {
            $keyword = str_replace(" ", "%", $keyword);
            // $query->where('name', 'like', '%' . $keyword . '%');
        })->where(function ($query) use ($keyword) {
            $query->orWhereHas('employee', function ($q) use ($keyword) {
                $q->where('employee_id', 'like', "%$keyword%");
            })
            ->orWhereHas('employee', function ($q) use ($keyword) {
                $q->where('firstname', 'like', "%$keyword%")
                    ->orWhere('lastname', 'like', "%$keyword%");
            });
        });

        if ($employee->roles[0]->group_id !== 1) {
            switch ($employee->employees->classification_id) {
                case 2:
                    $data->where('requested_by', $employee->employee_id);
                    break;
                case 3:
                    if ($employee->employees->position_id == 21) {
                        $data->where('endorsed_by', $employee->employee_id)
                            ->where('status', '>=', 1)
                            ->orWhere('requested_by', $employee->employee_id);
                    } else {
                        $data->where('recommended_by', $employee->employee_id)
                            ->orWhere('requested_by', $employee->employee_id);
                    }
                    break;
                case 4:
                    $data->where('approved_by', $employee->employee_id)
                        ->where('status', '>=', 2)
                        ->orWhere('requested_by', $employee->employee_id);
                    break;
            }
        }

        if (!empty($sortBy) && !empty($sortType)) {
            $data = $data->orderBy($sortBy, $sortType);
        }

        $data = $data->paginate($perPage);

        // dd($data);
        return response()->json($data);
    }

    /**
     * Display a listing of the resource.
     */
    public function show($employee_id)
    {
        //
        // dd($employee_id);
        $data = PersonnelActionForm::with([
            'employee',
            'type_of_movement', 
            'requestor',
            'recommendor',
            'endorser',
            'approver',
        ])->select('personnel_action_forms.id', 'jt_prev.name as prev_position_name', 'jt_next.name as next_position_name',
        'personnel_action_forms.*')
        ->join('job_titles as jt_prev', 'personnel_action_forms.position_id', '=', 'jt_prev.id')
        ->join('job_titles as jt_next', 'personnel_action_forms.position' , '=', 'jt_next.id')
        ->where('personnel_action_forms.employee_id', '=', $employee_id)
        ->where('personnel_action_forms.status', '=', '3')
        ->get();

        // dd($data);
        // // Get the raw SQL query
        // $sql = $data->toSql();

        // // // Get the bindings
        // $bindings = $data->getBindings();

        // // // Display the query with bindings
        // dd(vsprintf(str_replace('?', '%s', $sql), array_map('addslashes', $bindings)));

        return response()->json($data);
    }

    public function store(Request $request)
    {
        // Iniialize the supporting documents here
        $supporting_documents = [];
        $supporting_documents_id = [];
        
        if ($request->hasFile('supporting_documents')) {
            
            $documents = $request->file('supporting_documents');
            // dd($documents);
            foreach ($documents as $index => $documentArr) {
                $attachment_name  = time().'_'.$documentArr->getClientOriginalName();
                
                // Push the the attachment_name on $supporting_documents

                $supporting_documents[] = $attachment_name;
                $path       = "paf/".$attachment_name;

                Storage::disk('local')->put($path, file_get_contents($documentArr));
            }
        }

        $documents_id = $request->supporting_documents_id;

        if($documents_id){
            foreach($documents_id as $index => $documents_idArr){
                $supporting_documents_id[] = $documents_idArr;
            }
        }
        
        $user = Auth::user();
        
        $validator = Validator::make($request->all(), [
            'company_id' => "required",
        ]);

        /** If validation fails return with error message */
        if ($validator->fails()) {
            $errors = $validator->errors();
            $first = $errors->getMessages();
            return response()->json([
                'status'  => false,
                'message' => (reset($first))[0],
                'errors'  => $errors
            ], Response::HTTP_UNPROCESSABLE_ENTITY);
        }

        DB::connection()->beginTransaction();
        try {
            $status = PersonnelActionForm::create([
                'company_id' => $request->company_id,
                'employee_id' => $request->employee_id,
                'employment_status_id' => $request->employment_status_id,
                'position_id' => $request->position_id,
                'unit_id' => $request->unit_id,
                'jg_step' => $request->jg_step,
                'present_salary' => $request->present_salary,
                'allowance' => $request->allowance,
                'nature_of_request_id' => $request->nature_of_request_id,
                'position' => $request->position,
                'unit' => $request->unit,
                'salary_increase_to' => $request->salary_increase_to,
                'salary_increment' => $request->salary_increment,
                'honorarium' => $request->honorarium,
                'peso' => $request->peso,
                'incentive' => $request->incentive,
                'commission' => $request->commission,
                'benefits' => $request->benefits,
                'supporting_documents' => json_encode($supporting_documents),
                'supporting_documents_id' => json_encode($supporting_documents_id),
                'effectivity' => $request->effectivity,
                'other' => $request->other,
                'inclusive_period' => $request->inclusive_period,
                'immediate_head' => $request->immediate_head,
                'justification_request' => $request->justification_request,
                'requested_by' => $request->requested_by,
                'recommended_by' => $request->recommended_by,
                'concurred_by' => $request->concurred_by,
                'endorsed_by' => $request->endorsed_by,
                'approved_by' => $request->approved_by,
            ]);

            DB::connection()->commit();

            // dd($request->all());
            
            return response()->json([
                'status'  => true,
                'message' => 'Saved successfully!',
                'data'    => $status
            ],201);

        } catch (Throwable $e) {

            DB::connection()->rollback();
            return response()->json([
                'status'  => false,
                'message' => 'Unable to process request. Please try again.',
                'data'    => $e->getMessage()
            ]);
        }
    }

    public function update(Request $request)
    {

        $id = $request->id;

        $data = PersonnelActionForm::where('id', $id)->first();
        
        if($request->status == 99){
            $request['status'] = 0;
        }

        // dd($request->status);
        // Initialize the supporting documents here
        $supporting_documents = [];
        $supporting_documents_id = [];
        
        if ($request->hasFile('supporting_documents')) {
            $documents = $request->file('supporting_documents');

            if (is_array($documents)) {
                foreach ($documents as $index => $documentArr) {
                    $attachment_name = time() . '_' . $documentArr->getClientOriginalName();
                    
                    // Push the attachment_name on $supporting_documents
                    $supporting_documents[] = $attachment_name;
                    $path = "paf/" . $attachment_name;

                    Storage::disk('local')->put($path, file_get_contents($documentArr));
                }
            }
        }

        $documents_id = $request->supporting_documents_id;

        if ($documents_id && is_array($documents_id)) {
            foreach ($documents_id as $index => $documents_idArr) {
                $supporting_documents_id[] = $documents_idArr;
            }
        }

        $user = Auth::user();
        
        $validator = Validator::make($request->all(), [
            'company_id' => "required",
        ]);

        /** If validation fails return with error message */
        if ($validator->fails()) {
            $errors = $validator->errors();
            $first = $errors->getMessages();
            return response()->json([
                'status'  => false,
                'message' => (reset($first))[0],
                'errors'  => $errors
            ], Response::HTTP_UNPROCESSABLE_ENTITY);
        }

        $attachment_name = $request->attachment;

        if ($data->attachment != $request->attachment) {
            $attachment_file_path = 'paf/' . $data->attachment;
            if (Storage::exists($attachment_file_path)) {
                Storage::delete($attachment_file_path);
            }

            if ($request->hasFile('attachment')) {
                $image = $request->file('attachment');
                $attachment_name = time() . '_' . $image->getClientOriginalName();
                $path = "paf/" . $attachment_name;
                if (!Storage::disk('local')->put($path, file_get_contents($image))) {
                    return response()->json(['message' => "Failed to upload attachment"], 304);
                }
            } else {
                $attachment_name = null;
            }
        }

        DB::connection()->beginTransaction();

        try {
            $data->company_id = $request->company_id;
            $data->employee_id = $request->employee_id;
            $data->employment_status_id = $request->employment_status_id;
            $data->position_id = $request->position_id;
            $data->unit_id = $request->unit_id;
            $data->jg_step = $request->jg_step != 'null' ? $request->jg_step : NULL;
            $data->present_salary = $request->present_salary;
            $data->allowance = $request->allowance != 'null' ? $request->allowance : NULL;
            $data->nature_of_request_id = $request->nature_of_request_id;
            $data->position = $request->position;
            $data->unit = $request->unit != 'null' ? $request->unit : NULL;
            $data->salary_increase_to = $request->salary_increase_to;
            $data->salary_increment = $request->salary_increment != 'null' ? $request->salary_increment : NULL;
            $data->honorarium = $request->honorarium != 'null' ? $request->honorarium : NULL;
            $data->peso = $request->peso != 'null' ? $request->peso : NULL;
            $data->incentive = $request->incentive != 'null' ? $request->incentive : NULL;
            $data->commission = $request->commission != 'null' ? $request->commission : NULL;
            $data->benefits = $request->benefits;
            $data->supporting_documents = json_encode($supporting_documents);
            $data->supporting_documents_id = json_encode($supporting_documents_id);
            $data->effectivity = $request->effectivity;
            $data->other = $request->other != 'null' ? $request->other : NULL;
            $data->inclusive_period = $request->inclusive_period != 'null' ? $request->inclusive_period : NULL;
            $data->immediate_head = $request->immediate_head;
            $data->status = $request->status;
            $data->justification_request = $request->justification_request != 'null' ? $request->justification_request : NULL;
            $data->requested_by = $request->requested_by;
            $data->recommended_by = $request->recommended_by;
            $data->concurred_by = $request->concurred_by != 'null' ? $request->concurred_by : NULL;
            $data->endorsed_by = $request->endorsed_by;
            $data->approved_by = $request->approved_by;

            // dd($data);
            $data->save();
            DB::connection()->commit();

            return response()->json([
                'status'  => true,
                'message' => 'Saved successfully!',
                'data'    => $data
            ], 201);

        } catch (Throwable $e) {
            DB::connection()->rollback();
            return response()->json([
                'status'  => false,
                'message' => 'Unable to process request. Please try again.',
                'data'    => $e->getMessage()
            ]);
        } 
    }


    public function updateStatus(Request $request, $id)
    {
        $data = PersonnelActionForm::find($id);

        if (!$data) {
            return response()->json(['message' => 'No data found.'], 404);
        }

        DB::beginTransaction();
        try {
            $request->status == 3 ? $request['approved_at'] = date('Y-m-d') : '';

            $data->fill($request->all());
            $data->save();
            DB::commit();

            // $employee_id_for_notification = $this->getEmployeeIdForNotification($request->status, $data);
            // $this->sendNotificationToEmployee($employee_id_for_notification, $data);

            return response()->json([
                'message' => 'Record successfully updated!',
                'status' => 'success',
                'data' => $data,
            ], 201);

        } catch (Exception $e) {
            DB::rollBack();
            return $this->exceptionResponse($e);
        }
    }

    public function destroy(int $id)
    {
        $data = PersonnelActionForm::find($id);
        if(!$data)
        {
            return response()->json(['message' => "Record not found!"],204);
        }
        DB::connection()->beginTransaction();
        $data->delete();
        DB::connection()->commit();
        return response()->json(['message' => "Record successfully deleted!"],201);
    }
}
