<?php

namespace Kylin\Sms\Gateways;

use Kylin\Sms\Exceptions\GatewayException;

/**
 * 华为云短信网关
 * 
 * 支持华为云消息&短信服务的发送、模板发送和批量发送功能
 * 文档：https://support.huaweicloud.com/productdesc-msgsms/sms_01_0001.html
 */
class HuaweiGateway extends BaseGateway
{
    /**
     * 网关名称标识
     */
    protected static string $name = 'huawei';

    /**
     * 华为云 App Key
     */
    protected string $appKey;

    /**
     * 华为云 App Secret
     */
    protected string $appSecret;

    /**
     * 国内短信签名通道号
     */
    protected string $sender;

    /**
     * 签名名称
     */
    protected string $signature;

    /**
     * API 端点
     */
    protected string $endpoint;

    /**
     * 构造函数
     * 
     * 初始化华为云短信网关配置
     * 
     * @param array $config 网关配置数组
     */
    public function __construct(array $config = [])
    {
        parent::__construct($config);
        $this->appKey = $config['app_key'] ?? '';
        $this->appSecret = $config['app_secret'] ?? '';
        $this->sender = $config['sender'] ?? '';
        $this->signature = $config['signature'] ?? '';
        $this->endpoint = $config['endpoint'] ?? 'smsapi.cn-north-4.myhuaweicloud.com:443';
    }

    /**
     * 发送短信
     * 
     * @param string $to 接收手机号
     * @param string $content 短信内容
     * @param array $data 附加数据
     * @return array 发送结果
     */
    public function send(string $to, string $content, array $data = []): array
    {
        $url = 'https://' . $this->endpoint . '/sms/batchSendSms/v1';

        $params = [
            'from' => $this->sender,
            'to' => '+86' . $this->formatPhone($to),
            'templateId' => $data['template_id'] ?? '',
            'templateParas' => json_encode(array_values($data['template_params'] ?? [])),
            'signature' => $data['signature'] ?? $this->signature,
        ];

        $headers = $this->buildHeaders();

        try {
            $response = $this->request('POST', $url, [
                'headers' => $headers,
                'form_params' => $params,
            ]);
            return $this->parseResponse($response);
        } catch (GatewayException $e) {
            return $this->buildErrorResponse($e->getMessage(), $e->getCode(), $e->getContext());
        }
    }

    /**
     * 发送模板短信
     * 
     * @param string $to 接收手机号
     * @param string $templateId 模板 ID
     * @param array $params 模板参数
     * @return array 发送结果
     */
    public function sendTemplate(string $to, string $templateId, array $params = []): array
    {
        $data = [
            'template_id' => $templateId,
            'template_params' => $params,
        ];
        return $this->send($to, '', $data);
    }

    /**
     * 批量发送短信
     * 
     * @param array $recipients 接收手机号数组
     * @param string $content 短信内容
     * @param array $data 附加数据
     * @return array 发送结果
     */
    public function sendBatch(array $recipients, string $content, array $data = []): array
    {
        $results = [];
        foreach ($recipients as $recipient) {
            $results[] = $this->send($recipient, $content, $data);
        }
        return $this->buildSuccessResponse(['results' => $results]);
    }

    /**
     * 构建请求头
     * 
     * 生成华为云 API 所需的认证头信息
     * 
     * @return array 请求头数组
     */
    protected function buildHeaders(): array
    {
        $timestamp = date('Ymd\THis\Z');
        $nonce = uniqid();

        $stringToSign = $nonce . "\n" . $timestamp;
        $signature = base64_encode(hash_hmac('sha256', $stringToSign, $this->appSecret, true));

        return [
            'Content-Type' => 'application/x-www-form-urlencoded',
            'Authorization' => 'WSSE realm="SDP",profile="UsernameToken",type="Appkey"',
            'X-WSSE' => sprintf(
                'UsernameToken Username="%s",PasswordDigest="%s",Nonce="%s",Created="%s"',
                $this->appKey,
                $signature,
                $nonce,
                $timestamp
            ),
        ];
    }

    /**
     * 解析响应结果
     * 
     * @param array $response API 响应
     * @return array 标准化的响应结果
     */
    protected function parseResponse(array $response): array
    {
        $code = $response['code'] ?? '';
        if ($code === '000000') {
            return $this->buildSuccessResponse([
                'sms_id' => $response['smsId'] ?? '',
            ]);
        }

        return $this->buildErrorResponse(
            $response['description'] ?? '发送失败',
            $code ?: 500,
            $response
        );
    }
}
