<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

namespace App\Support;

use App\Enums\SupportCenter\SiteConnectionStatus;
use App\Services\SupportCenter\HostInstanceIdentityPresenter;
use App\Services\SupportCenter\HostInstanceIdentityService;
use App\Services\SupportCenter\HostSiteConnectionStatusResolver;
use App\Services\SupportCenter\HostSiteOnboardingLastAttemptStore;
use App\Services\SupportCenter\HostSiteOnboardingStatusCacheStore;
use App\Services\SupportCenter\HostSiteOnboardingStatusPresenter;
use App\Services\SupportCenter\SupportCenterConnectivityGuard;
use App\Services\SupportCenter\SupportCenterPostInstallCheckService;
use App\Services\SupportCenter\SupportCenterRuntimeConfig;
use Illuminate\Support\Carbon;

/**
 * 系统接入中心页只读展示数据（不含密钥与内部枚举）。
 */
final class SiteOnboardingCenterDisplay
{
    public function __construct(
        private readonly HostSiteConnectionStatusResolver $connectionStatusResolver,
        private readonly SupportCenterConnectivityGuard $connectivityGuard,
        private readonly SupportCenterRuntimeConfig $runtimeConfig,
        private readonly HostInstanceIdentityService $instanceIdentityService,
        private readonly HostInstanceIdentityPresenter $instanceIdentityPresenter,
        private readonly HostSiteOnboardingStatusCacheStore $statusCacheStore,
        private readonly HostSiteOnboardingLastAttemptStore $lastAttemptStore,
        private readonly HostSiteOnboardingStatusPresenter $statusPresenter,
        private readonly SupportCenterPostInstallCheckService $postInstallCheckService,
        private readonly DberpProductVersion $productVersion,
    ) {}

    /**
     * 安装包官方接入能力说明（面向业务用户，不含环境变量名与凭证）。
     */
    public function packageReadinessMessage(): string
    {
        return $this->postInstallCheckService->packageReadinessMessage();
    }

    public function packageReadinessReady(): bool
    {
        return $this->postInstallCheckService->isPackageReady();
    }

    public function localReadinessLabel(): string
    {
        return match ($this->connectionStatusResolver->resolve()) {
            SiteConnectionStatus::Ready => (string) __('dberp.site_onboarding.local_readiness.ready'),
            SiteConnectionStatus::Pending => (string) __('dberp.site_onboarding.local_readiness.pending'),
            SiteConnectionStatus::NotConnected => (string) __('dberp.site_onboarding.local_readiness.not_connected'),
        };
    }

    public function localReadinessBadgeColor(): string
    {
        return match ($this->connectionStatusResolver->resolve()) {
            SiteConnectionStatus::Ready => 'success',
            SiteConnectionStatus::Pending => 'warning',
            SiteConnectionStatus::NotConnected => 'gray',
        };
    }

    /**
     * 面向业务用户的连接说明（不含环境变量名与运维命令）。
     */
    public function localReadinessGuidance(): string
    {
        return match ($this->connectionStatusResolver->resolve()) {
            SiteConnectionStatus::Ready => (string) __('dberp.site_onboarding.local_readiness.guidance.ready'),
            SiteConnectionStatus::Pending => (string) __('dberp.site_onboarding.local_readiness.guidance.pending'),
            SiteConnectionStatus::NotConnected => (string) __('dberp.site_onboarding.local_readiness.guidance.not_connected'),
        };
    }

    public function normalizedSupportCenterBaseUrl(): ?string
    {
        return $this->runtimeConfig->normalizedBaseUrl();
    }

    /**
     * 技术支持排查用结构化信息（勿在普通业务界面直接展示）。
     *
     * @return array<string, mixed>
     */
    public function technicalDiagnostics(): array
    {
        return $this->runtimeConfig->technicalDiagnostics(
            $this->connectivityGuard->blockingReasonCode(),
        );
    }

    public function productLabel(): string
    {
        return 'DBErp';
    }

    public function ensureInstanceIdentityProvisioned(): void
    {
        $this->instanceIdentityService->ensureProvisioned();
    }

    public function siteIdentityLabel(): string
    {
        return $this->instanceIdentityPresenter->siteIdentityLabel();
    }

    public function officialAccessLabel(): string
    {
        return $this->instanceIdentityPresenter->officialAccessLabel();
    }

