<?php

namespace App\Modules\Payroll\Repositories;

use App\Modules\Payroll\Models\PayrollEmployeeSnapshot;
use App\Modules\Payroll\Support\PayrollPeriodStatus;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;

class PayrollEmployeeSnapshotRepository
{
    public function deleteForPeriod(int $tenantId, int $payrollPeriodId): int
    {
        return PayrollEmployeeSnapshot::query()
            ->where('tenant_id', $tenantId)
            ->where('payroll_period_id', $payrollPeriodId)
            ->delete();
    }

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

    public function countForPeriod(int $tenantId, int $payrollPeriodId): int
    {
        return PayrollEmployeeSnapshot::query()
            ->where('tenant_id', $tenantId)
            ->where('payroll_period_id', $payrollPeriodId)
            ->count();
    }

    public function paginateForPeriod(int $tenantId, int $payrollPeriodId, int $perPage = 50): LengthAwarePaginator
    {
        return PayrollEmployeeSnapshot::query()
            ->where('tenant_id', $tenantId)
            ->where('payroll_period_id', $payrollPeriodId)
            ->with(['employee:id,full_name,employee_code'])
            ->orderBy('employee_id')
            ->paginate($perPage)
            ->withQueryString();
    }

    public function paginateFinalizedForEmployee(int $tenantId, int $employeeId, int $perPage = 20): LengthAwarePaginator
    {
        return PayrollEmployeeSnapshot::query()
            ->where('tenant_id', $tenantId)
            ->where('employee_id', $employeeId)
            ->whereHas('period', fn ($q) => $q->where('status', PayrollPeriodStatus::FINALIZED))
            ->with([
                'period:id,tenant_id,name,start_date,end_date,status,finalized_at',
            ])
            ->orderByDesc('generated_at')
            ->paginate($perPage)
            ->withQueryString();
    }

    public function findFinalizedForTenantEmployee(int $tenantId, int $employeeId, int $snapshotId): ?PayrollEmployeeSnapshot
    {
        return PayrollEmployeeSnapshot::query()
            ->where('tenant_id', $tenantId)
            ->where('employee_id', $employeeId)
            ->whereKey($snapshotId)
            ->whereHas('period', fn ($q) => $q->where('status', PayrollPeriodStatus::FINALIZED))
            ->with([
                'employee:id,tenant_id,full_name,employee_code',
                'period:id,tenant_id,name,start_date,end_date,status,finalized_at',
            ])
            ->first();
    }

    public function findForTenant(int $tenantId, int $snapshotId): ?PayrollEmployeeSnapshot
    {
        return PayrollEmployeeSnapshot::query()
            ->where('tenant_id', $tenantId)
            ->whereKey($snapshotId)
            ->with([
                'employee:id,tenant_id,full_name,employee_code',
                'period:id,tenant_id,name,start_date,end_date,status,finalized_at',
            ])
            ->first();
    }
}
