<?php

namespace App\Services\Leave;

use App\Models\LeaveType;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class LeaveEligibilityService
{
    public function __construct(
        private readonly LeaveLedgerService $ledger
    ) {}

    public function eligibleUsersQuery(LeaveType $leaveType): Builder
    {
        $companyId = Auth::user()?->company_id ?? $leaveType->company_id;

        $base = User::query()->forActiveDirectory();
        if ($companyId) {
            $base->where('company_id', $companyId);
        }

        if ($leaveType->apply_to_all) {
            return $base;
        }

        $userIds = collect();

        if ($companyId) {
            $direct = DB::table('leave_type_users')
                ->where('company_id', $companyId)
                ->where('leave_type_id', $leaveType->id)
                ->pluck('user_id');

            $deptUserIds = DB::table('users')
                ->where('company_id', $companyId)
                ->whereIn('department_id', DB::table('leave_type_departments')
                    ->where('company_id', $companyId)
                    ->where('leave_type_id', $leaveType->id)
                    ->pluck('department_id'))
                ->pluck('id');

            $roleUserIds = DB::table('role_user')
                ->whereIn('role_id', DB::table('leave_type_roles')
                    ->where('company_id', $companyId)
                    ->where('leave_type_id', $leaveType->id)
                    ->pluck('role_id'))
                ->pluck('user_id');

            $userIds = $userIds->merge($direct)->merge($deptUserIds)->merge($roleUserIds)->unique()->values();
        } else {
            $direct = DB::table('leave_type_users')
                ->where('leave_type_id', $leaveType->id)
                ->pluck('user_id');

            $deptUserIds = DB::table('users')
                ->whereIn('department_id', DB::table('leave_type_departments')
                    ->where('leave_type_id', $leaveType->id)
                    ->pluck('department_id'))
                ->pluck('id');

            $roleUserIds = DB::table('role_user')
                ->whereIn('role_id', DB::table('leave_type_roles')
                    ->where('leave_type_id', $leaveType->id)
                    ->pluck('role_id'))
                ->pluck('user_id');

            $userIds = $userIds->merge($direct)->merge($deptUserIds)->merge($roleUserIds)->unique()->values();
        }

        if ($userIds->isEmpty()) {
            return $base->whereRaw('1 = 0');
        }

        return $base->whereIn('id', $userIds->all());
    }

    public function countEligibleUsers(LeaveType $leaveType): int
    {
        return $this->eligibleUsersQuery($leaveType)->count();
    }

    public function availableLeaveDays(User $user, LeaveType $leaveType): float
    {
        return $this->ledger->availableLeaveDays($user, $leaveType);
    }
    
}

