<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Leave;
use App\Models\LeaveType;
use App\Models\LeaveBalance;
use App\Models\Employee;
use Illuminate\Support\Facades\DB;

class LeaveController extends Controller
{
    public function __construct() { $this->middleware('auth'); }

    public function index(Request $request)
    {
        $user  = auth()->user();
        $query = Leave::with(['employee.user','employee.department','leaveType']);

        // ── Role scoping ───────────────────────────────────────
        if ($user->isEmployee()) {
            // Employees see only their own leaves
            if ($emp = $user->employee) $query->where('employee_id', $emp->id);
            else $query->whereRaw('1=0');
        } elseif ($user->isDeptHead()) {
            // Dept heads see leaves from their department
            $query->whereHas('employee', fn($q) => $q->where('department_id', $user->department_id));
        }
        // President / HR / Admin see all

        // ── Filters ────────────────────────────────────────────
        if ($request->status)        $query->where('status', $request->status);
        if ($request->leave_type_id) $query->where('leave_type_id', $request->leave_type_id);
        if ($request->month) {
            [$year,$mon] = explode('-', $request->month);
            $query->whereYear('date_from',$year)->whereMonth('date_from',$mon);
        }
        if ($request->search && !$user->isEmployee()) {
            $s = $request->search;
            $query->where(fn($q) =>
                $q->where('leave_number','like',"%$s%")
                  ->orWhereHas('employee', fn($e) =>
                      $e->where('first_name','like',"%$s%")->orWhere('last_name','like',"%$s%")
                  )
            );
        }

        // ── Counts ─────────────────────────────────────────────
        $countBase = Leave::when($user->isEmployee() && $user->employee,
                fn($q) => $q->where('employee_id', $user->employee->id))
            ->when($user->isDeptHead(),
                fn($q) => $q->whereHas('employee', fn($e) => $e->where('department_id', $user->department_id)));

        $counts = [
            'pending'       => (clone $countBase)->where('status','pending')->count(),
            'dept_approved' => (clone $countBase)->where('status','dept_approved')->count(),
            'hr_approved'   => (clone $countBase)->where('status','hr_approved')->count(),
            'approved'      => (clone $countBase)->where('status','approved')->count(),
            'rejected'      => (clone $countBase)->where('status','rejected')->count(),
        ];

        $leaves     = $query->latest()->paginate(20)->withQueryString();
        $leaveTypes = LeaveType::where('is_active',true)->get();

        return view('leaves.index', compact('leaves','counts','leaveTypes'));
    }

    public function create()
    {
        $leaveTypes = LeaveType::where('is_active',true)->get();
        $employee   = auth()->user()->employee;
        $employees  = auth()->user()->isHrOrAdmin()
            ? Employee::with('user')->where('status','active')->get()
            : null;
        return view('leaves.create', compact('leaveTypes','employee','employees'));
    }

    public function store(Request $request)
    {
        $request->validate([
            'leave_type_id' => 'required|exists:leave_types,id',
            'date_from'     => 'required|date',
            'date_to'       => 'required|date|after_or_equal:date_from',
        ]);

        // Determine employee_id
        $employeeId = auth()->user()->isHrOrAdmin() && $request->employee_id
            ? $request->employee_id
            : auth()->user()->employee?->id;

        abort_if(!$employeeId, 422, 'No employee profile found.');

        // Calculate working days
        $from = \Carbon\Carbon::parse($request->date_from);
        $to   = \Carbon\Carbon::parse($request->date_to);
        $days = 0;
        for ($d = $from->copy(); $d->lte($to); $d->addDay()) {
            if (!$d->isWeekend()) $days++;
        }

        Leave::create([
            'employee_id'       => $employeeId,
            'leave_type_id'     => $request->leave_type_id,
            'date_from'         => $request->date_from,
            'date_to'           => $request->date_to,
            'total_days'        => $days,
            'reason'            => $request->reason,
            'forwarding_address'=> $request->forwarding_address,
            'duty_arrangement'  => $request->duty_arrangement,
            'duration_weeks'    => $request->duration_weeks,
            'duration_months'   => $request->duration_months,
            'status'            => 'pending',
        ]);

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

    public function show(Leave $leave)
    {
        $user = auth()->user();
        if ($user->isEmployee()) {
            abort_if($user->employee?->id !== $leave->employee_id, 403);
        }
        $leave->load(['employee.user','employee.department','leaveType',
                      'deptHead','hrApprover','president']);
        return view('leaves.show', compact('leave'));
    }

    public function approveDept(Leave $leave)
    {
        abort_if(!auth()->user()->isDeptHead() && !auth()->user()->isHrOrAdmin(), 403);
        abort_if($leave->status !== 'pending', 422, 'Leave is not in pending status.');
        $leave->update(['status'=>'dept_approved','dept_approved_at'=>now(),'dept_head_id'=>auth()->id()]);
        return back()->with('success','Department approval granted.');
    }

    public function approveHR(Leave $leave)
    {
        abort_if(!auth()->user()->isHrOrAdmin(), 403);
        abort_if($leave->status !== 'dept_approved', 422, 'Leave has not been dept-approved.');
        $leave->update(['status'=>'hr_approved','hr_approved_at'=>now(),'hr_approver_id'=>auth()->id()]);
        return back()->with('success','HR approval granted.');
    }

    public function approvePresident(Leave $leave)
    {
        abort_if(!auth()->user()->isPresident() && !auth()->user()->isSuperAdmin(), 403);
        abort_if($leave->status !== 'hr_approved', 422, 'Leave has not been HR-approved.');
        $leave->update(['status'=>'approved','president_approved_at'=>now(),'president_approver_id'=>auth()->id()]);

        // Deduct from leave balance
        $bal = LeaveBalance::firstOrCreate(
            ['employee_id' => $leave->employee_id, 'leave_type_id' => $leave->leave_type_id, 'year' => now()->year],
            ['entitled_days' => LeaveType::find($leave->leave_type_id)?->days_allowed_per_year ?? 0, 'taken_days' => 0]
        );
        $bal->increment('taken_days', $leave->total_days);

        return back()->with('success','Final approval granted. Leave is now approved.');
    }

    public function reject(Request $request, Leave $leave)
    {
        abort_if(
            !auth()->user()->isDeptHead() &&
            !auth()->user()->isHrOrAdmin() &&
            !auth()->user()->isPresident(),
            403
        );
        $leave->update(['status'=>'rejected','rejection_reason'=>$request->reason]);
        return back()->with('success','Leave request rejected.');
    }

    public function cancel(Leave $leave)
    {
        abort_if(auth()->user()->employee?->id !== $leave->employee_id, 403);
        abort_if(!in_array($leave->status,['pending','dept_approved']), 422, 'Cannot cancel at this stage.');
        $leave->update(['status'=>'cancelled']);
        return back()->with('success','Leave request cancelled.');
    }
}
