<?php

namespace app\service;

use app\service\GoogleAdsClientService;
use app\model\ThirdUserAdvertiser;
use app\util\Helper;
use app\util\ArgumentNames;
use app\util\ArgumentParser;

//use Google\Ads\GoogleAds\Lib\V18\GoogleAdsClient;
//use Google\Ads\GoogleAds\Util\FieldMasks;
//use Google\Ads\GoogleAds\Util\V18\ResourceNames;
//use Google\Ads\GoogleAds\V18\Common\ResponsiveSearchAdInfo;
//use Google\Ads\GoogleAds\V18\Enums\AdGroupAdStatusEnum\AdGroupAdStatus;
//use Google\Ads\GoogleAds\V18\Enums\GoogleAdsFieldCategoryEnum\GoogleAdsFieldCategory;
//use Google\Ads\GoogleAds\V18\Enums\GoogleAdsFieldDataTypeEnum\GoogleAdsFieldDataType;
//use Google\Ads\GoogleAds\V18\Errors\GoogleAdsError;
//use Google\Ads\GoogleAds\V18\Resources\Ad;
//use Google\Ads\GoogleAds\V18\Resources\AdGroupAd;
//use Google\Ads\GoogleAds\V18\Resources\GoogleAdsField;
//use Google\Ads\GoogleAds\V18\Services\AdGroupAdOperation;
//use Google\Ads\GoogleAds\V18\Services\AdOperation;
//use Google\Ads\GoogleAds\V18\Services\MutateAdGroupAdsRequest;
//
//use Google\Ads\GoogleAds\V18\Common\AdTextAsset;
//use Google\Ads\GoogleAds\V18\Enums\ServedAssetFieldTypeEnum\ServedAssetFieldType;
//use Google\Ads\GoogleAds\V18\Services\GoogleAdsRow;
//use Google\Ads\GoogleAds\V18\Services\MutateAdsRequest;
//use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsFieldsRequest;
//use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsRequest;
//use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsStreamRequest;
//use Google\Protobuf\Internal\RepeatedField;


use DateTime;
use think\facade\Db as ThinkDb;
use app\model\Ad as AdModel;
use app\model\Asset as AssetModel;
use app\model\AssetRelation as AssetRelationModel;


use Google\ApiCore\ApiException;

class GoogleAdsAssetRelationService extends BaseService
{
//    private $googleAdsClient;
    private $customerId;

    public function __construct($customerId = null)
    {

    }

    // 从数据库动态获取 google RefreshToken
//    private function getRefreshTokenFromDatabase($advertiserId)
//    {
//        // 通过 advertiser_id 查询 ThirdUserAdvertiser,联表查询 ThirdUser 数据
//        $userAdvertiser = ThirdUserAdvertiser::with('googleUser')  // 联表查询 user 关联
//        ->where('advertiser_id', $advertiserId)  // 根据 advertiser_id 查询
//        ->find();  // 获取第一个结果
//
//// 如果找到广告主数据
//        if ($userAdvertiser && $userAdvertiser->googleUser) {
//            // 获取关联用户的 access_token
//            return $userAdvertiser->googleUser ? $userAdvertiser->googleUser->access_token : null;
//        } else {
////            return $this->errorResponse('101', '未找到该广告主或关联的用户');
//        }
//    }


    /* @param int $customerId the customer ID
     * @param $options
     * @return mixed
     * @throws ApiException
     */
    public function runListAssetRelations(int $customerId, $date): array
    {
//        dump($customerId);
        // Creates a single shared budget to be used by the campaigns added below.
        $assetsResourceName = self::getAssetRelations($customerId,$date);

        if (is_array($assetsResourceName) && count($assetsResourceName) > 0) {
//              dump($assetsResourceName);
            self::saveAssetRelations($assetsResourceName);
        }
        return  $assetsResourceName;
//        return 'insert success';
    }


    /* @param int $customerId the customer ID
     * @param $options
     * @return mixed
     * @throws ApiException
     */
    public function runListVideoAssetRelations(int $customerId): mixed
    {
        // Creates a single shared budget to be used by the campaigns added below.
        $assetsResourceName = self::getVideoAssetRelations($customerId);
//        dump(json_encode($assetsResourceName));
        if (is_array($assetsResourceName) && count($assetsResourceName) > 0) {
            self::saveAssetRelations($assetsResourceName);
        }
//        return $assetsResourceName;
        return 'insert success';
    }


