<?php

namespace App\Http\Controllers\API\v1;

use App\Http\Controllers\Controller;
use App\Models\EmployeeMonthlySchedule;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class EmployeeMonthlyScheduleController extends Controller
{
    public function index(Request $request)
    {
        $user = Auth::user();

        // $monthlyEmployeeScheduleRequest = EmployeeMonthlySchedule::with('department:id,name')
        $monthlyEmployeeScheduleRequest = EmployeeMonthlySchedule::with(['recommending', 'approving', 'department', 'requested'])
            ->where('requested_by', $user->employee_id)
            ->get();

        $decodedSchedules = [];

        foreach ($monthlyEmployeeScheduleRequest as $schedule) {
            
            $decodedData = json_decode($schedule->data, true);
            
            $decodedSchedules[] = [
                'id' => $schedule->id,
                'department_name' => $schedule->department->name, 
                'department_id' => $schedule->department_id, 
                'department_ids' => $decodedData['department_ids'], 
                'entries' => $decodedData['entries'], 
                'recommending' => $schedule->recommending,
                'approving' => $schedule->approving,
                'recommending_id' => $schedule->recommending_id, 
                'approver_id' => $schedule->approver_id, 
                'status' => $schedule->status, 
                'validated' =>$schedule->validated,
                'validated_by' =>$schedule->validated_by,
                'validated_at' =>$schedule->validated_at,
                'deferred_reason' => $schedule->deferred_reason,
                'created_at' => $schedule->created_at, 
                'updated_at' => $schedule->updated_at, 
            ];
        }
        
        // Return the decoded schedules as a JSON response
        return response()->json($decodedSchedules);
    }

    public function store(Request $request)
    {
        $user = Auth::user();

        $validated = $request->validate([
            'department' => 'required|array',
            'department.*' => 'integer|exists:departments,id',
            'recommending_id' => 'required', // Accept both array and integer
            'approver_id' => 'required',     // Accept both array and integer
            'entries' => 'required|array',
            'entries.*.employee' => 'required|array',
            'entries.*.schedule_id' => 'required|integer|exists:schedule_shifts,id',
            'entries.*.date_from' => 'required|date',
            'entries.*.date_to' => 'nullable|date|after_or_equal:entries.*.date_from',
        ]);

        $combinedEntry = [
            'department_ids' => $validated['department'],
            'entries' => [],
        ];

        foreach ($validated['entries'] as $entry) {
            $currentEntry = [
                'schedule_id' => $entry['schedule_id'],
                'date_from' => $entry['date_from'],
                'date_to' => $entry['date_to'],
                'employee' => $entry['employee'], 
            ];

            $combinedEntry['entries'][] = $currentEntry;
        }

        $jsonEntry = json_encode($combinedEntry);

        // Extract single values from arrays if needed
        $recommendingId = is_array($validated['recommending_id']) 
            ? $validated['recommending_id'][0] 
            : $validated['recommending_id'];
        
        $approverId = is_array($validated['approver_id']) 
            ? $validated['approver_id'][0] 
            : $validated['approver_id'];

        $schedule = EmployeeMonthlySchedule::create([
            'department_id' => $validated['department'][0], 
            'data' => $jsonEntry, 
            'recommending_id' => $recommendingId,
            'approver_id' => $approverId,
            'requested_by' => $user->employee_id, 
            'created_at' => now(),
            'updated_at' => now(),
        ]);

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

    public function update(Request $request, $id)
    {
        $user = Auth::user();

        // Find the existing EmployeeMonthlySchedule by ID
        $schedule = EmployeeMonthlySchedule::findOrFail($id);

        // Validate the incoming request
        $validated = $request->validate([
            'department' => 'required|array',
            'department.*' => 'integer|exists:departments,id',
            'entries' => 'required|array',
            'entries.*.employee' => 'required|array',
            'entries.*.schedule_id' => 'required|integer|exists:schedule_shifts,id',
            'entries.*.date_from' => 'required|date',
            'entries.*.date_to' => 'nullable|date|after_or_equal:entries.*.date_from',
        ]);

        // Prepare the combined structure with updated data
        $combinedEntry = [
            'department_ids' => $validated['department'], // Updated department IDs
            'entries' => [],
        ];

        // Loop through entries to update
        foreach ($validated['entries'] as $entry) {
            $currentEntry = [
                'schedule_id' => $entry['schedule_id'],
                'date_from' => $entry['date_from'],
                'date_to' => $entry['date_to'],
                'employee' => $entry['employee'], // Updated employees
            ];

            $combinedEntry['entries'][] = $currentEntry;
        }

        // Convert the combined structure to JSON
        $jsonEntry = json_encode($combinedEntry);

        // Update the existing schedule record
        $schedule->update([
            'department_id' => $validated['department'][0], // Use the first department ID or change as needed
            'data' => $jsonEntry, // Updated JSON data
            'recommending_id' => $request->recommending_id,
            'approver_id' => $request->approver_id,
            'requested_by' => $user->employee_id, // Update requested_by if necessary
            'updated_at' => now(), // Automatically update timestamp
        ]);

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

        // return response()->json(['message' => 'Employee Monthly Schedule updated successfully.'], 200);
    }

    public function destroy(int $id)
    {
        $data = EmployeeMonthlySchedule::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);
    }

    public function getMonthlySchedList(Request $request)
    {
        $user = Auth::user();
        $keyword = $request->input('keyword', '');
        $perPage = $request->input('per_page',PHP_INT_MAX);
        $sortBy = $request->input('sortBy', '');
        $sortType = $request->input('sortType', '');
        $dealership_id = $request->input('dealership', null);

         // Base query with eager loading
        $query = EmployeeMonthlySchedule::with('recommending', 'approving','department:id,name')
        ->where(['status' => 2])
        ->where(function ($query) use ($keyword) {
            if (!empty($keyword)) {
                $keyword = str_replace(' ', '%', $keyword); // Replace spaces with %
                $query->where('data', 'LIKE', "%$keyword%")
                    ->orWhereHas('department', function ($query) use ($keyword) {
                        $query->where('name', 'LIKE', "%$keyword%");
                    });
            }
        });

        if ($request->date_created) {
            $dates = explode(' to ', $request->date_created); // Split into start and end date
            if (count($dates) == 2) {
                $query = $query->whereBetween('created_at', [$dates[0], $dates[1]]);
            }
        }
        
        if ($request->range) {
            $dates = explode(' to ', $request->range); // Split into start and end date
            if (count($dates) == 2) {
                $query = $query->whereBetween('date', [$dates[0], $dates[1]]);
            }
        }
        
        if ($request->status && is_array($request->status)) {
            $query = $query->where(function ($query) use ($request) {
                if (in_array('pending', $request->status)) {
                    $query->orWhere('status', 0);
                }
        
                if (in_array('validated', $request->status)) {
                    $query->orWhere(function ($q) {
                        $q->where('status', 2)->where('validated', 1);
                    });
                }
        
                if (in_array('denied', $request->status)) {
                    $query->orWhere('status', 99)
                        ->orWhere(function ($q) {
                            $q->where('status', 2)->where('validated', 99);
                        });
                }
        
                if (in_array('for_validation', $request->status)) {
                    $query->orWhere(function ($q) {
                        $q->where('status', 2)->where('validated', 0);
                    });
                }
            });
        }   

        // Apply dealership filtering if provided
        // if($dealership_id) $query = $query->where('dealer_id', $dealership_id);

        // Apply sorting
        if (!empty($sortBy) && in_array($sortType, ['asc', 'desc'])) {
            $query->orderBy($sortBy, $sortType);
        }

        // Get paginated results
        $monthlyEmployeeSchedules = $query->paginate($perPage);
        
        // Decode JSON data and transform results
        $decodedSchedules = $monthlyEmployeeSchedules->map(function ($schedule) {
            $decodedData = json_decode($schedule->data, true);
            return [
                'id' => $schedule->id,
                'department_name' => $schedule->department->name ?? null,
                'department_id' => $schedule->department_id,
                'department_ids' => $decodedData['department_ids'] ?? [],
                'entries' => $decodedData['entries'] ?? [],
                'recommending' => $schedule->recommending,
                'approving' => $schedule->approving,
                'recommending_id' => $schedule->recommending_id,
                'approver_id' => $schedule->approver_id,
                'status' => $schedule->status,
                'validated' =>$schedule->validated,
                'validated_by' =>$schedule->validated_by,
                'validated_at' =>$schedule->validated_at,
                'deferred_reason' => $schedule->deferred_reason,
                'requested_by' => $schedule->requested_by,
                'requested_name' => $schedule->requested->firstname.' '.$schedule->requested->lastname,
                'created_at' => $schedule->created_at,
                'updated_at' => $schedule->updated_at,
                
            ];
        });

        // Return paginated data as JSON
        return response()->json([
            'data' => $decodedSchedules,
            'current_page' => $monthlyEmployeeSchedules->currentPage(),
            'per_page' => $monthlyEmployeeSchedules->perPage(),
            'total' => $monthlyEmployeeSchedules->total(),
        ]);
    }


}
