<?php

namespace app\service;

use GuzzleHttp\Client;
use think\facade\Db as ThinkDb;
use app\model\BpsAdsMerchantRelation;
use app\model\ThirdUserAdvertiser;
use app\model\ThirdUser;
use Webman\Event\Event;
use Webman\RedisQueue\Redis;
use Webman\RedisQueue\Client as QueueClient;
use app\event\GoogleAdsCustomers;

class GoogleOAuthService
{
    /*
     * 获取google主体账号信息
     *
     */

    public function getGoogleAccountInfo($accessToken)
    {
//        'id' => '用户的Google ID',
//        'email' => '用户的电子邮件地址',
//        'verified_email' => true, // 邮箱是否已验证
//        'name' => '用户的全名',
//        'given_name' => '用户的名字',
//        'family_name' => '用户的姓氏',
//        'picture' => '用户头像的URL',
//        'locale' => '用户的语言偏好',
        $client = new Client();
        try {

            $options  = [
                "headers" => [
                    'Authorization' => 'Bearer ' . $accessToken,
                ],
            ];
            $userInfo = json_decode($client->request('Get', 'https://www.googleapis.com/oauth2/v2/userinfo', $options)->getBody()->getContents(), true);
//            // Process user info...
//            dump($userInfo,666);
            return $userInfo;
        } catch (\GuzzleHttp\Exception\ClientException $e) {
            error_log('Client error: ' . $e->getMessage());
            if ($e->hasResponse()) {
                error_log('Response: ' . $e->getResponse()->getBody());
            }
        } catch (\Exception $e) {
            // Handle other exceptions
            error_log('Error: ' . $e->getMessage());
        }
    }


    public function getAuthUrl($state = '')
    {
        $clientId     = getenv('GOOGLE_CLIENT_ID');
        $redirectUri  = getenv('GOOGLE_REDIRECT_URI');
        $scope        = 'https://www.googleapis.com/auth/adwords https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email';
        $responseType = 'code';
        $accessType   = 'offline';

//        $state        = 'state_parameter_passthrough_value'; // 可选,保护防止CSRF

        // 将state保存到会话或数据库中,稍后验证
//        $_SESSION['oauth_state'] = $state;  // 使用PHP会话来保存state

//        $authUrl = "https://accounts.google.com/o/oauth2/v2/auth?client_id=$clientId&redirect_uri=$redirectUri&scope=$scope&response_type=$responseType&state=$state";
        if (!empty($state)) {
            // 生成随机的state参数,防止CSRF攻击
//            $state = bin2hex(random_bytes(16)); // 生成一个随机字符串
//            $this->saveThirdUser($state);
            $authUrl = "https://accounts.google.com/o/oauth2/v2/auth?client_id=$clientId&redirect_uri=$redirectUri&scope=$scope&response_type=$responseType&access_type=$accessType&state=$state";
        } else {
            $authUrl = "https://accounts.google.com/o/oauth2/v2/auth?client_id=$clientId&redirect_uri=$redirectUri&scope=$scope&response_type=$responseType&access_type=$accessType";

        }
        return $authUrl;
    }

    public function getThirdUserByRandomCode($state)
    {
        $tableName = 'bps_third_user';
        $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
        $result    = ThinkDb::name($tableName)->where('random_code', $state)->find();
        return $result;
    }

