<?php

namespace App\Modules\HR\EmployeeSelfService\Services;

use App\Modules\Admin\Tenancy\Models\Tenant;
use App\Modules\HR\Attendance\Repositories\AttendanceRecordRepository;
use App\Modules\HR\Attendance\Services\AttendanceHistoryWindowService;
use App\Modules\HR\Employees\Models\Employee;
use App\Modules\HR\Employees\Services\EmployeeHierarchyService;
use App\Modules\HR\EmployeeSelfService\Requests\MeAttendanceIndexRequest;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Validation\ValidationException;

class MeTeamAttendanceService
{
    public function __construct(
        private readonly EmployeeHierarchyService $hierarchy,
        private readonly AttendanceRecordRepository $records,
        private readonly AttendanceHistoryWindowService $historyWindow,
    ) {}

    /**
     * @return array{
     *     paginator: LengthAwarePaginator,
     *     from: string,
     *     to: string,
     *     employeeOptions: array<int, string>,
     *     selectedEmployeeId: int|null
     * }
     */
    public function page(Tenant $tenant, Employee $manager, MeAttendanceIndexRequest $request): array
    {
        $subordinateIds = $this->hierarchy->subordinateIds((int) $tenant->id, (int) $manager->id);
        abort_if($subordinateIds === [], 403);

        $selected = $this->selectedEmployeeId($request, $subordinateIds);
        $scopeIds = $selected !== null ? [$selected] : $subordinateIds;
        $floor = $this->historyWindow->earliestReportDate($tenant);
        $from = $request->fromOrDefault($floor?->toDateString() ?? now()->subMonth()->toDateString());
        $to = $request->toOrDefault(now()->toDateString());

        return [
            'paginator' => $this->records->paginateForEmployees(
                (int) $tenant->id,
                $scopeIds,
                $from,
                $to,
            ),
            'from' => $from,
            'to' => $to,
            'employeeOptions' => $this->hierarchy->subordinateOptions((int) $tenant->id, (int) $manager->id),
            'selectedEmployeeId' => $selected,
        ];
    }

    /**
     * @param  list<int>  $allowedIds
     */
    private function selectedEmployeeId(MeAttendanceIndexRequest $request, array $allowedIds): ?int
    {
        $raw = $request->input('employee_id');
        if ($raw === null || $raw === '') {
            return null;
        }

        $id = (int) $raw;
        if (! in_array($id, $allowedIds, true)) {
            throw ValidationException::withMessages([
                'employee_id' => [__('me.team_attendance.invalid_employee')],
            ]);
        }

        return $id;
    }
}