    public function officialAccessBadgeColor(): string
    {
        return $this->instanceIdentityPresenter->officialAccessBadgeColor();
    }

    public function nextStepLabel(): string
    {
        return $this->instanceIdentityPresenter->nextStepLabel();
    }

    public function instanceId(): string
    {
        return $this->instanceIdentityService->instanceId();
    }

    public function hostVersion(): string
    {
        return $this->productVersion->displayVersion();
    }

    public function officialSiteNo(): ?string
    {
        $cached = $this->statusCacheStore->get();
        $siteNo = $cached['site_no'] ?? null;

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

        $configured = config('dberp.support_center.site_no');

        return is_string($configured) && trim($configured) !== '' ? trim($configured) : null;
    }

    public function bindingStatusLabel(): string
    {
        $cached = $this->statusCacheStore->get();

        if ($cached === null) {
            return (string) __('dberp.site_onboarding.status_labels.no_active_site_binding');
        }

        $label = $cached['binding_status_label'] ?? null;

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

        $status = $cached['binding_status'] ?? null;

        return $this->statusPresenter->label(is_string($status) ? $status : null);
    }

    public function bindingStatusBadgeColor(): string
    {
        $cached = $this->statusCacheStore->get();
        $status = is_array($cached) ? ($cached['binding_status'] ?? null) : null;

        return $this->statusPresenter->badgeColor(is_string($status) ? $status : null);
    }

    public function isBound(): bool
    {
        $cached = $this->statusCacheStore->get();

        if (is_array($cached) && array_key_exists('is_bound', $cached)) {
            return (bool) $cached['is_bound'];
        }

        if (! is_array($cached)) {
            return false;
        }

        return $this->statusPresenter->resolveIsBoundFromData($cached);
    }

    public function lastStatusFetchedAt(): ?string
    {
        $cached = $this->statusCacheStore->get();
        $fetchedAt = $cached['fetched_at'] ?? null;

        return $this->formatStoredUtcTimestamp(is_string($fetchedAt) ? $fetchedAt : null);
    }

    public function lastAttemptSummary(): ?string
    {
        $attempt = $this->lastAttemptStore->get();

        if ($attempt === null) {
            return null;
        }

        $attemptedAt = $attempt['attempted_at'] ?? null;
        $success = (bool) ($attempt['success'] ?? false);

        $formattedTime = $this->formatStoredUtcTimestamp(is_string($attemptedAt) ? $attemptedAt : null);

        if ($formattedTime === null) {
            return null;
        }

        if ($success) {
            return (string) __('dberp.site_onboarding.last_attempt.success', ['time' => $formattedTime]);
        }

        $message = $attempt['message'] ?? null;

        if (is_string($message) && trim($message) !== '') {
            return (string) __('dberp.site_onboarding.last_attempt.failed_with_message', [
                'time' => $formattedTime,
                'message' => trim($message),
            ]);
        }

        return (string) __('dberp.site_onboarding.last_attempt.failed', ['time' => $formattedTime]);
    }

    private function formatStoredUtcTimestamp(?string $value): ?string
    {
        if ($value === null || trim($value) === '') {
            return null;
        }

        try {
            return Carbon::parse($value)
                ->timezone(DberpSystemProfileSettings::displayTimezone())
                ->format('Y-m-d H:i');
        } catch (\Throwable) {
            return trim($value);
        }
    }

    public function hasSiteNoForHeartbeat(): bool
    {
        return filled($this->officialSiteNo());
    }

    /**
     * 接入成功且安装包已就绪时，安装包说明对业务用户已无指引价值。
     */
    public function shouldShowPackageReadiness(): bool
    {
        return ! ($this->isBound() && $this->packageReadinessReady());
    }

    /**
     * 接入成功且本机已可连通时，连接说明多为接入前文案，避免与当前状态矛盾。
     */
    public function shouldShowLocalReadinessGuidance(): bool
    {
        if (! $this->isBound()) {
            return true;
        }

        return $this->connectionStatusResolver->resolve() !== SiteConnectionStatus::Ready;
    }

    /**
     * 接入成功后仅保留失败类最近操作，成功记录不再占屏。
     */
    public function shouldShowLastAttemptSummary(): bool
    {
        $attempt = $this->lastAttemptStore->get();

        if ($attempt === null) {
            return false;
        }

        if (! $this->isBound()) {
            return true;
        }

        return ! (bool) ($attempt['success'] ?? false);
    }
}
