<?php

namespace App\Http\Controllers;

use App\Models\LeaveRequest;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class LeaveRequestController extends Controller
{
    public function index()
    {
        $user = auth()->user();
        
        if ($user->hasRole('admin')) {
            $leaves = LeaveRequest::with(['employee', 'approvedBy'])
                ->latest()
                ->paginate(15);
        } elseif ($user->hasRole('supervisor')) {
            $employeeIds = $user->subordinates()->pluck('id');
            $leaves = LeaveRequest::with(['employee', 'approvedBy'])
                ->whereIn('employee_id', $employeeIds)
                ->orWhere('employee_id', $user->id)
                ->latest()
                ->paginate(15);
        } else {
            $leaves = LeaveRequest::with(['approvedBy'])
                ->where('employee_id', $user->id)
                ->latest()
                ->paginate(15);
        }
        
        return view('leaves.index', compact('leaves'));
    }

    public function create()
    {
        $user = auth()->user();
        
        // Calculate available leave balance
        $usedLeaves = $user->leaveRequests()
            ->where('status', 'approved')
            ->sum('days');
        
        $totalLeaves = 21; // Default annual leaves
        $availableLeaves = $totalLeaves - $usedLeaves;
        
        return view('leaves.create', compact('availableLeaves', 'totalLeaves'));
    }

    public function store(Request $request)
    {
        $user = auth()->user();
        
        $request->validate([
            'type' => 'required|in:sick,vacation,personal,emergency',
            'start_date' => 'required|date',
            'end_date' => 'required|date|after_or_equal:start_date',
            'reason' => 'required|string|max:1000',
        ]);

        // Calculate days difference
        $startDate = Carbon::parse($request->start_date);
        $endDate = Carbon::parse($request->end_date);
        $days = $startDate->diffInDays($endDate) + 1; // Inclusive of both dates

        // Check available leaves
        $usedLeaves = $user->leaveRequests()
            ->where('status', 'approved')
            ->sum('days');
        
        $totalLeaves = 21;
        $availableLeaves = $totalLeaves - $usedLeaves;
        
        if ($days > $availableLeaves) {
            return back()->with('error', "You only have {$availableLeaves} leaves available. You're requesting {$days} days.");
        }

        // Check for overlapping leaves
        $overlappingLeaves = LeaveRequest::where('employee_id', $user->id)
            ->where('status', '!=', 'rejected')
            ->where(function($query) use ($startDate, $endDate) {
                $query->whereBetween('start_date', [$startDate, $endDate])
                      ->orWhereBetween('end_date', [$startDate, $endDate])
                      ->orWhere(function($q) use ($startDate, $endDate) {
                          $q->where('start_date', '<=', $startDate)
                            ->where('end_date', '>=', $endDate);
                      });
            })
            ->exists();
        
        if ($overlappingLeaves) {
            return back()->with('error', 'You already have a leave request for this period.');
        }

        try {
            DB::beginTransaction();
            
            $leave = LeaveRequest::create([
                'employee_id' => $user->id,
                'type' => $request->type,
                'start_date' => $startDate,
                'end_date' => $endDate,
                'days' => $days,
                'reason' => $request->reason,
                'status' => 'pending',
            ]);
            
            DB::commit();
            
            return redirect()->route('leaves.my-leaves')
                ->with('success', 'Leave request submitted successfully.');
                
        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Failed to submit leave request: ' . $e->getMessage());
        }
    }

    public function myLeaves()
    {
        $user = auth()->user();
        
        $leaves = LeaveRequest::where('employee_id', $user->id)
            ->with(['approvedBy'])
            ->latest()
            ->paginate(15);
            
        // Calculate leave statistics
        $usedLeaves = $user->leaveRequests()
            ->where('status', 'approved')
            ->sum('days');
        
        $totalLeaves = 21;
        $availableLeaves = $totalLeaves - $usedLeaves;
        
        $pendingLeaves = $user->leaveRequests()
            ->where('status', 'pending')
            ->sum('days');
        
        $rejectedLeaves = $user->leaveRequests()
            ->where('status', 'rejected')
            ->sum('days');
        
        $stats = [
            'total' => $totalLeaves,
            'used' => $usedLeaves,
            'available' => $availableLeaves,
            'pending' => $pendingLeaves,
            'rejected' => $rejectedLeaves,
        ];
        
        return view('leaves.my-leaves', compact('leaves', 'stats'));
    }

    public function approve(Request $request, LeaveRequest $leave)
    {
        $this->authorize('approve', $leave);
        
        $request->validate([
            'admin_notes' => 'nullable|string|max:1000',
        ]);
        
        $leave->update([
            'status' => 'approved',
            'approved_by' => auth()->id(),
            'admin_notes' => $request->admin_notes,
        ]);
        
        return back()->with('success', 'Leave request approved successfully.');
    }

    public function reject(Request $request, LeaveRequest $leave)
    {
        $this->authorize('approve', $leave);
        
        $request->validate([
            'admin_notes' => 'required|string|max:1000',
        ]);
        
        $leave->update([
            'status' => 'rejected',
            'approved_by' => auth()->id(),
            'admin_notes' => $request->admin_notes,
        ]);
        
        return back()->with('success', 'Leave request rejected.');
    }

    public function destroy(LeaveRequest $leave)
    {
        $this->authorize('delete', $leave);
        
        if ($leave->status !== 'pending') {
            return back()->with('error', 'Only pending leave requests can be deleted.');
        }
        
        $leave->delete();
        
        return back()->with('success', 'Leave request deleted successfully.');
    }
}