<?php

namespace App\Http\Controllers;

use App\Models\Company;
use App\Models\Staff;
use App\Models\StaffLeaveAllocation;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Inertia\Inertia;

class LeaveAllocationController extends Controller
{
    private const LEAVE_TYPES = ['Annual Leave', 'Medical Leave', 'Emergency Leave', 'Maternity Leave', 'Paternity Leave', 'Unpaid Leave'];

    public function index(Request $request)
    {
        $user      = Auth::user();
        $year      = (int) $request->get('year', now()->year);
        $leaveType = $request->get('leave_type', 'Annual Leave');
        $companyId = $request->get('company_id');

        $query = Staff::with('company')->orderBy('full_name');

        if ($user->role === 'company_hr') {
            $query->where('company_id', $user->company_id);
        } elseif ($companyId) {
            $query->where('company_id', $companyId);
        }

        $staff = $query->get();

        $allocations = StaffLeaveAllocation::where('year', $year)
            ->where('leave_type', $leaveType)
            ->whereIn('staff_id', $staff->pluck('id'))
            ->get()
            ->keyBy('staff_id');

        $withAlloc    = $allocations->count();
        $withoutAlloc = $staff->count() - $withAlloc;
        $avgDays      = $withAlloc > 0 ? round($allocations->avg('days_allocated'), 1) : 0;

        $companies = $user->role === 'super_admin'
            ? Company::orderBy('name')->get(['id', 'name'])
            : collect();

        return Inertia::render('LeaveAllocation/Index', [
            'staff'       => $staff,
            'allocations' => $allocations->values()->keyBy('staff_id'),
            'companies'   => $companies,
            'leaveTypes'  => self::LEAVE_TYPES,
            'filters'     => ['year' => $year, 'leave_type' => $leaveType, 'company_id' => $companyId],
            'stats'       => [
                'total'        => $staff->count(),
                'with_alloc'   => $withAlloc,
                'without_alloc'=> $withoutAlloc,
                'avg_days'     => $avgDays,
            ],
            'years' => range(now()->year + 1, now()->year - 3),
        ]);
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'staff_id'             => 'required|integer|exists:staff,id',
            'leave_type'           => 'required|string',
            'year'                 => 'required|integer',
            'days_allocated'       => 'required|numeric|min:0',
            'days_taken'           => 'nullable|numeric|min:0',
            'days_carried_forward' => 'nullable|numeric|min:0',
        ]);

        $allocated = (float) $data['days_allocated'];
        $taken     = (float) ($data['days_taken'] ?? 0);
        $carried   = (float) ($data['days_carried_forward'] ?? 0);

        StaffLeaveAllocation::updateOrCreate(
            [
                'staff_id'   => $data['staff_id'],
                'leave_type' => $data['leave_type'],
                'year'       => $data['year'],
            ],
            [
                'days_allocated'       => $allocated,
                'days_taken'           => $taken,
                'days_carried_forward' => $carried,
                'days_balance'         => $allocated + $carried - $taken,
            ]
        );

        return back()->with('success', 'Leave allocation saved.');
    }

    public function bulk(Request $request)
    {
        $data = $request->validate([
            'staff_ids'            => 'required|array',
            'staff_ids.*'          => 'integer|exists:staff,id',
            'leave_type'           => 'required|string',
            'year'                 => 'required|integer',
            'days_allocated'       => 'required|numeric|min:0',
        ]);

        foreach ($data['staff_ids'] as $staffId) {
            StaffLeaveAllocation::updateOrCreate(
                ['staff_id' => $staffId, 'leave_type' => $data['leave_type'], 'year' => $data['year']],
                ['days_allocated' => $data['days_allocated'], 'days_balance' => $data['days_allocated']]
            );
        }

        return back()->with('success', count($data['staff_ids']) . ' allocations saved.');
    }
}
