<?php

namespace App\Modules\HR\Attendance\Services;

use App\Modules\Admin\Tenancy\Models\Tenant;
use App\Modules\HR\Attendance\Repositories\AttendanceRecordRepository;
use App\Modules\HR\Employees\Models\Employee;
use Carbon\CarbonImmutable;

class AttendanceMonthlyReportService
{
    public function __construct(
        private readonly AttendanceRecordRepository $records,
        private readonly AttendanceHistoryWindowService $historyWindow,
        private readonly AttendanceWorkingDayResolver $workingDays,
    ) {}

    /**
     * @return array{
     *   present_days: int,
     *   absent_days: int,
     *   late_days: int,
     *   leave_days: int,
     *   overtime_hours: float,
     *   expected_working_days: int,
     *   calendar_non_working_days: int
     * }
     */
    public function employeeMonthSummary(Tenant $tenant, int $employeeId, CarbonImmutable $month): array
    {
        $floor = $this->historyWindow->earliestReportDate($tenant);
        $start = $month->startOfMonth();
        if ($floor !== null && $start->lt($floor)) {
            $start = $floor;
        }
        $base = $this->records->monthlyAggregatesForEmployee(
            (int) $tenant->id,
            $employeeId,
            $start,
        );
        $employee = Employee::query()
            ->where('tenant_id', $tenant->id)
            ->whereKey($employeeId)
            ->first();
        $expected = 0;
        $nonWorking = 0;
        if ($employee !== null) {
            $cursor = $start->startOfDay();
            $end = $month->endOfMonth()->startOfDay();
            while ($cursor->lte($end)) {
                if ($this->workingDays->isWorkingDay($employee, $cursor)) {
                    $expected++;
                } else {
                    $nonWorking++;
                }
                $cursor = $cursor->addDay();
            }
        }

        return array_merge($base, [
            'expected_working_days' => $expected,
            'calendar_non_working_days' => $nonWorking,
        ]);
    }
}
