<?php

namespace app\event;

use app\model\TiktokAd;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use support\Db;
//use QL\QueryList;
use support\Redis;


class TiktokAds
{
    //微博热榜地址
//    const url = 'https://library.tiktok.com/api/v1/search?region=GB&type=1&start_time=1666540800&end_time=1666627200';

    const  userAgent = 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';

    const type = 'tiktokads';
    const limit = 12;
    const sort_order = 'impression,desc';


//    const countries = ["AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU", "IS", "IE","IT", "LV", "LI", "LT", "LU", "MT", "NL", "NO", "PL", "PT", "RO", "SK", "SI", "ES", "SE", "CH", "TR", "GB"] ;
    const countries = ["GB", "BE"];


    /**
     * 每天爬取tiktok广告
     * @return void
     */
    public function update()
    {
        try {

            $client = new Client([
                //允许重定向
//                'allow_redirects' => true,
            ]);


            // 获取前两天 0 点的时间戳
            $dayBeforeYesterdayStart = strtotime('-2 days 00:00:00');

            // 获取前一天 0 点的时间戳
            $yesterdayStart = strtotime('-1 day 00:00:00');
            $countryCache = Redis::get(self::type . 'lastCountry');
            //全部跑完跳出
            if ($countryCache == 'All') {
                dump($countryCache . '国家更新tiktok Ads 完成');
                return;
            }

            if (empty($countryCache)) {
                $countryCache = 'GB';
            }

            $searchIdCache = Redis::get(self::type . 'lastSearchId');
            $offsetCache   = Redis::get(self::type . 'nextOffset');
            $totalCache    = Redis::get(self::type . 'totalCache');
            if (!isset($searchIdCache) || empty($searchIdCache)) {
                $searchIdCache = '';
            }
            if (!isset($offsetCache) || empty($searchIdCache)) {
                $offsetCache = 0;
            }
            if (!isset($totalCache) || empty($searchIdCache)) {
                $totalCache = 0;
            }

            //判断国家是否跑完。
            if ($totalCache > 0 && $offsetCache > ceil($totalCache / self::limit)) {
                $key = array_search($countryCache, self::countries, true);
                if (in_array($countryCache, self::countries) && isset(self::countries[$key + 1])) {
                    $countryCache = self::countries[$key + 1];
                    dump('更新' . $countryCache . '国家的tiktok Ads 完成');
                } else {
                    $countryCache = 'All'; //赋值非正常国家的code中断定时任务
                    dump($countryCache . '国家更新tiktok Ads 完成');
                }
                return;
            }


            $start_time = $dayBeforeYesterdayStart;
            $end_time   = $yesterdayStart;
            //当前国家爬取
            $currentParams = null;
            $currentParams = ['country' => $countryCache, 'search_id' => $searchIdCache, 'type' => 1, 'start_time' => $start_time, 'end_time' => $end_time];


            $url = 'https://library.tiktok.com/api/v1/search?region=' . $currentParams['country'] . '&type=' . $currentParams['type'] . '&start_time=' . $currentParams['start_time'] . '&end_time=' . $currentParams['end_time'];

            $res = json_decode($client->post($url, [
                'headers' => [
                    'accept' => 'application/json, text/plain, */*',
                    'accept-language' => 'zh-CN,zh;q=0.9',
                    'content-type' => 'application/json',
                    'cookie' => 'cookie: _ttp=2ov8Fc4C2CaNscHJd90O9fMhlpE; _ga=GA1.1.1025820618.1731926196; FPID=FPID2.2.Bcgkp%2Fk%2Bbn5w5YeSMR9wd9VpNHJwTUpkkaEqSdCEa0w%3D.1731926196; FPAU=1.2.944915349.1731926193; FPLC=mbVyryI5aG6IVpAvhs1JsgWjA7FVA6QsCJ7VbXhM7zWoXNp4rcD0IK7FNTTf%2FuOrqeOgqEhTd4NB3hY7q3aDVTGQa3WGHqxkGte4%2BBZxsrpaHFas9kb7DPRXM12T5Q%3D%3D; _ga_TEQXTT9FE4=GS1.1.1732097542.7.0.1732097542.0.0.857840528',
                    'origin' => 'https://library.tiktok.com',
                    'priority' => 'u=1, i',
                    'referer' => 'https://library.tiktok.com/ads?region=AT&start_time=1731945600000&end_time=1732032000000&adv_name=&adv_biz_ids=&query_type=&sort_type=last_shown_date,desc',
                    'sec-ch-ua' => '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
                    'sec-ch-ua-mobile' => '?0',
                    'sec-ch-ua-platform' => '"Windows"',
                    'sec-fetch-dest' => 'empty',
                    'sec-fetch-mode' => 'cors',
                    'sec-fetch-site' => 'same-origin',
                    'user-agent' => self::userAgent,
//                        'user-agent' => 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
                ],
                'json' => [
                    'query' => '',
                    'query_type' => '',
                    'adv_biz_ids' => '',
                    'order' => self::sort_order,
                    'offset' => (int) $offsetCache,
                    'search_id' => $currentParams['search_id'],
                    'limit' => self::limit,
                ],

            ])->getBody()->getContents(), true);
//            dump($res);return;  //调试点

            if ($res['search_id'] != $searchIdCache) {
                $searchIdCache = $res['search_id'];
                dump( 'search_id更新 ' . $searchIdCache . ' 成功');
            }


            if ($res['total'] == 0 || $res['code'] != 0) {
                dump('更新tiktok Ads接口响应异常:' . json_encode($res, JSON_UNESCAPED_UNICODE));
                return;
            }
            $listAdsIds = [];
            foreach ($res['data'] as $ad) {
                if($ad['audit_status'] == 2 || empty($ad['videos'])){
                    continue; //审核不过或者没视频不采集
                }

                $imagesJson = is_array($ad['image_urls']) ? json_encode($ad['image_urls']):json_encode([]);
                $rejection_info = is_array($ad['rejection_info']) ? json_encode($ad['rejection_info']):null;
//                dump($rejection_info);
                $insertData[$ad['id']] = [
                    'ad_id' => $ad['id'],
                    'name' => $ad['name'],
                    'audit_status' => $ad['audit_status'],
                    'type' => $ad['type'],
                    'first_shown_date' => $ad['first_shown_date'],
                    'last_shown_date' => $ad['last_shown_date'],
                    'image_urls' => $imagesJson,
                    'estimated_audience' => $ad['estimated_audience'],
                    'spent' => $ad['spent'],
                    'impression' => $ad['impression'],
                    'show_mode' => $ad['show_mode'],
                    'rejection_info' => $rejection_info,
                    'sor_audit_status' => $ad['sor_audit_status'],
                    'country_code' => $countryCache,
                ];
                if(isset($ad['videos']) && !empty($ad['videos'])) {
                    // 遍历 "videos" 数组
                    foreach ($ad['videos'] as $video) {
                        $insertData[$ad['id']]['video_url'] = $video['video_url'];
                        $insertData[$ad['id']]['cover_img'] = $video['cover_img'];
                    }
                }
                $listAdsIds = array_column($insertData, 'ad_id');

            }
//            dump($insertData);return;


            if (empty($insertData)) return;

            //开启事务
            Db::beginTransaction();


            //删除原来的旧数据
            TiktokAd::query()->whereIn('ad_id', array_keys($insertData))->delete();
            //添加新的数据
            TiktokAd::query()->insert($insertData);

            //redis缓存
            Redis::set(self::type, json_encode($insertData, JSON_UNESCAPED_UNICODE));

            //redis缓存 记录更新时间
            $time = date('Y-m-d H:i:s');
            Redis::set(self::type . 'time', $time);
            Redis::set(self::type . 'lastCountry', $countryCache);
            Redis::set(self::type . 'nextOffset', ++$offsetCache); //记录下一次的offset
            Redis::set(self::type . 'totalCache', $res['total']);
            Redis::set(self::type . 'lastSearchId', $searchIdCache);
            if(!empty($listAdsIds)){
                Redis::rPush(self::type . 'AdsIds',...$listAdsIds);
            }

            //提交事务
            Db::commit();
            //销毁$res
            unset($res);

            dump(date('Y-m-d H:i:s') . '更新' . self::type . '成功');
        } catch (GuzzleException|\Exception $exception) {
            //回滚事务
            Db::rollBack();
            dump('更' . self::type . '异常:' . $exception->getMessage());
            dump($exception);
        }
//        } catch (ClientExceptionInterface $e) {
//            // 捕获 4xx 错误
//            dump( 'Client error: ' . $e->getMessage() . "\n");
//        } catch (ServerExceptionInterface $e) {
//            // 捕获 5xx 错误
//            dump('Server error: ' . $e->getMessage() . "\n");
//        } catch (TransportExceptionInterface $e) {
//            // 捕获网络传输错误
//            dump('Transport error: ' . $e->getMessage() . "\n") ;
//        } catch (\Exception $e) {
//            // 捕获所有其他错误
//            dump('General error: ' . $e->getMessage() . "\n") ;
//        }
    }
}