<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreLeaveRequest;
use Illuminate\Support\Facades\DB;
use App\Models\Company;
use App\Models\Leave;
use App\Models\LeaveType;
use App\Models\Employee;
use Illuminate\Http\Request;
use App\Services\EmployeeService;

class LeaveController extends Controller
{
    protected $employeeService;

    public function __construct(EmployeeService $employeeService)
    {
        $this->employeeService = $employeeService;
    }

    public function index()
    {
        if (!auth()->user()->hasPermission('Leave List')) {
            abort(403, 'Unauthorized action.');
        }
        $companies = Company::all();
        $leavesQuery = Leave::with(['employee', 'leaveType'])
            ->orderBy(Employee::select(DB::raw("CONCAT(first_name, ' ', last_name)"))
                ->whereColumn('employees.id', 'leaves.employee_id')
            );

        if (!auth()->user()->hasRole('Superadmin')) {
            $leavesQuery->where('company_id', auth()->user()->employee->company_id);
        }
    
        $leaves = $leavesQuery->get();

        $leaveTypes = LeaveType::all();
    
        return view('admin.leaves.index', compact('leaves', 'companies', 'leaveTypes'));
    }

    public function view($id)
    {
        if (!auth()->user()->hasPermission('Leave View')) {
            abort(403, 'Unauthorized action.');
        }
        $leave = Leave::findOrFail($id);
        $leaves = Leave::where('employee_id', $leave->employee_id)
            ->whereYear('created_at', $leave->created_at->year)
            ->whereMonth('created_at', $leave->created_at->month)
            ->get();
        $leaveTypes = LeaveType::all();
        return view('admin.leaves.view', compact('leave', 'leaves', 'leaveTypes'));
    }

    public function create()
    {
        if (!auth()->user()->hasPermission('Leave Create')) {
            abort(403, 'Unauthorized action.');
        }
        $leaveTypes = LeaveType::all();
        $employees = $this->employeeService->getAllEmployees();
        $companies = Company::orderBy('name', 'asc')->get();
        return view('admin.leaves.create', compact('leaveTypes', 'employees', 'companies'));
    }

    public function store(StoreLeaveRequest $request)
    {
        if (!auth()->user()->hasPermission('Leave Create')) {
            abort(403, 'Unauthorized action.');
        }

        $created_at = now()->setDate($request->year, $request->month, now()->day);

        foreach ($request->leave_type as $key => $leave_type_id) {
            // Ensure there's a corresponding days value
            if (isset($request->days[$key]) && $request->days[$key] > 0) {
                Leave::create([
                    'employee_id' => $request->employee,
                    'company_id' => $request->company,
                    'leave_type_id' => $leave_type_id,
                    'days' => $request->days[$key], // Get corresponding days
                    'created_at' => $created_at,
                ]);
            }
        }

        return redirect()->route('leaves.index')->with('success', 'Leave created successfully.');
    }

    public function edit($id)
    {
        if (!auth()->user()->hasPermission('Leave Update')) {
            abort(403, 'Unauthorized action.');
        }
        $leave = Leave::findOrFail($id);
        $leaves = Leave::where('employee_id', $leave->employee_id)
            ->whereYear('created_at', $leave->created_at->year)
            ->whereMonth('created_at', $leave->created_at->month)
            ->get();
        $leaveTypes = LeaveType::all();
        $employees = $this->employeeService->getAllEmployees();
        $companies = Company::orderBy('name', 'asc')->get();
        return view('admin.leaves.edit', compact('leave', 'leaveTypes', 'employees', 'companies', 'leaves'));
    }


    public function update(StoreLeaveRequest $request, $id)
    {
        if (!auth()->user()->hasPermission('Leave Update')) {
            abort(403, 'Unauthorized action.');
        }
        $leave = Leave::findOrFail($id);
        $created_at = now()->setDate($request->year, $request->month, now()->day);
        $existingLeaves = Leave::where('employee_id', $leave->employee_id)
            ->whereYear('created_at', $leave->created_at->year)
            ->whereMonth('created_at', $leave->created_at->month)
            ->get()
            ->keyBy('leave_type_id');

        $updatedLeaveTypeIds = [];

        foreach ($request->leave_type as $key => $leave_type_id) {
            $days = $request->days[$key] ?? 0;

            if ($days > 0) {
                if (isset($existingLeaves[$leave_type_id])) {
                    $existingLeaves[$leave_type_id]->update([
                        'days' => $days,
                        'created_at' => $created_at,
                    ]);
                } else {
                    Leave::create([
                        'employee_id' => $request->employee,
                        'company_id' => $request->company,
                        'leave_type_id' => $leave_type_id,
                        'days' => $days,
                        'created_at' => $created_at,
                    ]);
                }

                $updatedLeaveTypeIds[] = $leave_type_id;
            }
        }

        Leave::where('employee_id', $request->employee)
            ->whereYear('created_at', $request->year)
            ->whereMonth('created_at', $request->month)
            ->whereNotIn('leave_type_id', $updatedLeaveTypeIds)
            ->delete();

        return redirect()->route('leaves.index')->with('success', 'Leave updated successfully.');
    }

    public function destroy($id)
    {
        if (!auth()->user()->hasPermission('Leave Delete')) {
            abort(403, 'Unauthorized action.');
        }
        $leave = Leave::findOrFail($id);
        Leave::where('employee_id', $leave->employee_id)
            ->whereYear('created_at', $leave->created_at->year)
            ->whereMonth('created_at', $leave->created_at->month)
            ->delete();
            
        return redirect()->route('leaves.index')->with('success', 'Leave deleted successfully.');
    }

    public function getApprovedLeavesByEmployee($employeeId)
    {
        $leaves = Leave::where('employee_id',$employeeId)->where('leave_type_id',1)->first();
        return response()->json(['leaves' => $leaves]);
    }
    public function getUnauthorizedLeavesByEmployee($employeeId)
    {
        $leaves = Leave::where('employee_id',$employeeId)->where('leave_type_id',2)->first();
        return response()->json(['leaves' => $leaves]);
    }
    public function getApprovedWithPayLeavesByEmployee($employeeId)
    {
        $leaves = Leave::where('employee_id',$employeeId)->where('leave_type_id',3)->first();
        return response()->json(['leaves' => $leaves]);
    }

    public function getLeavesByEmployee(Request $request, $employeeId)
    {
        $employee = Employee::findOrFail($employeeId);

        // Get all leave types for the employee's company
        $leaveTypes = LeaveType::where('company_id', $employee->company_id)->get();

        $created_at = now()->setDate($request->year, $request->month, now()->day);
    
        // Get total days for each leave_type_id from the leaves table
        $leaveTotals = Leave::where('employee_id', $employeeId)
            ->whereYear('created_at', $created_at->year)
            ->whereMonth('created_at', $created_at->month)
            ->select('leave_type_id', DB::raw('SUM(days) as total_days'))
            ->groupBy('leave_type_id')
            ->pluck('total_days', 'leave_type_id');
    
        // Map leave types with their total days, defaulting to 0 if not present in leaveTotals
        $leaveSummary = $leaveTypes->map(function ($leaveType) use ($leaveTotals) {
            return [
                'leave_type_id' => $leaveType->id,
                'leave_type_name' => $leaveType->name,
                'total_days' => $leaveTotals[$leaveType->id] ?? 0,
            ];
        });
    
        return response()->json(['leaves' => $leaveSummary]);
    }
}