<?php

namespace App\Modules\Dashboard\Repositories;

use App\Modules\Dashboard\DTOs\OperationalSnapshot;
use App\Modules\HR\Attendance\Repositories\AttendanceDashboardRepository;
use App\Modules\HR\Attendance\Repositories\AttendanceExceptionRepository;
use App\Modules\HR\Leave\Models\LeaveRequest;
use App\Modules\HR\Leave\Support\LeaveRequestStatus;
use App\Modules\HR\Shifts\Repositories\ShiftStatisticsRepository;
use Illuminate\Support\Facades\Cache;

class OperationalMetricsRepository
{
    private const CACHE_TTL = 45;

    public function __construct(
        private readonly AttendanceDashboardRepository $attendanceDashboard,
        private readonly ShiftStatisticsRepository $shiftStats,
        private readonly AttendanceExceptionRepository $attendanceExceptions,
    ) {}

    public function snapshot(int $tenantId): OperationalSnapshot
    {
        $key = 'tenant:'.$tenantId.':'.AttendanceExceptionRepository::OPERATIONAL_SNAPSHOT_CACHE_SUFFIX;

        return Cache::remember($key, self::CACHE_TTL, function () use ($tenantId): OperationalSnapshot {
            return $this->buildSnapshot($tenantId);
        });
    }

    private function buildSnapshot(int $tenantId): OperationalSnapshot
    {
        return new OperationalSnapshot(
            pendingLeaveManager: $this->leaveCount($tenantId, LeaveRequestStatus::PENDING),
            pendingLeaveHr: $this->leaveCount($tenantId, LeaveRequestStatus::MANAGER_APPROVED),
            pendingAttendanceExceptions: $this->attendanceExceptions->pendingCountForTenant($tenantId),
            criticalAttendanceExceptions: $this->attendanceExceptions->criticalPendingCountForTenant($tenantId),
            employeesMissingShift: $this->shiftStats->employeesWithoutActiveShiftCount($tenantId),
            lateToday: $this->attendanceDashboard->lateTodayCount($tenantId),
            absentToday: $this->attendanceDashboard->absentTodayCount($tenantId),
        );
    }

    private function leaveCount(int $tenantId, string $status): int
    {
        return LeaveRequest::query()
            ->where('tenant_id', $tenantId)
            ->where('status', $status)
            ->count();
    }
}
