<?php

declare(strict_types=1);

namespace App\Services\SupportCenter;

use App\Exceptions\SupportCenter\SupportCenterException;
use Illuminate\Support\Facades\Log;

/**
 * 站点在线状态心跳（site_no 缺失时跳过，失败不影响页面主流程）。
 */
final class HostSiteOnboardingHeartbeatService
{
    public function __construct(
        private readonly SupportCenterOpenApiTransport $transport,
        private readonly SupportCenterRequestContextBuilder $contextBuilder,
        private readonly HostSiteOnboardingStatusCacheStore $statusCacheStore,
        private readonly SupportCenterAuditLogger $auditLogger,
    ) {}

    public function send(string $message = 'ok'): bool
    {
        $siteNo = $this->resolveSiteNo();

        if ($siteNo === null) {
            Log::info('support_center.site_presence.skipped', [
                'reason' => 'site_no_missing',
            ]);

            return false;
        }

        $payload = array_filter(
            $this->contextBuilder->sitePresenceBody($message, $siteNo),
            static fn (mixed $value): bool => $value !== null && $value !== '',
        );

        try {
            $this->transport->post(
                SupportCenterOpenHostEndpoints::SITE_PRESENCE,
                $payload,
                'site_presence',
            );

            Log::info('support_center.site_presence.sent', [
                'site_no' => $siteNo,
            ]);

            $this->auditLogger->logSitePresenceReported($siteNo);

            return true;
        } catch (SupportCenterException $exception) {
            Log::warning('support_center.site_presence.failed', [
                'site_no' => $siteNo,
                'error_code' => $exception->errorCode(),
                'request_id' => $exception->requestId(),
            ]);

            $this->auditLogger->logSitePresenceFailed($siteNo, $exception);

            return false;
        } catch (\Throwable $exception) {
            Log::warning('support_center.site_presence.failed', [
                'site_no' => $siteNo,
                'exception_class' => $exception::class,
            ]);

            return false;
        }
    }

    private function resolveSiteNo(): ?string
    {
        $configured = config('dberp.support_center.site_no');

        if (is_string($configured) && trim($configured) !== '') {
            return trim($configured);
        }

        $cached = $this->statusCacheStore->get();
        $siteNo = $cached['site_no'] ?? null;

        if (is_string($siteNo) && trim($siteNo) !== '') {
            return trim($siteNo);
        }

        return null;
    }
}
