<?php

namespace App\Handlers;

use Illuminate\Support\Facades\Cache;
use App\Command\Log;

//小程序accesstoken
class MpAaccessToken
{

    private $appId;
    private $appSecret;

    public function __construct()
    {
        $this->appId = env('WX_XCX_APPID');
        $this->appSecret = env('WX_XCX_KEY');
    }

    /**
     * 获取微信小程序access_token
     * @param bool $force 是否强制刷新token,默认false
     * @return string|null 返回access_token或null
     * @throws \Exception 当获取token失败时抛出异常
     * 
     * 使用示例:
     * $token = (new MpAaccessToken())->getAccessToken(true); // 强制刷新
     * $token = (new MpAaccessToken())->getAccessToken(); // 正常获取
     * 
     * 注意事项:
     * 1. 强制刷新会忽略缓存直接请求新token
     * 2. 建议仅在明确知道token失效时使用强制刷新
     */
    
    public function getAccessToken($force = false)
    {
        $token = Cache::get('access_token_expire_time');
        $data = $token ? $token : ['expire_time' => 0];
        
        if ($force || $data['expire_time'] < time()) {
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
            $res = json_decode($this->httpGet($url));
            
            if (isset($res->access_token)) {
                $data['expire_time'] = time() + 7000;
                $data['access_token'] = $res->access_token;
                Cache::set('access_token_expire_time', $data);
                return $data['access_token'];
            } else {
                Log::add('debug', '获取access_token失败: ' . json_encode($res));
                throw new \Exception('获取access_token失败');
            }
        }
        
        return $data['access_token'];
    }

    private function httpGet($url)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);

        $res = curl_exec($curl);
        curl_close($curl);

        return $res;
    }
}