<?php

namespace App\Modules\HR\Shifts\Repositories;

use App\Modules\HR\Shifts\Models\EmployeeShiftAssignment;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Collection;

class EmployeeShiftAssignmentRepository
{
    public function coveringInstant(int $tenantId, int $employeeId, CarbonImmutable $instant): ?EmployeeShiftAssignment
    {
        return EmployeeShiftAssignment::query()
            ->where('tenant_id', $tenantId)
            ->where('employee_id', $employeeId)
            ->where('starts_at', '<=', $instant)
            ->where(function ($q) use ($instant): void {
                $q->whereNull('ends_at')->orWhere('ends_at', '>=', $instant);
            })
            ->with('shift')
            ->orderByDesc('starts_at')
            ->first();
    }

    public function coveringDate(int $tenantId, int $employeeId, CarbonImmutable $day): ?EmployeeShiftAssignment
    {
        $start = $day->startOfDay();
        $end = $day->endOfDay();

        return EmployeeShiftAssignment::query()
            ->where('tenant_id', $tenantId)
            ->where('employee_id', $employeeId)
            ->where('starts_at', '<=', $end)
            ->where(function ($q) use ($start): void {
                $q->whereNull('ends_at')->orWhere('ends_at', '>=', $start);
            })
            ->with('shift')
            ->orderByDesc('starts_at')
            ->first();
    }

    /**
     * @return Collection<int, EmployeeShiftAssignment>
     */
    public function activeRowsForEmployee(int $tenantId, int $employeeId): Collection
    {
        return EmployeeShiftAssignment::query()
            ->where('tenant_id', $tenantId)
            ->where('employee_id', $employeeId)
            ->where('is_active', true)
            ->get();
    }

    /**
     * @param  array<string, mixed>  $data
     */
    public function create(array $data): EmployeeShiftAssignment
    {
        return EmployeeShiftAssignment::query()->create($data);
    }

    public function closeAssignment(EmployeeShiftAssignment $row, CarbonImmutable $endsAt): void
    {
        $row->forceFill([
            'ends_at' => $endsAt,
            'is_active' => false,
        ])->save();
    }
}
