<?php

namespace App\Http\Controllers;

use App\Models\LeaveRequest;
use App\Models\Employee;
use Illuminate\Http\Request;
use Yajra\DataTables\DataTables;
use Illuminate\Support\Facades\Auth;

class LeaveRequestController extends Controller
{
    public function index()
    {
        $user = Auth::user();
        $leaveTypes = [
            (object)['id' => 'Sick Leave', 'name' => 'Sick Leave'],
            (object)['id' => 'Casual Leave', 'name' => 'Casual Leave'],
            (object)['id' => 'Annual Leave', 'name' => 'Annual Leave'],
            (object)['id' => 'Other', 'name' => 'Other'],
        ];

        // Filter employees for non-admins
        $query = Employee::query();
        if (!$user->hasRole('Admin')) {
            $subordinateIds = $user->employee ? $user->employee->subordinates->pluck('id') : collect([]);
            $query->whereIn('id', $subordinateIds);
        }
        $employees = $query->get();

        return view('leave_requests.index', compact('leaveTypes', 'employees'));
    }

    public function create()
    {
        return view('leave_requests.create');
    }

    public function getData(Request $request)
    {
        $user = Auth::user();
        $query = LeaveRequest::with(['employee', 'actionBy']);

        // Mandatory Scoping for non-admins
        if (!$user->hasRole('Admin')) {
            $subordinateIds = $user->employee ? $user->employee->subordinates->pluck('id') : collect([]);
            $allowedIds = $subordinateIds->push($user->employee_id);
            $query->whereIn('employee_id', $allowedIds);
        }

        if ($request->has('mine')) {
            $query->where('employee_id', $user->employee_id);
            if ($request->status) {
                $query->where('status', $request->status);
            }
        } elseif ($request->has('team')) {
            $status = $request->status ?: 'pending';
            $query->where('status', $status);

            if ($user->hasRole('Admin')) {
                // Admin sees all based on status except their own (unless specifically looking for history)
                if ($status == 'pending') {
                    $query->where('employee_id', '!=', $user->employee_id);
                }
            } else {
                // Manager sees their subordinates
                $subordinateIds = $user->employee ? $user->employee->subordinates->pluck('id') : collect([]);
                $query->whereIn('employee_id', $subordinateIds);
            }
        }

        // Aggregates for widgets
        $aggQuery = LeaveRequest::query();
        if ($user->hasRole('Admin')) {
            if ($request->has('team')) {
                if (!$request->status || $request->status == 'pending') {
                    $aggQuery->where('employee_id', '!=', $user->employee_id);
                }
            } elseif ($request->has('mine')) {
                $aggQuery->where('employee_id', $user->employee_id);
            }
        } else {
            // Mandatory scope for non-admins
            $subordinateIds = $user->employee ? $user->employee->subordinates->pluck('id') : collect([]);
            if ($request->has('mine')) {
                $aggQuery->where('employee_id', $user->employee_id);
            } else {
                // Default to team view for non-admin widget counts if 'mine' isn't explicitly requested
                $aggQuery->whereIn('employee_id', $subordinateIds);
            }
        }

        // Apply date filters to aggregates
        $aggQuery->when($request->start_date, function ($q) use ($request) {
            return $q->where('start_date', '>=', $request->start_date);
        })
        ->when($request->end_date, function ($q) use ($request) {
            return $q->where('end_date', '<=', $request->end_date);
        })
        ->when($request->employee_id, function ($q) use ($request) {
            return $q->where('employee_id', $request->employee_id);
        });

        $aggregates = [
            'pending' => (clone $aggQuery)->where('status', 'pending')->count(),
            'approved' => (clone $aggQuery)->where('status', 'approved')->count(),
            'rejected' => (clone $aggQuery)->where('status', 'rejected')->count(),
        ];

        return DataTables::of($query)
            ->addColumn('employee', function ($leave) {
                return $leave->employee->name;
            })
            ->editColumn('leave_type', function ($leave) {
                $type = $leave->leave_type;
                if ($leave->is_half_day) {
                    $session = $leave->half_day_session == 'first_half' ? 'First Half' : 'Second Half';
                    $type .= " (Half Day - $session)";
                }
                return $type;
            })
            ->editColumn('status', function ($leave) {
                $status = ucfirst($leave->status);
                $badgeClass = 'bg-light-warning text-warning border-warning';
                if ($leave->status == 'approved') $badgeClass = 'bg-light-success text-success border-success';
                if ($leave->status == 'rejected') $badgeClass = 'bg-light-danger text-danger border-danger';
                
                $html = '<span class="badge ' . $badgeClass . ' border px-2 py-1" style="font-weight: 600;">' . $status . '</span>';
                if ($leave->is_lop) {
                    $html .= ' <span class="badge bg-light-danger text-danger border border-danger px-2 py-1" style="font-weight: 600;">LOP</span>';
                }
                return $html;
            })
            ->addColumn('action', function ($leave) {
                if ($leave->status == 'pending' && Auth::user()->employee_id != $leave->employee_id && Auth::user()->canAccess('leaves.manage')) {
                    return '<div class="d-flex gap-1 justify-content-center">
                            <button class="btn-crm-approve approve-leave" data-id="' . $leave->id . '" title="Approve Request"><i class="fas fa-check"></i></button>
                            <button class="btn-crm-reject reject-leave" data-id="' . $leave->id . '" title="Reject Request"><i class="fas fa-times"></i></button>
                            </div>';
                }

                $status = ucfirst($leave->status);
                $badgeClass = 'bg-light-warning text-warning border-warning';
                if ($leave->status == 'approved') $badgeClass = 'bg-light-success text-success border-success';
                if ($leave->status == 'rejected') $badgeClass = 'bg-light-danger text-danger border-danger';
                
                return '<span class="badge ' . $badgeClass . ' border px-2 py-1" style="font-weight: 600;">' . $status . '</span>';
            })
            ->addColumn('action_by_name', function ($leave) {
                return $leave->actionBy ? $leave->actionBy->name : '-';
            })
            ->rawColumns(['action', 'status'])
            ->with('aggregates', $aggregates)
            ->make(true);
    }

