<?php

declare(strict_types=1);

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

namespace App\Services\SupportCenter;

use App\Models\HostSystemUpdateCheck;
use Illuminate\Support\Carbon;

/**
 * Support Center 下载令牌响应 → HostSystemUpdatePackage 字段映射。
 */
final class HostSystemUpdatePackageMetadataMapper
{
    /**
     * @param  array<string, mixed>  $data
     * @return array<string, mixed>
     */
    public function mapTokenResponseToAttributes(array $data, HostSystemUpdateCheck $checkSnapshot): array
    {
        return [
            'package_id' => $this->stringifyIdentifier($data['package_id'] ?? $checkSnapshot->package_id),
            'package_no' => $this->nullableString($data['package_no'] ?? null),
            'product_code' => $this->nullableString($data['product_code'] ?? null) ?? 'dberp',
            'version' => $this->nullableString($data['version'] ?? null) ?? $checkSnapshot->package_version,
            'release_channel' => $this->nullableString($data['release_channel'] ?? null) ?? $checkSnapshot->release_channel,
            'package_type' => $this->nullableString($data['package_type'] ?? null) ?? $checkSnapshot->package_type,
            'package_name' => $this->nullableString($data['package_name'] ?? null),
            'package_size' => $this->nullableInt($data['package_size'] ?? null) ?? $checkSnapshot->package_size,
            'checksum' => $this->nullableString($data['checksum'] ?? null) ?? $checkSnapshot->checksum,
            'checksum_algorithm' => $this->nullableString($data['checksum_algorithm'] ?? null) ?? $checkSnapshot->checksum_algorithm,
            'signature' => $this->nullableString($data['signature'] ?? null) ?? $checkSnapshot->signature,
            'token_expires_at' => $this->parseDateTime($data['token_expires_at'] ?? null),
            'raw_payload' => SupportCenterSnapshotSanitizer::sanitize($data),
        ];
    }

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

        if (is_string($value) || is_int($value)) {
            $string = trim((string) $value);

            return $string === '' ? null : $string;
        }

        return null;
    }

    private function nullableString(mixed $value): ?string
    {
        if (! is_string($value)) {
            return null;
        }

        $trimmed = trim($value);

        return $trimmed === '' ? null : $trimmed;
    }

    private function nullableInt(mixed $value): ?int
    {
        if ($value === null || $value === '') {
            return null;
        }

        if (is_int($value)) {
            return $value;
        }

        if (is_numeric($value)) {
            return (int) $value;
        }

        return null;
    }

    private function parseDateTime(mixed $value): ?Carbon
    {
        if (! is_string($value) || trim($value) === '') {
            return null;
        }

        try {
            return Carbon::parse($value)->utc();
        } catch (\Throwable) {
            return null;
        }
    }
}
