<?php

declare(strict_types=1);

namespace Kylin\Fitness\Services;

use Illuminate\Support\Facades\Crypt;

/**
 * 体测数据加密服务
 *
 * 依据《个人信息保护法》第二十八条：
 * 健康数据（体测数据）属于敏感个人信息，存储时需加密处理。
 *
 * 依据《个人信息保护法》第五十一条：
 * 采取加密、去标识化等安全技术措施保护个人信息。
 *
 * 使用方式：
 *   $encrypted = FitnessTestEncryptor::encrypt(['weight' => 70.5, 'body_fat_rate' => 18.2]);
 *   $original  = FitnessTestEncryptor::decrypt($encrypted);
 *   $masked    = FitnessTestEncryptor::mask($data);
 */
final class FitnessTestEncryptor
{
    /**
     * 加密体测数据
     *
     * @param array<string, mixed> $data 体测数据键值对
     * @return string JSON 加密字符串
     */
    public static function encrypt(array $data): string
    {
        return Crypt::encryptString(json_encode($data, JSON_UNESCAPED_UNICODE));
    }

    /**
     * 解密体测数据
     *
     * @param string $encrypted 加密字符串
     * @return array<string, mixed> 体测数据键值对
     */
    public static function decrypt(string $encrypted): array
    {
        try {
            return json_decode(Crypt::decryptString($encrypted), true, 512, JSON_THROW_ON_ERROR);
        } catch (\Throwable) {
            return [];
        }
    }

    /**
     * 脱敏体测数据用于日志/导出
     *
     * 依据《个人信息保护法》第五十一条，日志中敏感信息需脱敏。
     * 移除 member_id、member_name、id_card 等关联标识。
     *
     * @param array<string, mixed> $data 体测数据
     * @return array<string, mixed> 脱敏后的数据
     */
    public static function mask(array $data): array
    {
        $masked = $data;
        unset($masked['member_id'], $masked['member_name'], $masked['id_card'], $masked['phone']);

        return $masked;
    }
}