<?php

namespace Kylin\Sms\Gateways;

use Kylin\Sms\Exceptions\GatewayException;

/**
 * 百度云短信网关
 * 
 * 支持百度云短信服务的发送功能
 * 百度云短信服务提供稳定可靠的短信发送能力，支持验证码、通知等场景
 * 
 * 文档：https://cloud.baidu.com/doc/SMS/index.html
 * 
 * @package Kylin\Sms\Gateways
 */
class BaiduGateway extends BaseGateway
{
    /**
     * 网关名称标识
     */
    protected static string $name = 'baidu';

    /**
     * API 请求地址
     */
    protected const API_URL = 'https://smsv3.bj.baidubce.com/api/v3/singleSendSms';

    /**
     * 百度云 Access Key ID
     * 
     * @var string
     */
    protected string $accessKeyId;

    /**
     * 百度云 Secret Access Key
     * 
     * @var string
     */
    protected string $secretAccessKey;

    /**
     * 短信签名
     * 
     * @var string
     */
    protected string $signName;

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

    /**
     * 构造函数
     * 
     * 初始化百度云短信网关配置
     * 
     * @param array $config 网关配置数组
     */
    public function __construct(array $config = [])
    {
        parent::__construct($config);
        $this->accessKeyId = $config['access_key_id'] ?? '';
        $this->secretAccessKey = $config['secret_access_key'] ?? '';
        $this->signName = $config['sign_name'] ?? '';
        $this->endpoint = $config['endpoint'] ?? 'smsv3.bj.baidubce.com';
    }

    /**
     * 发送短信
     * 
     * 发送短信到指定手机号
     * 
     * @param string $to 接收手机号
     * @param string $content 短信内容（百度云使用模板，此参数可忽略）
     * @param array $data 附加数据，包含 template_id 和 template_params
     * @return array 发送结果
     */
    public function send(string $to, string $content, array $data = []): array
    {
        $params = [
            'mobile' => $this->formatPhone($to),
            'template' => $data['template_id'] ?? '',
            'signatureId' => $data['signature_id'] ?? $this->signName,
            'contentVar' => $data['template_params'] ?? [],
        ];

        $headers = $this->buildHeaders('POST', '/api/v3/singleSendSms', json_encode($params));

        try {
            $response = $this->request('POST', 'https://' . $this->endpoint . '/api/v3/singleSendSms', [
                'headers' => $headers,
                'json' => $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
    {
        return $this->send($to, '', [
            'template_id' => $templateId,
            'template_params' => $params,
        ]);
    }

    /**
     * 批量发送短信
     * 
     * 向多个手机号发送相同内容的短信
     * 
     * @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 所需的认证头信息
     * 
     * @param string $method HTTP 方法
     * @param string $uri 请求 URI
     * @param string $body 请求体
     * @return array 请求头数组
     */
    protected function buildHeaders(string $method, string $uri, string $body): array
    {
        $timestamp = gmdate('Y-m-d\TH:i:s\Z');
        $expirationPeriodInSeconds = 1800;
        $expirationTime = time() + $expirationPeriodInSeconds;

        $authString = 'bce-auth-v1/' . $this->accessKeyId . '/' . $timestamp . '/' . $expirationPeriodInSeconds;
        $signingKey = hash_hmac('sha256', $authString, $this->secretAccessKey);
        $canonicalRequest = $method . "\n" . $uri . "\n\nhost:" . $this->endpoint;
        $signature = hash_hmac('sha256', $canonicalRequest, $signingKey);

        $authorization = $authString . '/host/' . $signature;

        return [
            'Authorization' => $authorization,
            'Content-Type' => 'application/json',
            'Host' => $this->endpoint,
            'x-bce-date' => $timestamp,
        ];
    }

    /**
     * 解析响应结果
     * 
     * 将百度云 API 响应转换为标准化的结果格式
     * 
     * @param array $response API 响应
     * @return array 标准化的响应结果
     */
    protected function parseResponse(array $response): array
    {
        if (isset($response['code']) && $response['code'] === '1000') {
            return $this->buildSuccessResponse([
                'message_id' => $response['data']['messageId'] ?? '',
            ]);
        }

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