    public function store(Request $request)
    {
        $request->validate([
            'leave_type' => 'required',
            'start_date' => 'required|date',
            'end_date' => 'required|date|after_or_equal:start_date',
            'reason' => 'required',
            'is_half_day' => 'boolean',
            'half_day_session' => 'required_if:is_half_day,1|in:first_half,second_half',
        ]);

        $startDate = $request->start_date;
        $endDate = $request->is_half_day ? $startDate : $request->end_date;

        LeaveRequest::create([
            'employee_id' => Auth::user()->employee_id,
            'leave_type' => $request->leave_type,
            'start_date' => $startDate,
            'end_date' => $endDate,
            'reason' => $request->reason,
            'is_lop' => $request->has('is_lop'),
            'is_half_day' => $request->has('is_half_day'),
            'half_day_session' => $request->is_half_day ? $request->half_day_session : null,
            'status' => 'pending',
        ]);

        if ($request->ajax()) {
            return response()->json(['success' => 'Leave application submitted successfully.']);
        }

        return redirect()->route('leave-requests.index')->with('success', 'Leave application submitted successfully.');
    }

    public function approve(Request $request, $id)
    {
        $leave = LeaveRequest::findOrFail($id);

        // Authorization: Admin or Manager
        if (!Auth::user()->hasRole('Admin') && $leave->employee->manager_id != Auth::user()->employee_id) {
            return response()->json(['error' => 'Unauthorized.'], 403);
        }

        $leave->update([
            'status' => 'approved',
            'action_by' => Auth::user()->employee_id,
            'remarks' => $request->remarks
        ]);

        return response()->json(['success' => 'Leave approved.']);
    }

    public function reject(Request $request, $id)
    {
        $leave = LeaveRequest::findOrFail($id);

        // Authorization: Admin or Manager
        if (!Auth::user()->hasRole('Admin') && $leave->employee->manager_id != Auth::user()->employee_id) {
            return response()->json(['error' => 'Unauthorized.'], 403);
        }

        $leave->update([
            'status' => 'rejected',
            'action_by' => Auth::user()->employee_id,
            'remarks' => $request->remarks
        ]);

        return response()->json(['success' => 'Leave rejected.']);
    }
}
