<?php

namespace App\Modules\HR\Contracts\Repositories;

use App\Modules\HR\Contracts\Models\EmploymentContract;
use App\Support\Lists\ListQuery;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;

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

    public function findForTenant(int $tenantId, int $id): ?EmploymentContract
    {
        return EmploymentContract::query()
            ->where('tenant_id', $tenantId)
            ->whereKey($id)
            ->first();
    }

    public function paginateForTenant(int $tenantId, int $perPage = 20): LengthAwarePaginator
    {
        return EmploymentContract::query()
            ->where('tenant_id', $tenantId)
            ->with(['employee', 'template'])
            ->orderByDesc('start_date')
            ->paginate($perPage);
    }

    public function paginateForIndex(int $tenantId, Request $request): LengthAwarePaginator
    {
        $query = EmploymentContract::query()
            ->where('tenant_id', $tenantId)
            ->with(['employee', 'template']);

        $term = trim((string) $request->input('q'));
        if ($term !== '') {
            $query->whereHas('employee', fn ($q) => $q->where('full_name', 'like', '%'.$term.'%'));
        }
        ListQuery::applyEquals($query, 'employee_id', $request->input('employee_id'));
        ListQuery::applyEquals($query, 'contract_type', $request->input('contract_type'));
        ListQuery::applyEquals($query, 'status', $request->input('status'));
        ListQuery::applyDateFrom($query, 'start_date', $request->input('start_date_from'));
        ListQuery::applyDateTo($query, 'start_date', $request->input('start_date_to'));
        ListQuery::applySort(
            $query,
            $request->input('sort'),
            $request->input('dir'),
            [
                'start_date' => 'start_date',
                'end_date' => 'end_date',
                'status' => 'status',
            ],
            'start_date',
            'desc',
        );

        return ListQuery::paginate($query, $request);
    }

    public function expiringWithinDays(int $tenantId, int $days): Collection
    {
        return EmploymentContract::query()
            ->where('tenant_id', $tenantId)
            ->where('status', 'active')
            ->whereBetween('end_date', [today(), today()->addDays($days)])
            ->with('employee')
            ->orderBy('end_date')
            ->get();
    }

    /**
     * @param  array<string, mixed>  $data
     */
    public function update(EmploymentContract $contract, array $data): EmploymentContract
    {
        $contract->update($data);

        return $contract->fresh(['employee']);
    }
}
