<?php

declare(strict_types=1);

namespace App\Support;

use App\Models\HostSystemAuthorization;
use App\Services\SupportCenter\HostSystemAuthorizationEntitlementPresenter;
use App\Services\SupportCenter\HostSystemAuthorizationStatusPresenter;
use Illuminate\Support\Carbon;

/**
 * 系统授权中心页只读展示数据。
 */
final class HostSystemAuthorizationCenterDisplay
{
    public function __construct(
        private readonly HostSystemAuthorizationStatusPresenter $statusPresenter,
        private readonly HostSystemAuthorizationEntitlementPresenter $entitlementPresenter,
        private readonly SiteOnboardingCenterDisplay $siteOnboardingDisplay,
    ) {}

    public function record(): HostSystemAuthorization
    {
        return HostSystemAuthorization::singleton();
    }

    public function hasSiteBinding(): bool
    {
        return $this->siteOnboardingDisplay->isBound() || filled($this->record()->site_no);
    }

    /**
     * 系统接入中心缓存认定的官方站点绑定（用于绑定提示分区，不含授权表兜底）。
     */
    public function isOfficialSiteBound(): bool
    {
        return $this->siteOnboardingDisplay->isBound();
    }

    public function authorizationLabel(): string
    {
        return $this->statusPresenter->authorizationLabel((bool) $this->record()->authorized);
    }

    public function authorizationBadgeColor(): string
    {
        return $this->statusPresenter->authorizationBadgeColor((bool) $this->record()->authorized);
    }

    public function serviceStatusLabel(): string
    {
        return $this->statusPresenter->serviceStatusLabel($this->record()->service_status);
    }

    public function serviceStatusBadgeColor(): string
    {
        return $this->statusPresenter->serviceStatusBadgeColor($this->record()->service_status);
    }

    public function syncStatusLabel(): string
    {
        return $this->statusPresenter->syncStatusLabel($this->record()->last_sync_status);
    }

    public function syncStatusBadgeColor(): string
    {
        return $this->statusPresenter->syncStatusBadgeColor($this->record()->last_sync_status);
    }

