<?php

namespace Kylin\Sms\Gateways;

use Kylin\Sms\Exceptions\GatewayException;

/**
 * 移动云MAS短信网关
 * 
 * 支持中国移动云MAS短信服务的发送功能
 * 中国移动云MAS是中国移动面向企业客户提供的消息服务解决方案
 * 
 * 文档：https://mas.10086.cn/
 * 
 * @package Kylin\Sms\Gateways
 */
class MasGateway extends BaseGateway
{
    /**
     * 网关名称标识
     */
    protected static string $name = 'mas';

    /**
     * API 请求地址
     */
    protected const API_URL = 'https://mas.10086.cn/api/sms/send';

    /**
     * 应用 ID
     * 
     * @var string
     */
    protected string $appId;

    /**
     * 应用 Key
     * 
     * @var string
     */
    protected string $appKey;

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

    /**
     * 企业名称
     * 
     * @var string
     */
    protected string $ecName;

    /**
     * 密钥
     * 
     * @var string
     */
    protected string $secretKey;

    /**
     * 构造函数
     * 
     * 初始化移动云MAS短信网关配置
     * 
     * @param array $config 网关配置数组
     */
    public function __construct(array $config = [])
    {
        parent::__construct($config);
        $this->appId = $config['app_id'] ?? '';
        $this->appKey = $config['app_key'] ?? '';
        $this->signName = $config['sign_name'] ?? '';
        $this->ecName = $config['ec_name'] ?? '';
        $this->secretKey = $config['secret_key'] ?? '';
    }

    /**
     * 发送短信
     * 
     * 发送普通短信内容到指定手机号
     * 
     * @param string $to 接收手机号
     * @param string $content 短信内容
     * @param array $data 附加数据
     * @return array 发送结果
     */
    public function send(string $to, string $content, array $data = []): array
    {
        $mobiles = [$this->formatPhone($to)];
        $params = [
            'ecName' => $this->ecName,
            'apId' => $this->appId,
            'secretKey' => $this->secretKey,
            'mobiles' => implode(',', $mobiles),
            'content' => $content,
            'sign' => $data['sign_name'] ?? $this->signName,
            'addSerial' => '',
        ];

        $params['mac'] = $this->computeMac($params);

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

    /**
     * 发送模板短信
     * 
     * 使用模板内容发送短信，模板参数将被替换
     * 
     * @param string $to 接收手机号
     * @param string $templateId 模板内容（移动云MAS使用模板内容）
     * @param array $params 模板参数
     * @return array 发送结果
     */
    public function sendTemplate(string $to, string $templateId, array $params = []): array
    {
        $content = $templateId;
        foreach ($params as $key => $value) {
            $content = str_replace('{' . $key . '}', $value, $content);
        }
        return $this->send($to, $content);
    }

    /**
     * 批量发送短信
     * 
     * 向多个手机号发送相同内容的短信
     * 
     * @param array $recipients 接收手机号数组
     * @param string $content 短信内容
     * @param array $data 附加数据
     * @return array 发送结果
     */
    public function sendBatch(array $recipients, string $content, array $data = []): array
    {
        $mobiles = array_map([$this, 'formatPhone'], $recipients);
        $params = [
            'ecName' => $this->ecName,
            'apId' => $this->appId,
            'secretKey' => $this->secretKey,
            'mobiles' => implode(',', $mobiles),
            'content' => $content,
            'sign' => $data['sign_name'] ?? $this->signName,
            'addSerial' => '',
        ];

        $params['mac'] = $this->computeMac($params);

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

    /**
     * 计算 MAC 签名
     * 
     * 生成移动云MAS API 所需的 MAC 签名
     * 
     * @param array $params 请求参数
     * @return string MAC 签名字符串
     */
    protected function computeMac(array $params): string
    {
        $stringToSign = $params['ecName'] . $params['apId'] . $params['secretKey'] . $params['mobiles'] . $params['content'] . $params['sign'] . $params['addSerial'];
        return md5($stringToSign);
    }

    /**
     * 解析响应结果
     * 
     * 将移动云MAS API 响应转换为标准化的结果格式
     * 
     * @param array $response API 响应
     * @return array 标准化的响应结果
     */
    protected function parseResponse(array $response): array
    {
        if (isset($response['success']) && $response['success'] === true) {
            return $this->buildSuccessResponse([
                'msg_id' => $response['data']['msgId'] ?? '',
            ]);
        }

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