<?php

namespace Kylin\Notification\Channels;

use GuzzleHttp\Client;
use Kylin\Notification\Contracts\ChannelInterface;
use Kylin\Notification\Models\Notification;

/**
 * 腾讯云短信渠道
 * 通过 HTTP API 直接调用，无需 Fork 整个 tencentcloud-sdk-php（过于庞大）
 * API文档：https://cloud.tencent.com/document/product/382/55981
 */
class TencentSmsChannel implements ChannelInterface
{
    public function send(Notification $notification, array $params = []): array
    {
        try {
            $phone = $params['phone'] ?? $params['to'] ?? null;
            $signName = $params['sign_name'] ?? config('kylin-notification.channels.tencent_sms.sign_name', '');
            $templateId = $params['template_id'] ?? '';
            $templateParams = $params['template_params'] ?? [];
            $sdkAppId = $params['sdk_app_id'] ?? config('kylin-notification.channels.tencent_sms.sdk_app_id', '');

            if (!$phone) {
                return ['success' => false, 'message_id' => null, 'error' => 'Missing phone number', 'raw_response' => null];
            }

            $config = config('kylin-notification.channels.tencent_sms', []);
            $secretId = $config['secret_id'];
            $secretKey = $config['secret_key'];
            $region = $config['region'] ?? 'ap-guangzhou';

            // 腾讯云 SMS API 3.0 签名请求
            $payload = [
                'PhoneNumberSet' => ['+86' . $phone],
                'SmsSdkAppId' => $sdkAppId,
                'SignName' => $signName,
                'TemplateId' => $templateId,
                'TemplateParamSet' => array_values($templateParams),
            ];

            $result = $this->callTencentApi($secretId, $secretKey, $region, 'SendSms', '2021-01-11', $payload);

            $statusSet = $result['Response']['SendStatusSet'][0] ?? [];
            $code = $statusSet['Code'] ?? 'UNKNOWN';
            $success = $code === 'Ok';

            return [
                'success' => $success,
                'message_id' => $statusSet['SerialNo'] ?? null,
                'error' => $success ? null : ($statusSet['Message'] ?? $code),
                'raw_response' => $result,
            ];
        } catch (\Throwable $e) {
            return ['success' => false, 'message_id' => null, 'error' => $e->getMessage(), 'raw_response' => null];
        }
    }

    public function getName(): string
    {
        return 'tencent_sms';
    }

    private function callTencentApi(string $secretId, string $secretKey, string $region, string $action, string $version, array $payload): array
    {
        $host = 'sms.tencentcloudapi.com';
        $timestamp = time();
        $date = gmdate('Y-m-d', $timestamp);

        $httpRequestMethod = 'POST';
        $canonicalUri = '/';
        $canonicalQueryString = '';
        $contentType = 'application/json; charset=utf-8';
        $payloadJson = json_encode($payload);
        $hashedPayload = strtolower(hash('sha256', $payloadJson));

        $canonicalHeaders = "content-type:{$contentType}\nhost:{$host}\nx-tc-action:{$action}\n";
        $signedHeaders = 'content-type;host;x-tc-action';
        $canonicalRequest = "{$httpRequestMethod}\n{$canonicalUri}\n{$canonicalQueryString}\n{$canonicalHeaders}\n{$signedHeaders}\n{$hashedPayload}";

        $algorithm = 'TC3-HMAC-SHA256';
        $credentialScope = "{$date}/sms/tc3_request";
        $hashedCanonicalRequest = strtolower(hash('sha256', $canonicalRequest));
        $stringToSign = "{$algorithm}\n{$timestamp}\n{$credentialScope}\n{$hashedCanonicalRequest}";

        $secretDate = hash_hmac('sha256', $date, "TC3{$secretKey}", true);
        $secretService = hash_hmac('sha256', 'sms', $secretDate, true);
        $secretSigning = hash_hmac('sha256', 'tc3_request', $secretService, true);
        $signature = hash_hmac('sha256', $stringToSign, $secretSigning);

        $authorization = "{$algorithm} Credential={$secretId}/{$credentialScope}, SignedHeaders={$signedHeaders}, Signature={$signature}";

        $client = new Client();
        $response = $client->post("https://{$host}", [
            'headers' => [
                'Content-Type' => $contentType,
                'Host' => $host,
                'X-TC-Action' => $action,
                'X-TC-Version' => $version,
                'X-TC-Region' => $region,
                'X-TC-Timestamp' => (string) $timestamp,
                'Authorization' => $authorization,
            ],
            'body' => $payloadJson,
        ]);

        return json_decode($response->getBody()->getContents(), true);
    }
}
