[CmdletBinding()]
param(
    [string]$ExpectedGoogleEmail = 'seoanalyticsmaster@gmail.com',
    [string]$AnalyticsBaseUrl = 'http://localhost/Savit/Analytics/public',
    [int]$TimeoutSeconds = 300,
    [int]$PollIntervalSeconds = 5,
    [switch]$ForceReconnect
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

function Get-NullableString {
    param($Value)

    if ($null -eq $Value) {
        return ''
    }
    return [string]$Value
}

function Get-BulkStatus {
    param(
        [Parameter(Mandatory = $true)]
        [string]$BaseUrl
    )

    $statusUrl = ('{0}/api/bulk-connect/status' -f $BaseUrl.TrimEnd('/'))
    $raw = Invoke-RestMethod -Method Get -Uri $statusUrl -TimeoutSec 20
    return Resolve-BulkStatus -RawResponse $raw
}

function Resolve-BulkStatus {
    param(
        [Parameter(Mandatory = $true)]
        $RawResponse
    )

    $payload = $RawResponse
    if ($null -ne $RawResponse.PSObject.Properties['data'] -and $null -ne $RawResponse.data) {
        $payload = $RawResponse.data
    }

    $connected = $false
    $email = ''

    if ($null -ne $payload.PSObject.Properties['connected']) {
        $connected = [bool]$payload.connected
    }

    if ($null -ne $payload.PSObject.Properties['email']) {
        $email = Get-NullableString $payload.email
    }

    return [pscustomobject]@{
        connected = $connected
        email     = $email
        raw       = $RawResponse
    }
}

function Disconnect-Bulk {
    param(
        [Parameter(Mandatory = $true)]
        [string]$BaseUrl
    )

    $disconnectUrl = ('{0}/api/bulk-connect' -f $BaseUrl.TrimEnd('/'))
    Invoke-RestMethod -Method Delete -Uri $disconnectUrl -TimeoutSec 20 | Out-Null
}

function Start-BulkConnectFlow {
    param(
        [Parameter(Mandatory = $true)]
        [string]$BaseUrl
    )

    $connectUrl = ('{0}/api/bulk-connect' -f $BaseUrl.TrimEnd('/'))
    Write-Host "Opening OAuth consent screen: $connectUrl" -ForegroundColor Cyan
    Start-Process $connectUrl | Out-Null
}

Write-Host '=== Savit Analytics One-Time Bulk Connect Setup ===' -ForegroundColor Green
Write-Host ("Target Google account: {0}" -f $ExpectedGoogleEmail)
Write-Host ("Analytics base URL: {0}" -f $AnalyticsBaseUrl)

try {
    $status = Get-BulkStatus -BaseUrl $AnalyticsBaseUrl
} catch {
    throw "Unable to reach bulk-connect status API. Confirm Apache/XAMPP is running and open this URL first: $AnalyticsBaseUrl"
}

$currentConnected = [bool]$status.connected
$currentEmail = Get-NullableString $status.email

if ($ForceReconnect -and $currentConnected) {
    Write-Host 'Force reconnect requested. Disconnecting current bulk token...' -ForegroundColor Yellow
    Disconnect-Bulk -BaseUrl $AnalyticsBaseUrl
    $status = Get-BulkStatus -BaseUrl $AnalyticsBaseUrl
    $currentConnected = [bool]$status.connected
    $currentEmail = Get-NullableString $status.email
}

if ($currentConnected -and $currentEmail -ieq $ExpectedGoogleEmail) {
    Write-Host ("Bulk connect already completed with: {0}" -f $currentEmail) -ForegroundColor Green
    Write-Host 'No action needed. This is already set for all projects using global OAuth tokens.' -ForegroundColor Green
    exit 0
}

if ($currentConnected -and -not ($currentEmail -ieq $ExpectedGoogleEmail)) {
    throw "Bulk token is currently connected to '$currentEmail'. Re-run with -ForceReconnect to switch to '$ExpectedGoogleEmail'."
}

Start-BulkConnectFlow -BaseUrl $AnalyticsBaseUrl
Write-Host ("Complete Google consent in your browser using account: {0}" -f $ExpectedGoogleEmail) -ForegroundColor Yellow
Write-Host 'Waiting for callback and token storage...' -ForegroundColor Yellow

$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
$connected = $false

while ((Get-Date) -lt $deadline) {
    Start-Sleep -Seconds $PollIntervalSeconds

    try {
        $status = Get-BulkStatus -BaseUrl $AnalyticsBaseUrl
    } catch {
        continue
    }

    if ([bool]$status.connected) {
        $connected = $true
        break
    }

    $remaining = [int][Math]::Max(0, ($deadline - (Get-Date)).TotalSeconds)
    Write-Host ("Still waiting... {0}s remaining" -f $remaining)
}

if (-not $connected) {
    throw "Timed out after $TimeoutSeconds seconds waiting for bulk OAuth callback. Re-run this script after completing consent."
}

$finalEmail = Get-NullableString $status.email
if (-not ($finalEmail -ieq $ExpectedGoogleEmail)) {
    throw "Connected account is '$finalEmail', expected '$ExpectedGoogleEmail'. Run with -ForceReconnect and sign in with the expected account."
}

Write-Host ("SUCCESS: Bulk connect completed for {0}" -f $finalEmail) -ForegroundColor Green
Write-Host 'GA4 + GSC global OAuth tokens are now available for all projects.' -ForegroundColor Green
