<?php

namespace PloverCRM\Modules\Integrations\Services;

use PloverCRM\Modules\Integrations\Models\GoogleAdsConnection;

/**
 * Resolves whether a connected Google Ads customer is ready for lead uploads.
 */
class GoogleAdsLeadUploadStatusService
{
    private const STATUS_READY = 'ready';
    private const STATUS_ACTION_REQUIRED = 'action_required';
    private const STATUS_UNAVAILABLE = 'unavailable';
    private const HELP_URL = 'https://support.google.com/google-ads/answer/14662970?hl=en';
    private const DOCS_URL = 'https://developers.google.com/google-ads/api/docs/conversions/upload-offline';
    private const CACHE_TTL = 300;

    public static function forConnectionId(int $connectionId, bool $forceRefresh = false): array
    {
        $connection = GoogleAdsConnectionService::getConnection($connectionId);

        if (!$connection) {
            return self::buildUnavailableStatus(
                'This Google Ads connection could not be found anymore.'
            );
        }

        return self::forConnection($connection, $forceRefresh);
    }

    public static function forConnection(GoogleAdsConnection $connection, bool $forceRefresh = false): array
    {
        $cacheKey = sprintf(
            'plover_google_lead_upload_%s',
            md5($connection->customer_id . '|' . ($connection->manager_id ?? '') . '|' . $connection->updated_at)
        );

        if ($forceRefresh) {
            delete_transient($cacheKey);
        } else {
            $cached = get_transient($cacheKey);
            if (is_array($cached)) {
                return $cached;
            }
        }

        $config = get_option('plover_crm_google_config', []);
        $developerToken = trim((string) ($config['developer_token'] ?? ''));
        if ($developerToken === '') {
            $status = self::buildUnavailableStatus(
                'Add a Google Ads developer token before using this connection in automations.'
            );
            set_transient($cacheKey, $status, self::CACHE_TTL);

            return $status;
        }

        try {
            $settings = (new GoogleAdsService())->getLeadUploadSettings(
                $developerToken,
                $connection->customer_id,
                $connection->manager_id
            );

            $status = self::buildStatusFromSettings(
                (bool) $settings['accepted_customer_data_terms'],
                (bool) $settings['enhanced_conversions_for_leads_enabled']
            );
        } catch (\Throwable $e) {
            $status = self::buildUnavailableStatus(
                self::humanizeFailureMessage($e->getMessage())
            );
        }

        set_transient($cacheKey, $status, self::CACHE_TTL);

        return $status;
    }

    public static function buildAutomationBlockMessage(array $status): string
    {
        if (($status['status'] ?? '') === self::STATUS_ACTION_REQUIRED) {
            return 'Finish Google Ads lead setup before using this connection in automations. ' . trim((string) ($status['message'] ?? ''));
        }

        return trim((string) ($status['message'] ?? 'This Google Ads connection is not ready for lead uploads.'));
    }

    private static function buildStatusFromSettings(bool $acceptedCustomerDataTerms, bool $enhancedConversionsForLeadsEnabled): array
    {
        if ($acceptedCustomerDataTerms && $enhancedConversionsForLeadsEnabled) {
            return [
                'status' => self::STATUS_READY,
                'is_ready' => true,
                'accepted_customer_data_terms' => true,
                'enhanced_conversions_for_leads_enabled' => true,
                'message' => 'Ready for Google Ads lead conversion uploads.',
                'help_url' => self::HELP_URL,
                'docs_url' => self::DOCS_URL,
                'setup_steps' => [],
            ];
        }

        $needsTerms = !$acceptedCustomerDataTerms;
        $needsEnhancedConversions = !$enhancedConversionsForLeadsEnabled;
        $messages = [];

        if ($needsTerms) {
            $messages[] = 'Accept the customer data terms in Google Ads.';
        }

        if ($needsEnhancedConversions) {
            $messages[] = 'Turn on Enhanced Conversions for Leads in Google Ads.';
        }

        return [
            'status' => self::STATUS_ACTION_REQUIRED,
            'is_ready' => false,
            'accepted_customer_data_terms' => $acceptedCustomerDataTerms,
            'enhanced_conversions_for_leads_enabled' => $enhancedConversionsForLeadsEnabled,
            'message' => implode(' ', $messages),
            'help_url' => self::HELP_URL,
            'docs_url' => self::DOCS_URL,
            'setup_steps' => self::buildSetupSteps($needsTerms, $needsEnhancedConversions),
        ];
    }

    private static function buildUnavailableStatus(string $message): array
    {
        return [
            'status' => self::STATUS_UNAVAILABLE,
            'is_ready' => false,
            'accepted_customer_data_terms' => false,
            'enhanced_conversions_for_leads_enabled' => false,
            'message' => $message,
            'help_url' => self::HELP_URL,
            'docs_url' => self::DOCS_URL,
            'setup_steps' => [
                'Open this customer account in Google Ads and confirm it is active.',
                'Make sure the connected Google user still has permission to manage conversions for this account.',
                'Reconnect the customer in Plover CRM if you changed ownership or permissions.',
            ],
        ];
    }

    private static function buildSetupSteps(bool $needsTerms, bool $needsEnhancedConversions): array
    {
        $steps = [
            'Open the connected customer account in Google Ads.',
            'Go to Goals > Settings in Google Ads.',
        ];

        if ($needsTerms) {
            $steps[] = 'Accept the customer data terms if Google shows them for this account.';
        }

        if ($needsEnhancedConversions) {
            $steps[] = 'Turn on Enhanced Conversions for Leads for this customer account.';
        }

        $steps[] = 'Save your changes in Google Ads, then return here and refresh this page.';

        return $steps;
    }

    private static function humanizeFailureMessage(string $message): string
    {
        $normalized = trim($message);

        if ($normalized === '') {
            return 'We could not verify this Google Ads customer right now.';
        }

        if (stripos($normalized, 'CUSTOMER_NOT_ENABLED') !== false) {
            return 'This Google Ads customer is not enabled or is no longer accessible to the connected Google user.';
        }

        if (stripos($normalized, 'permission') !== false) {
            return 'The connected Google user no longer has permission to manage this customer account.';
        }

        return $normalized;
    }
}
