<?php

namespace app\service;

use app\model\Campaign;
use app\model\CampaignBudget;
use app\model\AdGroup;
use app\model\Ad;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Exception\RequestException;

class GoogleAdsService
{
    // Google Ads API 基础 URL
    private $baseUrl = 'https://googleads.googleapis.com/v17';

    // Google Ads API 客户 ID
    private $customerId;

    private $loginCustomerId; // 增加 login-customer-id 属性

    // OAuth2 access token
    private $accessToken;

    // Developer Token
    private $developerToken;

    private $client;

    public function __construct($accessToken, $customerId, $developerToken, $loginCustomerId = null)
    {
        $this->accessToken     = $accessToken;
        $this->customerId      = $customerId;
        $this->developerToken  = $developerToken;
        $this->loginCustomerId = $loginCustomerId;

        // 初始化 Guzzle 客户端
        $this->client = new GuzzleClient();
    }

    /**
     * 发起 HTTP 请求
     * @param string $method 请求方法(GET, POST, PATCH, DELETE)
     * @param string $endpoint API 端点
     * @param array $data 请求数据
     * @return array API 响应
     */
    private function sendRequest($method, $endpoint, $data = [])
    {
        // 构建 URL
        $url = "{$this->baseUrl}/customers/{$this->customerId}/$endpoint";

        // 设置请求头
        $headers = [
            'Authorization' => "Bearer {$this->accessToken}",
            'developer-token' => $this->developerToken,
            'Content-Type' => 'application/json'
        ];
        // 如果有广告经理 ID,添加到请求头
        if ($this->loginCustomerId) {
            $headers['login-customer-id'] = $this->loginCustomerId;
        }

        // 调试:输出请求的 URL 和头部信息
//        return [$url, $headers, $data];
        // 使用 Guzzle 发起请求
        try {
            $response = $this->client->request($method, $url, [
                'headers' => $headers,
                'json' => $data
            ]);


            // 获取响应体并解析为数组
            $body = $response->getBody()->getContents();
            return json_decode($body, true);

        } catch (RequestException $e) {
            // 处理请求错误
            echo "HTTP Request failed: " . $e->getMessage();
            return [];
        }
    }

    /**
     * 创建广告预算并存储到数据库
     */
    public function createCampaignBudget($budgetName, $amount)
    {
        // 构建请求数据
        $data = [
            'operations' => [
                [
                    'create' => [
                        'name' => $budgetName,
                        'amountMicros' => $amount * 1000000, // 转换为微单位
//                        'delivery_method' => 'STANDARD',
//                        'status' => 'ENABLED'
                    ]
                ]
            ]
        ];
//        return $data;
        // 调用 sendRequest 方法发起 POST 请求到 mutate 端点
        $response = $this->sendRequest('POST', 'campaignBudgets:mutate', $data);

        // 存储返回的广告预算数据到数据库
//        if (isset($response['results'][0]['resource_name'])) {
//            CampaignBudget::create([
//                'name' => $response['results'][0]['name'],
//                'amount_micros' => $response['results'][0]['amount_micros'],
//                'status' => $response['results'][0]['status'],
//                'delivery_method' => $response['results'][0]['delivery_method'],
//            ]);
//        }

        return $response;
    }

    /**
     * 创建广告系列并存储到数据库
     */
    public function createCampaign($campaignName, $budgetId)
    {
        // 构建请求数据
        $data = [
            'name' => $campaignName,
            'status' => 'PAUSED',
            'advertising_channel_type' => 'SEARCH',
            'campaign_budget' => "customers/{$this->customerId}/campaignBudgets/{$budgetId}",
            'network_settings' => [
                'target_google_search' => true,
                'target_search_network' => true,
                'target_content_network' => false,
                'target_partner_search_network' => false
            ],
            'start_date' => date('Y-m-d'),
            'end_date' => date('Y-m-d', strtotime('+1 year'))
        ];

        // 调用 sendRequest 方法发起 POST 请求
        $response = $this->sendRequest('POST', 'campaigns', $data);

        // 存储返回的广告系列数据到数据库
        if (isset($response['resource_name'])) {
            Campaign::create([
                'name' => $response['name'],
                'status' => $response['status'],
                'advertising_channel_type' => $response['advertising_channel_type'],
                'campaign_budget' => $response['campaign_budget'],
                'start_date' => $response['start_date'],
                'end_date' => $response['end_date'],
            ]);
        }

        return $response;
    }

    /**
     * 创建广告组并存储到数据库
     */
    public function createAdGroup($adGroupName, $campaignId)
    {
        // 构建请求数据
        $data = [
            'name' => $adGroupName,
            'status' => 'PAUSED',
            'campaign' => "customers/{$this->customerId}/campaigns/{$campaignId}",
            'type' => 'SEARCH_STANDARD'
        ];

        // 调用 sendRequest 方法发起 POST 请求
        $response = $this->sendRequest('POST', 'adGroups', $data);

        // 存储返回的广告组数据到数据库
        if (isset($response['resource_name'])) {
            AdGroup::create([
                'name' => $response['name'],
                'status' => $response['status'],
                'campaign_id' => $campaignId,
                'type' => $response['type'],
            ]);
        }

        return $response;
    }

    /**
     * 创建广告并存储到数据库
     */
    public function createAd($adGroupId, $adName, $finalUrl)
    {
        // 构建请求数据
        $data = [
            'ad' => [
                'expanded_text_ad' => [
                    'headline_part1' => 'Headline 1',
                    'headline_part2' => 'Headline 2',
                    'description' => 'Description',
                    'final_urls' => [$finalUrl]
                ],
                'status' => 'PAUSED'
            ],
            'ad_group' => "customers/{$this->customerId}/adGroups/{$adGroupId}"
        ];

        // 调用 sendRequest 方法发起 POST 请求
        $response = $this->sendRequest('POST', 'ads', $data);

        // 存储返回的广告数据到数据库
        if (isset($response['resource_name'])) {
            Ad::create([
                'name' => $response['ad']['expanded_text_ad']['headline_part1'], // 使用广告的标题字段作为示例
                'ad_group_id' => $adGroupId,
                'status' => $response['ad']['status'],
                'final_url' => $response['ad']['expanded_text_ad']['final_urls'][0],
            ]);
        }

        return $response;
    }
}