    public function officialSiteNo(): ?string
    {
        $siteNo = $this->record()->site_no;

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

    public function licenseNo(): ?string
    {
        $licenseNo = $this->record()->license_no;

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

    public function licenseHolder(): ?string
    {
        $holder = $this->record()->license_holder;

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

    public function boundDomainsText(): ?string
    {
        $lines = $this->boundDomainsLines();

        return $lines === [] ? null : implode('、', $lines);
    }

    /**
     * @return list<string>
     */
    public function boundDomainsLines(): array
    {
        $domains = $this->record()->bound_domains;

        if (! is_array($domains) || $domains === []) {
            return [];
        }

        $items = array_values(array_filter($domains, static fn (mixed $item): bool => is_string($item) && $item !== ''));

        return $items === [] ? [] : $items;
    }

    public function expiresAtLabel(): ?string
    {
        $expiresAt = $this->record()->expires_at;

        return $expiresAt instanceof Carbon ? $expiresAt->copy()->timezone(config('app.display_timezone', 'UTC'))->format('Y-m-d H:i') : null;
    }

    public function remainingServiceDays(): ?int
    {
        $expiresAt = $this->record()->expires_at;

        if (! $expiresAt instanceof Carbon) {
            return null;
        }

        return (int) now()->utc()->startOfDay()->diffInDays($expiresAt->copy()->utc()->startOfDay(), false);
    }

    public function remainingServiceDaysLabel(): ?string
    {
        $days = $this->remainingServiceDays();

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

        if ($days < 0) {
            return (string) __('dberp.system_authorization.remaining_days.expired', ['days' => abs($days)]);
        }

        if ($days === 0) {
            return (string) __('dberp.system_authorization.remaining_days.today');
        }

        return (string) __('dberp.system_authorization.remaining_days.remaining', ['days' => $days]);
    }

    public function hasServiceExpiry(): bool
    {
        return filled($this->expiresAtLabel());
    }

    public function hasRemainingServiceDays(): bool
    {
        return filled($this->remainingServiceDaysLabel());
    }

    public function expiresAtDisplayLabel(): string
    {
        $label = $this->expiresAtLabel();

        return is_string($label) && $label !== ''
            ? $label
            : (string) __('dberp.system_authorization.service_display.expires_unknown');
    }

    public function remainingServiceDaysDisplayLabel(): string
    {
        $label = $this->remainingServiceDaysLabel();

        return is_string($label) && $label !== ''
            ? $label
            : (string) __('dberp.system_authorization.service_display.remaining_unknown');
    }

    /**
     * @return list<array{key: string, label: string, enabled: bool, icon: string, status_label: string}>
     */
    public function entitlementSummaryItems(): array
    {
        $rows = $this->entitlementPresenter->primaryEntitlementsForDisplay($this->record()->entitlements);

        return array_map(
            fn (array $row): array => [
                'key' => $row['key'],
                'label' => $row['label'],
                'enabled' => $row['enabled'],
                'icon' => $this->entitlementIconFor($row['key']),
                'status_label' => $row['enabled']
                    ? (string) __('dberp.system_authorization.entitlements_display.status_enabled')
                    : (string) __('dberp.system_authorization.entitlements_display.status_disabled'),
            ],
            $rows,
        );
    }

    /**
     * @return list<string>
     */
    public function entitlementSummaryLines(): array
    {
        return array_map(
            static fn (array $item): string => $item['enabled']
                ? (string) __('dberp.system_authorization.entitlement_line.enabled', ['label' => $item['label']])
                : (string) __('dberp.system_authorization.entitlement_line.disabled', ['label' => $item['label']]),
            $this->entitlementSummaryItems(),
        );
    }

    private function entitlementIconFor(string $key): string
    {
        return match ($key) {
            'can_check_system_update' => 'heroicon-o-magnifying-glass-circle',
            'can_execute_system_update' => 'heroicon-o-arrow-up-tray',
            'can_install_plugin' => 'heroicon-o-puzzle-piece',
            'can_update_plugin' => 'heroicon-o-arrow-path',
            default => 'heroicon-o-check-badge',
        };
    }

    public function lastSyncedAtLabel(): ?string
    {
        $syncedAt = $this->record()->last_synced_at;

        return $syncedAt instanceof Carbon
            ? $syncedAt->copy()->timezone(config('app.display_timezone', 'UTC'))->format('Y-m-d H:i')
            : null;
    }

    public function lastSyncMessage(): ?string
    {
        $message = $this->record()->last_sync_message;

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

    /**
     * 同步分区仅展示业务提示，不展示远端返回的原始说明，避免泄露内部细节。
     */
    public function lastSyncDisplayHint(): ?string
    {
        $status = strtolower(trim((string) $this->record()->last_sync_status));

        if ($status === 'failed') {
            return (string) __('dberp.system_authorization.sync_display.last_failed_hint');
        }

        return null;
    }

    public function isAuthorizationGranted(): bool
    {
        return (bool) $this->record()->authorized;
    }

    /**
     * 已获官方授权且最近一次同步成功，视为稳定授权快照。
     */
    public function hasStableAuthorizationSnapshot(): bool
    {
        return $this->isAuthorizationGranted()
            && strtolower(trim((string) $this->record()->last_sync_status)) === 'success';
    }

    /**
     * 稳定快照下「同步成功」分区与通知重复，仅在未同步或失败时展示。
     */
    public function shouldShowSyncSection(): bool
    {
        return ! $this->hasStableAuthorizationSnapshot();
    }

    /**
     * 稳定快照且无权益行时，不再展示「请完成同步」类空状态引导。
     */
    public function shouldShowEntitlementsEmptyState(): bool
    {
        if ($this->entitlementSummaryItems() !== []) {
            return false;
        }

        return ! $this->hasStableAuthorizationSnapshot();
    }

    public function shouldShowEntitlementsSection(): bool
    {
        return $this->entitlementSummaryItems() !== [] || $this->shouldShowEntitlementsEmptyState();
    }
}