    /**
     *  在数据库中保存广告素材信息
     * @param $assetsResourceName
     * @return void
     */
    public static function saveAssetRelations($assetsResourceName)
    {
//        dump($assetsResourceName);
        $tableName = 'bps_google_ads_asset_relations';
        $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'public' . $tableName;
        foreach ($assetsResourceName as $data) {
            // 修改后的插入 SQL 语句
            $sql = "INSERT INTO {$tableName}
                (asset_id, ad_id, ad_group_id, campaign_id, date,month,season,year, create_at, update_at)
                VALUES (:asset_id, :ad_id, :ad_group_id, :campaign_id, :date,:month,:season,:year, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
                ON CONFLICT (asset_id, ad_id, date)
                DO NOTHING"; // 如果 (asset_id, ad_id, date) 存在,忽略插入操作
            ThinkDb::execute($sql, $data);
        }
    }


    /**
     *
     * @param int $customerId the customer ID
     */

    public static function getAssetRelations(int $customerId, $date = '2024-12-19')
    {
        // 调用私有方法提取 year, month, season
        $dateDetails = self::extractDateDetails($date);

        $year   = $dateDetails['year'];
        $month  = $dateDetails['month'];
        $season = $dateDetails['season'];

//        dump($year, $month, $season);

        // 获取所有素材
//        $assets = AssetModel::where('asset_type', 4)->select(); //图片素材

        $resourceNames = AssetModel::where('asset_type', 4)->where('customer_id', $customerId)
            ->column('asset_id, resource_name');

        if (!$resourceNames) {
            return [];
        }

//          dump($resourceNames);return($resourceNames);
        $result = [];
        foreach ($resourceNames as $resourceName) {
            // 获取广告表中的所有广告
            $ads = ThinkDb::table('bps.bps_ads_ad')
//            ->whereRaw("metadata->'marketing_images' @> ?", ['["customers/4060397299/assets/191677352383"]'])
//            ->whereOrRaw("metadata->'square_marketing_images' @> ?", ['["customers/4060397299/assets/191677352383"]'])
                ->whereRaw("metadata->'marketing_images' @> ?", ['["' . $resourceName['resource_name'] . '"]'])
                ->whereOrRaw("metadata->'square_marketing_images' @> ?", ['["' . $resourceName['resource_name'] . '"]'])
                ->select();

//            $ads = AdModel::where(function ($query) use ($resourceName) {
//                $query->whereJsonContains('metadata->marketing_images', $resourceName)
//                      ->WhereOrJsonContains('metadata->square_marketing_images', $resourceName);
//            })->select();
//            $result[$resourceName['asset_id']] = $ads;

            foreach ($ads as $ad) {
                $result[$resourceName['asset_id']]['ad_id']       = $ad['ad_id'];
                $result[$resourceName['asset_id']]['ad_group_id'] = $ad['ad_set_id'];
                $result[$resourceName['asset_id']]['campaign_id'] = $ad['campaign_id'];
                $result[$resourceName['asset_id']]['asset_id']    = $resourceName['asset_id'];
                $result[$resourceName['asset_id']]['date']        = $date;
                $result[$resourceName['asset_id']]['month']       = $month;
                $result[$resourceName['asset_id']]['season']      = $season;
                $result[$resourceName['asset_id']]['year']        = $year;
            }

        }
//        dump($result);
        return $result;
//        dump('Google Ads Asset synchronization completed.');

    }

    /**
     *
     * @param int $customerId the customer ID
     */

    public static function getVideoAssetRelations(int $customerId)
    {
//        $date = date('Y-m-d');
        $date = '2025-02-07';
        // 调用私有方法提取 year, month, season
        $dateDetails = self::extractDateDetails($date);

        $year   = $dateDetails['year'];
        $month  = $dateDetails['month'];
        $season = $dateDetails['season'];

        // 获取所有素材
//        $assets = AssetModel::where('asset_type', 2)->select(); //视频素材

        $resourceNames = AssetModel::where('asset_type', 2)->where('customer_id', $customerId)
            ->column('asset_id, resource_name');
        if (!$resourceNames) {
            return [];
        }
//          dump($resourceNames);return($resourceNames);
        $result = [];
        foreach ($resourceNames as $resourceName) {
            // 获取广告表中的所有匹配的广告
            $ads = ThinkDb::table('bps.bps_ads_ad')
                ->whereRaw("metadata->'youtube_videos' @> ?", ['["' . $resourceName['resource_name'] . '"]'])
                ->select();
            foreach ($ads as $ad) {
                $result[$resourceName['asset_id']]['ad_id']       = $ad['ad_id'];
                $result[$resourceName['asset_id']]['ad_group_id'] = $ad['ad_set_id'];
                $result[$resourceName['asset_id']]['campaign_id'] = $ad['campaign_id'];
                $result[$resourceName['asset_id']]['asset_id']    = $resourceName['asset_id'];
                $result[$resourceName['asset_id']]['date']        = $date;
                $result[$resourceName['asset_id']]['month']       = $month;
                $result[$resourceName['asset_id']]['season']      = $season;
                $result[$resourceName['asset_id']]['year']        = $year;
            }

        }
        return $result;
//        dump('Google Ads Asset synchronization completed.');

    }


    /**
     * 从日期字符串中提取年、月、季节信息,并返回这些信息
     *
     * @param string $date 日期,格式为 'Y-m-d'
     * @return array 包含 year, month 和 season 的数组
     */
    private static function extractDateDetails($date)
    {
        $dateObj = new DateTime($date); // 将日期字符串转换为 DateTime 对象

        // 提取年和月
        $year  = (int)$dateObj->format('Y');
        $month = (int)$dateObj->format('m');

        // 计算季度
        if ($month >= 1 && $month <= 3) {
            $season = (int)$dateObj->format('Y') . '01'; // Q1
        } elseif ($month >= 4 && $month <= 6) {
            $season = (int)$dateObj->format('Y') . '02'; // Q2
        } elseif ($month >= 7 && $month <= 9) {
            $season = (int)$dateObj->format('Y') . '03'; // Q3
        } else {
            $season = (int)$dateObj->format('Y') . '04'; // Q4
        }
        $month = (int)$dateObj->format('Ym');
        return [
            'year' => $year,
            'month' => $month,
            'season' => $season
        ];
    }
}