<?php
declare (strict_types=1);

namespace app\common\service\sms;

use app\common\model\sms\SmsConfig;
use Overtrue\EasySms\Strategies\OrderStrategy;

class EasySmsConfig
{
    public static function generateConfig(): array
    {
        $activeConfig = SmsConfig::where('status', 1)->find();

        if (!$activeConfig) {
            throw new \Exception('未找到启用的短信网关配置');
        }

        $gateway = $activeConfig['gateway'];
        $gatewayConfig = self::decryptSensitiveData($gateway, $activeConfig['config_data']);

        return [
            'timeout' => 5.0,
            'default' => [
                'strategy' => OrderStrategy::class,
                'gateways' => [$gateway],
            ],
            'gateways' => [
                $gateway => $gatewayConfig,
            ],
        ];
    }

    public static function buildGatewayConfig(string $gateway, array $configData): array
    {
        $gatewayConfig = self::decryptSensitiveData($gateway, $configData);

        return [
            'timeout' => 5.0,
            'default' => [
                'strategy' => OrderStrategy::class,
                'gateways' => [$gateway],
            ],
            'gateways' => [
                $gateway => $gatewayConfig,
            ],
        ];
    }

    public static function getSupportedGateways(): array
    {
        return SmsConfigMapping::GATEWAY_NAMES;
    }

    public static function isGatewaySupported(string $gateway): bool
    {
        return array_key_exists($gateway, self::getSupportedGateways());
    }

    public static function getRequiredFields(string $gateway): array
    {
        return SmsConfigMapping::GATEWAY_REQUIRED_FIELDS[$gateway] ?? [];
    }

    public static function getSensitiveFields(string $gateway): array
    {
        $sensitiveFieldsMap = [
            'aliyun' => ['access_key_secret'],
            'qcloud' => ['secret_key'],
            'huawei' => ['app_secret'],
            'qiniu' => ['secret_key'],
            'yunpian' => ['api_key'],
            'submail' => ['app_key'],
            'juhe' => ['app_key'],
            'sendcloud' => ['sms_key'],
            'baidu' => ['sk'],
        ];

        return $sensitiveFieldsMap[$gateway] ?? [];
    }

    public static function encrypt(string $data): string
    {
        $key = (string)config('app.sms_encrypt_key', 'default_sms_key_32bytes!!');
        $iv = substr(md5($key), 0, 16);
        return base64_encode(openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv));
    }

    public static function decrypt(string $encryptedData): string
    {
        $key = (string)config('app.sms_encrypt_key', 'default_sms_key_32bytes!!');
        $iv = substr(md5($key), 0, 16);
        return openssl_decrypt(base64_decode($encryptedData), 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv) ?: '';
    }

    public static function encryptSensitiveData(string $gateway, array $configData): array
    {
        $sensitiveFields = self::getSensitiveFields($gateway);

        foreach ($sensitiveFields as $field) {
            if (isset($configData[$field]) && $configData[$field] !== '') {
                $configData[$field] = self::encrypt((string)$configData[$field]);
            }
        }

        return $configData;
    }

    public static function decryptSensitiveData(string $gateway, array $configData): array
    {
        $sensitiveFields = self::getSensitiveFields($gateway);

        foreach ($sensitiveFields as $field) {
            if (isset($configData[$field]) && $configData[$field] !== '') {
                $decrypted = self::decrypt((string)$configData[$field]);
                $configData[$field] = $decrypted !== '' ? $decrypted : $configData[$field];
            }
        }

        return $configData;
    }
}