    public function getRefreshToken($authCode)
    {
        $client   = new Client();
        $response = $client->post('https://oauth2.googleapis.com/token', [
            'form_params' => [
                'code' => $authCode,
                'client_id' => getenv('GOOGLE_CLIENT_ID'),
                'client_secret' => getenv('GOOGLE_CLIENT_SECRET'),
                'redirect_uri' => getenv('GOOGLE_REDIRECT_URI'),
                'grant_type' => 'authorization_code',
            ],
        ]);

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

    public function saveThirdUser($state)
    {
        //发起授权前,新记录到bps_third_user表
        $data      = [
            'random_code' => $state,
            'is_default' => 't',
            'third_type' => 'google',
        ];
        $tableName = 'bps_third_user';
        $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;

        $sql = " INSERT INTO {$tableName}
                    (random_code, is_default,  third_type)
                    VALUES (:random_code, :is_default,  :third_type";
        ThinkDb::execute($sql, $data);
    }

    public function getCustomerListNew(string $merchant_id = '')
    {
//        dump($merchant_id,555);
        //$userId = $options['uid'];  // 获取用户ID
        $customers = BpsAdsMerchantRelation::alias('bamr')
            ->where('bamr.merchant_id', $merchant_id)
//            ->where('bamr.is_unbind', 'f')
            ->where('bamr.is_del', 'f')
            ->where('bamr.platform', 2)
            ->field('bamr.account_id, bamr.account_name,bamr.is_unbind,bamr.currency')
//            ->field('')
            ->select();  // 执行查询
//        dump($customers,555);
        // 打印调试 SQL 查询
//        $sql = $customers->getLastSql();
//        dump($sql);
        // 如果没有找到符合条件的用户,返回空数组
        if ($customers->isEmpty()) {
            return [];
        }
//        dump($customers->toArray());
        return $customers->toArray();
    }

    //保存或更新某个主体部广告账号 废弃2025-2-13
    public function saveThirdUserAdvertiser($customer_id, $third_user_id, $login_customer_id, $customer, $merchant_id)
    {
        // 确保 customer_id 和 third_user_id 是字符串
        $customer_id = (string)$customer_id;
        $tableName   = 'bps_third_user_advertiser';
        $tableName   = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
        $data        = [
            'doc_' => $third_user_id,
            'advertiser_id' => $customer_id,
            'advertiser_name' => $customer['descriptive_name'],
            'google_login_customer_id' => $login_customer_id,
            'merchant_id' => $merchant_id,
            'currency' => $customer['currency'],
        ];
        if ($customer['manager'] === true) {
            $data['google_manager'] = 't';
        } else {
            $data['google_manager'] = 'f';
        }
        if ($customer['test_account'] === true) {
            $data['google_test_account'] = 't';
        } else {
            $data['google_test_account'] = 'f';
        }
//        dump($data);
        $sql = "
                    INSERT INTO {$tableName}
                    (advertiser_id,advertiser_name, doc_,google_login_customer_id,google_manager,google_test_account,merchant_id,currency)
                    VALUES (:advertiser_id, :advertiser_name,:doc_,:google_login_customer_id,:google_manager,:google_test_account,:merchant_id,:currency)
                    ON CONFLICT (advertiser_id,doc_)
                    DO UPDATE SET
                    advertiser_name = EXCLUDED.advertiser_name,
                    google_login_customer_id = EXCLUDED.google_login_customer_id,
                    google_manager = EXCLUDED.google_manager,
                    google_test_account = EXCLUDED.google_test_account,
                    currency = EXCLUDED.currency,
                    merchant_id = EXCLUDED.merchant_id
                ";
//        dump($sql,$data);
        ThinkDb::execute($sql, $data);
    }
//没调用
//    public function updateAdsMerchantRelation($data,$sendMq = 0)
//    {
//        $tableName = 'bps_ads_merchant_relation';
//        $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps.' . $tableName;
//
//        $sql = "
//        UPDATE {$tableName}
//        SET
//            user_id = :user_id,
//            is_unbind = :is_unbind,
//            updated_at = CURRENT_TIMESTAMP
//        WHERE
//            platform = 2
//            AND merchant_id = :merchant_id
//            AND account_id = :account_id
//    ";
//
//        ThinkDb::execute($sql, [
//            'user_id' => (string)$data['user_id'],
//            'is_unbind' => $data['is_unbind'] ?? 'f',
//            'merchant_id' => (string)$data['merchant_id'],
//            'account_id' => (string)$data['account_id'],
//            'user_id' => (string)$data['user_id'],
//        ]);
//
//        // 如果需要发送队列
//        if ($sendMq == 1) {
//            $this->queueNew([
//                'merchant_id' => $data['merchant_id'],
//                'account_id' => $data['account_id']
//            ]);
//        }
//    }

    //保存或更新某个主体部广告账号
    public function saveThirdUserAdvertiserNew($data, $sendMq = 0)
    {
        // 确保 account_id 和 merchant_id 是字符串
        $data['account_id']  = (string)$data['account_id'];
        $data['merchant_id'] = (string)$data['merchant_id'];
        $data['user_id']     = (string)$data['user_id'];

        $tableName = 'bps_ads_merchant_relation';
        $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps.' . $tableName;

        // 构造插入或更新的数据
        $insertData = [
            'platform' => 2, // 假设google平台值为2,根据实际情况调整
            'merchant_id' => $data['merchant_id'],
            'user_id' => $data['user_id'],
            'account_id' => $data['account_id'],
            'access_token' => $data['access_token'],
            'refresh_token' => $data['refresh_token'],
            'account_name' => $data['account_name'],
            'currency' => $data['currency'],
            'platform_user_id' => $data['platform_user_id'] ?? '',
            'platform_user_name' => $data['platform_user_name'] ?? '',
            'is_unbind' => $data['is_unbind'] ?? 'f',
            'ext_info' => $data['ext_info'] ?? '{}',
        ];
//        dump($insertData,2525);
        // 构造SQL语句
        $sql = "
        INSERT INTO {$tableName}
        (platform, merchant_id, user_id,access_token, refresh_token,account_id, account_name, currency, ext_info,platform_user_id, platform_user_name,is_unbind)
        VALUES (:platform, :merchant_id,:user_id, :access_token, :refresh_token, :account_id, :account_name, :currency, :ext_info,:platform_user_id, :platform_user_name,:is_unbind)
        ON CONFLICT (platform,merchant_id,account_id)
        DO UPDATE SET
            user_id = EXCLUDED.user_id,
            platform_user_id = EXCLUDED.platform_user_id,
            platform_user_name = EXCLUDED.platform_user_name,
            account_name = EXCLUDED.account_name,
            access_token = EXCLUDED.access_token,
            refresh_token = EXCLUDED.refresh_token,
            is_unbind = EXCLUDED.is_unbind,
            is_del = 'f',
            ext_info = EXCLUDED.ext_info,
            currency = EXCLUDED.currency,
            updated_at = CURRENT_TIMESTAMP";

        // 执行SQL语句
        ThinkDb::execute($sql, $insertData);
//        dump(ThinkDb::getLastSql(),2525);

        //如果要异步更新改广告账号数据的话。
        if ($sendMq == 1) {
            //        Event::emit(GoogleAdsCustomers::add_queue, $data);
            $options                = [];
            $options['merchant_id'] = $data['merchant_id'];
            $options['account_id']  = $data['account_id'];
//            $options['refresh_token']  = $data['refresh_token'];
//            $options['login_customer_id']  = json_decode($data['ext_info'],true)['login_customer_id']??'';
            $this->queueNew($options);
        }
    }


    public function updateAccountLastSyncTime($merchantId, $accountId): void
    {
        $tableName = 'bps_ads_merchant_relation';
        $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;

        //更新last_sync_time 赋值当前时间戳
        $data      = [
            'merchant_id' => $merchantId,
            'account_id' => $accountId,
            'last_sync_time' => time()
        ];
        $sql       = "
                    UPDATE {$tableName}
                    SET last_sync_time = :last_sync_time
                    where platform = 2 and merchant_id = :merchant_id and account_id = :account_id
                    ";
        ThinkDb::execute($sql, $data);
    }


    public function updateThirdUserDefault($third_user_id, $is_default = 't'): void
    {
        $tableName = 'bps_third_user';
        $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
        $data      = [
            'is_default' => $is_default,
            'id' => $third_user_id,];
        $sql       = "
                    UPDATE {$tableName}
                    SET is_default = :is_default
                    WHERE id = :id
                    ";
        ThinkDb::execute($sql, $data);
    }

    //废弃2025-2-13
    public function saveRefreshToken($refreshToken, $state = '')
    {
        // 使用ThinkORM保存数据到bps_third_user表
//        $thirdUser               = new \App\Models\ThirdUser();
//        $thirdUser->access_token = $accessToken;
//        $thirdUser->is_default   = true;
//        $thirdUser->random_code  = bin2hex(random_bytes(16)); // 生成随机码
//        $thirdUser->third_type   = 'google';
//        $thirdUser->user_id      = $userId;
//        $thirdUser->save();
        $data      = [
            'access_token' => $refreshToken,
            'is_default' => 'f',
            'third_type' => 'google',
        ];
        $tableName = 'bps_third_user';
        $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
        if (!empty($state)) {

            $thirdUser = ThirdUser::where('merchant_id', $state)->where('third_type', 'google')->find();  // 获取第一个结果
            //        dump($thirdUser);        return ($uid);
            if ($thirdUser) {
                $data['id'] = $thirdUser->id;
                $sql        = "
                    UPDATE {$tableName}
                    SET
                    access_token = :access_token,
                    is_default = :is_default,
                    third_type = :third_type
                    WHERE id = :id
                    ";
            } else {
                $data['merchant_id'] = $state;
                $sql                 = "
                    INSERT INTO {$tableName}
                    (access_token, is_default,  third_type, merchant_id)
                    VALUES (:access_token, :is_default,  :third_type, :merchant_id)
                ";
            }
        } else {
            $sql = "
                    INSERT INTO {$tableName}
                    (access_token, is_default,  third_type)
                    VALUES (:access_token, :is_default,  :third_type)
                ";
        }
        ThinkDb::execute($sql, $data);

        $options                  = [];
        $options['refresh_token'] = $refreshToken;
        Event::emit(GoogleAdsCustomers::add_queue, $data);
        $this->queue($options);
    }

    public function saveRefreshTokenNew($refreshToken, $accessToken, $merchantId, $userId)
    {
        $data                     = [
            'refresh_token' => $refreshToken,
            'access_token' => $accessToken,
            'merchant_id' => $merchantId,
            'user_id' => $userId,
//            'is_default' => 'f',
//            'third_type' => 'google',
        ];
        $options                  = [];
        $options['refresh_token'] = $refreshToken;

//        dump($data,$options);
        Event::emit(GoogleAdsCustomers::add_queue, $data);
//        $this->queue($options);
    }

    public function initNewGoogleAdsAccountData($refreshToken)
    {

        $options                  = [];
        $options['refresh_token'] = $refreshToken;
//        Event::emit(GoogleAdsCustomers::add_queue, $data);
        $this->queue($options);
    }

    public function revokeToken($accessToken, $merchantId)
    {
        $client = new Client();
        $client->post('https://oauth2.googleapis.com/revoke', [
            'form_params' => [
                'token' => $accessToken,
            ],
        ]);

        // 在数据库中删除或标记该`access_token(其实是refresh_token)`为无效
        BpsAdsMerchantRelation::where('merchant_id', $merchantId)->where('platform', 2)->delete();
//
//        $tableName = 'bps_third_user';
//        $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
//        $sql       = "UPDATE {$tableName} SET access_token = :access_token WHERE id = :id";
//        $data      = [
//            'access_token' => '', // 这里的 $accessToken 是您想要匹配的值
//            'id' => $third_user_id, // 这里的 $accessToken 是您想要匹配的值
//        ];
//        // 执行 SQL 语句
//        $result = ThinkDb::execute($sql, $data);
////        ThirdUser::where('access_token', $accessToken)->delete();

    }

    public function useRefreshToken($refreshToken)
    {
        $client   = new Client();
        $response = $client->post('https://oauth2.googleapis.com/token', [
            'form_params' => [
                'refresh_token' => $refreshToken,
                'client_id' => getenv('GOOGLE_CLIENT_ID'),
                'client_secret' => getenv('GOOGLE_CLIENT_SECRET'),
                'grant_type' => 'refresh_token',
            ],
        ]);

        $data = json_decode($response->getBody(), true);
        return $data['access_token'];
    }


    /**
     * 批量获取全部Google广告账号数据
     * 作废2025-2-13
     */
    public function getGoogleAdCustomersBak($options = [])
    {
        if (!empty($options['refresh_token'])) {
            $refreshToken = $options['refresh_token'];
            // 获取符合条件的客户ID数组
            $customers = ThirdUserAdvertiser::alias('tua')
                ->join('bps.bps_third_user tu', 'tua.doc_ = tu.id')  // 连接 bps_third_user 表
                ->where('tu.third_type', 'google')  // 筛选 third_type 为 google 的记录
                ->where('tu.access_token', $refreshToken)  // 筛选 third_type 为 google 的记录
                ->field('CAST(tua.advertiser_id AS BIGINT) as customer_id,tua.google_login_customer_id as login_customer_id,tua.google_test_account as test_account,tua.google_manager as manager, tu.access_token as refresh_token')  // 获取 advertiser_id 字段
                ->select();  // 执行查询
        } else {
            // 获取符合条件的客户ID数组
            $customers = ThirdUserAdvertiser::alias('tua')
                ->join('bps.bps_third_user tu', 'tua.doc_ = tu.id')  // 连接 bps_third_user 表
                ->where('tu.third_type', 'google')  // 筛选 third_type 为 google 的记录
                ->field('CAST(tua.advertiser_id AS BIGINT) as customer_id,tua.google_login_customer_id as login_customer_id,tua.google_test_account as test_account,tua.google_manager as manager, tu.access_token as refresh_token')  // 获取 advertiser_id 字段
                ->select();  // 执行查询
        }


        // 如果没有找到符合条件的广告主,抛出异常
        if ($customers->isEmpty()) {
            return [];
//            throw new ApiException('No customers found for google third type');
        }

        // 转换为简单的数组(提取 advertiser_id)
        return $customers->toArray();

    }

    //废弃2025-2-13
    public function queue($options = []): string
    {
        // 队列名
//        $queue = GoogleAdsCustomers::add_queue;
        $queue2 = GoogleAdsCustomers::init_queue;
        // 数据,可以直接传数组,无需序列化
//        $options = ['to' => 'tom@gmail.com', 'content' => 'hello'];
        // 投递消息
//        Redis::send($queue, $options['data']);
        QueueClient::send($queue2, $options);  //异步投递 延后15秒
        // 投递延迟消息,消息会在60秒后处理
//        Redis::send($queue, $options['data'], 60);

        return $queue2 . ' redis queue ok';
    }

    public function queueNew($options = []): string
    {
        // 队列名
//        $queue = GoogleAdsCustomers::add_queue;
        $queue2 = GoogleAdsCustomers::init_queue;
        // 数据,可以直接传数组,无需序列化
//        $options = ['to' => 'tom@gmail.com', 'content' => 'hello'];
        // 投递消息
//        Redis::send($queue, $options['data']);
        QueueClient::send($queue2, $options);  //异步投递 延后15秒
        // 投递延迟消息,消息会在60秒后处理
//        Redis::send($queue, $options['data'], 60);

        return $queue2 . ' redis queue ok';
    }


}