<?php

namespace Api\Controller;

use Think\Controller;

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\Exceptions\MqttClientException;
use PhpMqtt\Client\ConnectionSettings;

class PublicController extends Controller
{
	protected $openid; // 用户openid
	protected $session_key; // 用户session_key
	//初始化
	public function _initialize()
	{
		// 获取请求头中的 Token
		$token = isset($_SERVER['HTTP_TOKEN']) ? $_SERVER['HTTP_TOKEN'] : null;
		// 获取 jwt 密钥
		$jwtKey = C('jwtKey');
		try {
			// 解码 JWT Token
			$decoded = JWT::decode($token, new Key($jwtKey, 'HS256'));
			// Token 没有过期，继续处理
			$this->openid = $decoded->openid;
			$this->session_key = $decoded->session_key;
		} catch (\Firebase\JWT\ExpiredException $e) {
			// Token 过期
			echo json_encode(array('status' => -1, 'msg' => 'Token 已过期'));
			exit();
		} catch (\Exception $e) {
			// 其他 JWT 解码错误
			echo json_encode(array('status' => -1, 'msg' => 'Token 解码失败'));
			exit();
		} catch (\TypeError $e) {
			// 处理 Token 为 null 或者不是字符串的情况
			echo json_encode(array('status' => -1, 'msg' => 'Token 无效'));
			exit();
		}
	}
	//远程调取页面 访问API
	protected function apiUrl($url)
	{
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		$output = curl_exec($ch);
		curl_close($ch);
		$jsoninfo = json_decode($output, true);
		return $jsoninfo;
	}
	/**
	 * @description: 构建token
	 * @param {array} data 要存储在 JWT 中的数据，键值对形式 ps:这里可以传exp 来覆盖默认的过期时间
	 * @return {*} token
	 */
	protected function makeToken($data = [])
	{
		// 定义密钥，应该使用安全的随机字符串并妥善保管
		$jwtKey = C('jwtKey');
		$currtime = time();

		// 默认的数据
		$defaultData = [
			'iat'  => $currtime,        // 签发时间（时间戳）
			'iss'  => 'jwt_admin',      // 签发者
			'nbf'  => $currtime,        // 在此时间之前不可用 (这里是2秒以内)
			'exp'  => strtotime('tomorrow'), //过期时间 到第二天凌晨
			'jti' => md5(uniqid('JWT') . $currtime), // JWT ID：令牌的唯一标识符
		];

		// 合并默认数据和传递的数据
		$tokenData = array_merge($defaultData, $data);

		// 使用密钥和 HS256 算法对数据进行编码生成 JWT
		return JWT::encode($tokenData, $jwtKey, 'HS256');
	}
	/**
	 * @description: 将手机号的倒数第 5 位到第 8 位替换成星号
	 * @param string $phoneNumber 完整的手机号
	 * @return string 处理后的手机号
	 */
	protected function maskPhoneNumber($phoneNumber)
	{
		// 去掉手机号中的+号以便处理
		$cleanPhoneNumber = str_replace('+', '', $phoneNumber);

		// 判断手机号长度（带国家区号和不带国家区号的情况）
		if (strlen($cleanPhoneNumber) > 11) { // 带国家区号的手机号
			$maskedPhoneNumber = substr_replace($cleanPhoneNumber, '****', -8, 4);
			return '+' . $maskedPhoneNumber;
		} elseif (strlen($cleanPhoneNumber) === 11) { // 不带国家区号的手机号
			return substr_replace($cleanPhoneNumber, '****', -8, 4);
		} else {
			// 非法手机号长度，返回原始号码
			return $phoneNumber;
		}
	}
	/**
	 * @description: 连接mqtt服务器 并向指定主题发布信息
	 * @param string $topic mqtt主题
	 * @param string $msg 要发布的主题
	 */
	protected function publish($topic, $msg)
	{
		$server   = C('mqtt')['server'];         // MQTT 代理地址
		$port     = C('mqtt')['port'];                    // MQTT 代理端口
		$clientId = C('mqtt')['client_id'];        // 客户端 ID
		$username = C('mqtt')['username'];                 // 用户名（如果需要）
		$password = C('mqtt')['password'];                // 密码（如果需要）

		try {
			// 创建连接设置对象
			$settings = (new ConnectionSettings)->setUsername($username)->setPassword($password);
			// 实例化 MQTT 客户端
			$mqtt = new MqttClient($server, $port, $clientId);
			// 连接到 MQTT 代理
			$mqtt->connect($settings);
			// 检查是否连接成功
			if ($mqtt->isConnected()) {
				// 发布消息到指定的主题 ps:主题  信息  qos
				$mqtt->publish($topic, $msg, 0);
				// 断开连接
				$mqtt->disconnect();
			} else {
				echo "连接失败";
			}
		} catch (MqttClientException $e) { //连接失败
			echo "Could not connect to MQTT broker: " . $e->getMessage();
		}
	}
}
