<?php

declare(strict_types=1);

namespace App\Services\Employee;

use App\DTOs\EmployeeSummaryDto;
use App\Enums\ApprovalStatus;
use App\Enums\VacationType;
use App\Models\Employee;
use App\Services\Vacation\VacationBalanceService;
use Illuminate\Database\Eloquent\Builder;

class EmployeeStatisticsService
{
    public function __construct(
        private readonly VacationBalanceService $vacationBalanceService,
    ) {}

    /**
     * @param  Builder<Employee>  $query
     * @return Builder<Employee>
     */
    public function applyTableAggregates(Builder $query, ?int $year = null): Builder
    {
        $year ??= (int) now()->year;

        return $query
            ->with(['department', 'position'])
            ->withCount(['sickLeaves', 'unpaidLeaves', 'disciplinaryReports', 'explanations', 'gifts'])
            ->withSum('bonuses', 'amount')
            ->withSum(['vacations as annual_vacation_days_taken' => fn (Builder $vacationQuery): Builder => $vacationQuery
                ->where('type', VacationType::Annual)
                ->where('status', ApprovalStatus::Approved)
                ->whereYear('start_date', $year),
            ], 'days');
    }

    public function summary(Employee $employee): EmployeeSummaryDto
    {
        return new EmployeeSummaryDto(
            vacationTaken: $this->vacationBalanceService->takenAnnualDays($employee),
            vacationRemaining: $this->vacationBalanceService->remainingAnnualDays($employee),
            sickLeaveCount: $employee->sickLeaves()->count(),
            reportsCount: $employee->disciplinaryReports()->count(),
            bonusesTotal: (float) $employee->bonuses()->sum('amount'),
            giftsCount: $employee->gifts()->count(),
            upcomingLeave: $employee->vacations()
                ->where('status', ApprovalStatus::Approved)
                ->where('start_date', '>=', now()->toDateString())
                ->orderBy('start_date')
                ->get(),
        );
    }
}
