<?php

namespace Kylin\Sms\Gateways;

use Kylin\Sms\Exceptions\GatewayException;

/**
 * 网易云信短信网关
 * 
 * 支持网易云信短信服务的发送功能
 * 网易云信是网易旗下的即时通讯云服务，提供短信验证码、通知短信等服务
 * 
 * 文档：https://dev.yunxin.163.com/docs/product/%E7%9F%AD%E4%BF%A1/%E7%9F%AD%E4%BF%A1%E6%8E%A5%E5%8F%A3%E6%8C%87%E5%8D%97
 * 
 * @package Kylin\Sms\Gateways
 */
class NeteaseGateway extends BaseGateway
{
    /**
     * 网关名称标识
     */
    protected static string $name = 'netease';

    /**
     * API 请求地址
     */
    protected const API_URL = 'https://api.netease.im/sms/sendtemplate.action';

    /**
     * 网易云信 App Key
     * 
     * @var string
     */
    protected string $appKey;

    /**
     * 网易云信 App Secret
     * 
     * @var string
     */
    protected string $appSecret;

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

    /**
     * 构造函数
     * 
     * 初始化网易云信短信网关配置
     * 
     * @param array $config 网关配置数组
     */
    public function __construct(array $config = [])
    {
        parent::__construct($config);
        $this->appKey = $config['app_key'] ?? '';
        $this->appSecret = $config['app_secret'] ?? '';
        $this->signName = $config['sign_name'] ?? '';
    }

    /**
     * 发送短信
     * 
     * 使用模板方式发送短信到指定手机号
     * 
     * @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
    {
        $nonce = mt_rand();
        $curTime = time();
        $checkSum = sha1($this->appSecret . $nonce . $curTime);

        $params = [
            'templateid' => $data['template_id'] ?? '',
            'mobiles' => json_encode([$this->formatPhone($to)]),
            'params' => json_encode(array_values($data['template_params'] ?? [])),
        ];

        $headers = [
            'AppKey' => $this->appKey,
            'Nonce' => $nonce,
            'CurTime' => $curTime,
            'CheckSum' => $checkSum,
            'Content-Type' => 'application/x-www-form-urlencoded',
        ];

        try {
            $response = $this->request('POST', self::API_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
    {
        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
    {
        $nonce = mt_rand();
        $curTime = time();
        $checkSum = sha1($this->appSecret . $nonce . $curTime);

        $params = [
            'templateid' => $data['template_id'] ?? '',
            'mobiles' => json_encode(array_map([$this, 'formatPhone'], $recipients)),
            'params' => json_encode(array_values($data['template_params'] ?? [])),
        ];

        $headers = [
            'AppKey' => $this->appKey,
            'Nonce' => $nonce,
            'CurTime' => $curTime,
            'CheckSum' => $checkSum,
            'Content-Type' => 'application/x-www-form-urlencoded',
        ];

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

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

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