// ============================================
// GOOGLE ADS API AUTHENTICATION
// ============================================

import type { GoogleAdsConfig } from "./types.js";

const TOKEN_URL = "https://oauth2.googleapis.com/token";

interface TokenResponse {
  access_token: string;
  expires_in: number;
  token_type: string;
}

export class GoogleAdsAuth {
  private config: GoogleAdsConfig;
  private accessToken: string | null = null;
  private tokenExpiry: number = 0;

  constructor(config: GoogleAdsConfig) {
    this.config = config;
  }

  async getAccessToken(): Promise<string> {
    // Return cached token if still valid (with 60s buffer)
    if (this.accessToken && Date.now() < this.tokenExpiry - 60_000) {
      return this.accessToken;
    }

    const response = await fetch(TOKEN_URL, {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: new URLSearchParams({
        client_id: this.config.clientId,
        client_secret: this.config.clientSecret,
        refresh_token: this.config.refreshToken,
        grant_type: "refresh_token",
      }),
    });

    if (!response.ok) {
      const error = await response.text();
      throw new Error(`Token refresh failed: ${response.status} — ${error}`);
    }

    const data = (await response.json()) as TokenResponse;
    this.accessToken = data.access_token;
    this.tokenExpiry = Date.now() + data.expires_in * 1000;

    return this.accessToken;
  }

  getHeaders(customerId?: string): Record<string, string> {
    const headers: Record<string, string> = {
      "developer-token": this.config.developerToken,
      "Content-Type": "application/json",
    };

    if (this.config.loginCustomerId) {
      headers["login-customer-id"] = this.config.loginCustomerId.replace(/-/g, "");
    }

    return headers;
  }

  static fromEnv(): GoogleAdsAuth {
    // Support inline JSON config (like samihalawa's approach)
    const jsonConfig = process.env.GOOGLE_ADS_CONFIG;
    if (jsonConfig) {
      try {
        const parsed = JSON.parse(jsonConfig);
        return new GoogleAdsAuth({
          clientId: parsed.client_id,
          clientSecret: parsed.client_secret,
          developerToken: parsed.developer_token,
          refreshToken: parsed.refresh_token,
          loginCustomerId: parsed.login_customer_id,
          customerId: process.env.GOOGLE_ADS_CUSTOMER_ID,
        });
      } catch {
        throw new Error("Invalid GOOGLE_ADS_CONFIG JSON");
      }
    }

    // Support individual env vars
    const clientId = process.env.GOOGLE_ADS_CLIENT_ID;
    const clientSecret = process.env.GOOGLE_ADS_CLIENT_SECRET;
    const developerToken = process.env.GOOGLE_ADS_DEVELOPER_TOKEN;
    const refreshToken = process.env.GOOGLE_ADS_REFRESH_TOKEN;

    if (!clientId || !clientSecret || !developerToken || !refreshToken) {
      throw new Error(
        "Missing Google Ads credentials. Set GOOGLE_ADS_CONFIG (JSON) or individual env vars: " +
          "GOOGLE_ADS_CLIENT_ID, GOOGLE_ADS_CLIENT_SECRET, GOOGLE_ADS_DEVELOPER_TOKEN, GOOGLE_ADS_REFRESH_TOKEN"
      );
    }

    return new GoogleAdsAuth({
      clientId,
      clientSecret,
      developerToken,
      refreshToken,
      loginCustomerId: process.env.GOOGLE_ADS_LOGIN_CUSTOMER_ID,
      customerId: process.env.GOOGLE_ADS_CUSTOMER_ID,
    });
  }
}
