<?php

namespace App\Models;

use Database\Factories\GoogleAdsConnectionFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class GoogleAdsConnection extends Model
{
    /** @use HasFactory<GoogleAdsConnectionFactory> */
    use HasFactory;

    protected $fillable = [
        'user_id', 'google_email', 'customer_id', 'available_customer_ids', 'available_customer_accounts', 'manager_customer_id', 'developer_token',
        'oauth_client_id', 'oauth_client_secret', 'refresh_token',
    ];

    protected $hidden = [
        'developer_token',
        'oauth_client_id',
        'oauth_client_secret',
        'refresh_token',
    ];

    protected function casts(): array
    {
        return [
            'developer_token' => 'encrypted',
            'oauth_client_id' => 'encrypted',
            'oauth_client_secret' => 'encrypted',
            'refresh_token' => 'encrypted',
            'available_customer_ids' => 'array',
            'available_customer_accounts' => 'array',
        ];
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * The one account this product buys on, from config rather than per user.
     *
     * Google Ads is one common internal access, the same as Meta, which reads a
     * single META_ACCESS_TOKEN and has no notion of connecting your own
     * account. Google arrived modelled the opposite way: a stored OAuth
     * connection per user, so every tool began by asking which row belonged to
     * the person typing, and a user without one could do nothing at all.
     *
     * Deliberately unsaved. Nothing about this belongs in the database: the
     * credentials live in config, and persisting a copy would mean two answers
     * to the same question and a stale one the day the token is rotated.
     *
     * Returns null when Google is not configured, which is what the publish
     * gate reports rather than failing inside an API client.
     *
     * Existing per-user rows are untouched. The parallel Google chat still
     * reads them, and it goes when it goes.
     */
    public static function shared(): ?self
    {
        $conn = PlatformConnection::shared('google');
        if ($conn) {
            $refreshToken = (string) ($conn->refresh_token ?: $conn->access_token);
            $customerId = (string) ($conn->account_id ?? $conn->platform_data['customer_id'] ?? config('services.google_ads.customer_id'));
            $managerId = (string) ($conn->platform_data['manager_customer_id'] ?? $conn->platform_data['login_customer_id'] ?? config('services.google_ads.login_customer_id'));

            if (filled($refreshToken) && filled($customerId)) {
                return new self([
                    'customer_id' => $customerId,
                    'manager_customer_id' => $managerId,
                    'refresh_token' => $refreshToken,
                ]);
            }
        }

        $refreshToken = (string) config('services.google_ads.refresh_token');
        $customerId = (string) config('services.google_ads.customer_id');

        if (blank($refreshToken) || blank($customerId)) {
            return null;
        }

        return new self([
            'customer_id' => $customerId,
            'manager_customer_id' => (string) config('services.google_ads.login_customer_id'),
            'refresh_token' => $refreshToken,
        ]);
    }

    /** Why Google cannot be reached, phrased for whoever reads it. */
    public static function missingReason(): string
    {
        $conn = PlatformConnection::shared('google');
        $hasRefresh = filled($conn?->refresh_token ?: $conn?->access_token) || filled(config('services.google_ads.refresh_token'));

        if (! $hasRefresh) {
            return 'Google Ads is not configured. Set GOOGLE_ADS_REFRESH_TOKEN before publishing to it';
        }

        return 'no Google Ads account is configured. Set GOOGLE_ADS_CUSTOMER_ID before publishing to it';
    }
}
