HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/ai.naniguide.com/app/Services/Customer/VerificationServerService.php
<?php

namespace App\Services\Customer;

use App\Dto\Refactor\VerificationServer\VerificationServerSidebarStatsDto;
use App\Model\Customer;
use App\Model\EmailVerificationServer;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;

/**
 * Read aggregator for the customer-side rich-redesigned "Email Verification
 * Servers" page. Owns: stats meta, filtered list, sidebar widgets.
 */
class VerificationServerService
{
    /**
     * Header inline-meta (used by mc-banner-meta).
     *
     * @return array{total:int,active:int,inactive:int,vendors:int}
     */
    public function headerMeta(Customer $customer): array
    {
        $base = EmailVerificationServer::query()->where('customer_id', $customer->id);

        $total = (clone $base)->count();
        $active = (clone $base)->where('status', EmailVerificationServer::STATUS_ACTIVE)->count();
        $inactive = max(0, $total - $active);
        $vendors = (clone $base)->distinct('type')->count('type');

        return [
            'total' => $total,
            'active' => $active,
            'inactive' => $inactive,
            'vendors' => $vendors,
        ];
    }

    public function list(
        Customer $customer,
        ?string $keyword = null,
        ?string $status = null,
        string $sortBy = 'created_at',
        string $sortDir = 'desc',
        int $perPage = 25,
    ): LengthAwarePaginator {
        $query = EmailVerificationServer::query()->where('customer_id', $customer->id);

        if ($keyword !== null && $keyword !== '') {
            $query->where('name', 'like', '%' . $keyword . '%');
        }

        if ($status === 'active') {
            $query->where('status', EmailVerificationServer::STATUS_ACTIVE);
        } elseif ($status === 'inactive') {
            $query->where(function ($q) {
                $q->where('status', '!=', EmailVerificationServer::STATUS_ACTIVE)
                    ->orWhereNull('status');
            });
        }

        $allowedSorts = ['created_at', 'name', 'type', 'status'];
        if (! in_array($sortBy, $allowedSorts, true)) {
            $sortBy = 'created_at';
        }
        $sortDir = strtolower($sortDir) === 'asc' ? 'asc' : 'desc';

        return $query->orderBy($sortBy, $sortDir)->paginate($perPage);
    }

    public function sidebarStats(Customer $customer): VerificationServerSidebarStatsDto
    {
        return new VerificationServerSidebarStatsDto(
            headerMeta: $this->headerMeta($customer),
            coverage: $this->coverage($customer),
            combinedCapacity: $this->combinedCapacity($customer),
        );
    }

    /**
     * Vendor catalog — cross-reference connected types with config('verification.services').
     *
     * @return array{used_vendor_ids:list<string>,catalog:list<array{id:string,name:string,connected:bool,count:int}>}
     */
    private function coverage(Customer $customer): array
    {
        $rows = \Illuminate\Support\Facades\DB::table('email_verification_servers')
            ->where('customer_id', $customer->id)
            ->selectRaw('type, COUNT(*) as cnt')
            ->groupBy('type')
            ->pluck('cnt', 'type')
            ->all();

        $services = (array) config('verification.services', []);
        $catalog = [];
        $usedIds = array_keys($rows);

        foreach ($services as $service) {
            $id = (string) ($service['id'] ?? '');
            if ($id === '') {
                continue;
            }
            $catalog[] = [
                'id' => $id,
                'name' => (string) ($service['name'] ?? $id),
                'connected' => isset($rows[$id]),
                'count' => (int) ($rows[$id] ?? 0),
            ];
        }

        // Stable sort: connected first, then by name.
        usort($catalog, function ($a, $b) {
            if ($a['connected'] !== $b['connected']) {
                return $a['connected'] ? -1 : 1;
            }
            return strcasecmp($a['name'], $b['name']);
        });

        return [
            'used_vendor_ids' => $usedIds,
            'catalog' => $catalog,
        ];
    }

    /**
     * Combined throughput across this customer's active verification servers.
     * Best-effort — sums options.limit_value normalised to per-hour where possible.
     *
     * @return array{value:int,unit:string,base:int,formatted:string}
     */
    private function combinedCapacity(Customer $customer): array
    {
        $servers = EmailVerificationServer::query()
            ->where('customer_id', $customer->id)
            ->where('status', EmailVerificationServer::STATUS_ACTIVE)
            ->get(['options']);

        $perHour = 0;
        $countedAny = false;

        foreach ($servers as $server) {
            $opts = $server->options;
            if (is_string($opts)) {
                $opts = json_decode($opts, true) ?: [];
            } elseif (! is_array($opts)) {
                $opts = [];
            }

            $value = (int) ($opts['limit_value'] ?? 0);
            $base = max(1, (int) ($opts['limit_base'] ?? 1));
            $unit = (string) ($opts['limit_unit'] ?? 'hour');

            if ($value <= 0) {
                continue;
            }

            $perBase = $value / $base;

            $perHourEquivalent = match ($unit) {
                'minute' => (int) round($perBase * 60),
                'hour' => (int) round($perBase),
                'day' => (int) round($perBase / 24),
                default => 0,
            };

            if ($perHourEquivalent > 0) {
                $perHour += $perHourEquivalent;
                $countedAny = true;
            }
        }

        return [
            'value' => $perHour,
            'unit' => 'hour',
            'base' => 1,
            'formatted' => $countedAny
                ? number_format($perHour) . '/hour'
                : '—',
        ];
    }
}