import { storeCredential, type OAuthCredentials, type Platform } from './credential-store.js';

interface TokenResponse {
  access_token: string;
  refresh_token?: string;
  expires_in?: number;
}

async function postRefresh(url: string, body: URLSearchParams): Promise<TokenResponse | null> {
  try {
    const res = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: body.toString(),
      signal: AbortSignal.timeout(15000),
    });
    if (!res.ok) {
      console.warn(`[token-refresh] HTTP ${res.status} from ${url}`);
      return null;
    }
    return await res.json() as TokenResponse;
  } catch (err) {
    console.error(`[token-refresh] request failed:`, err);
    return null;
  }
}

export async function tryRefreshToken(
  customerId: string,
  platform: Platform,
  creds: OAuthCredentials
): Promise<OAuthCredentials | null> {
  let data: TokenResponse | null = null;

  if (platform === 'linkedin') {
    data = await postRefresh('https://www.linkedin.com/oauth/v2/accessToken', new URLSearchParams({
      grant_type: 'refresh_token',
      refresh_token: creds.refreshToken!,
      client_id: process.env.LINKEDIN_CLIENT_ID ?? '',
      client_secret: process.env.LINKEDIN_CLIENT_SECRET ?? '',
    }));

  } else if (platform === 'twitter') {
    const credentials = Buffer.from(
      `${process.env.TWITTER_CLIENT_ID ?? ''}:${process.env.TWITTER_CLIENT_SECRET ?? ''}`
    ).toString('base64');
    try {
      const res = await fetch('https://api.twitter.com/2/oauth2/token', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Authorization': `Basic ${credentials}`,
        },
        body: new URLSearchParams({
          grant_type: 'refresh_token',
          refresh_token: creds.refreshToken!,
        }).toString(),
        signal: AbortSignal.timeout(15000),
      });
      if (res.ok) data = await res.json() as TokenResponse;
      else console.warn(`[token-refresh] twitter HTTP ${res.status}`);
    } catch (err) {
      console.error(`[token-refresh] twitter error:`, err);
    }

  } else if (platform === 'tiktok') {
    data = await postRefresh('https://open.tiktokapis.com/v2/oauth/token/', new URLSearchParams({
      grant_type: 'refresh_token',
      refresh_token: creds.refreshToken!,
      client_key: process.env.TIKTOK_CLIENT_KEY ?? '',
      client_secret: process.env.TIKTOK_CLIENT_SECRET ?? '',
    }));

  } else if (platform === 'instagram' || platform === 'facebook') {
    // Facebook long-lived token exchange uses the current access token, not refresh token
    try {
      const url = new URL('https://graph.facebook.com/oauth/access_token');
      url.searchParams.set('grant_type', 'fb_exchange_token');
      url.searchParams.set('client_id', process.env.FACEBOOK_APP_ID ?? '');
      url.searchParams.set('client_secret', process.env.FACEBOOK_APP_SECRET ?? '');
      url.searchParams.set('fb_exchange_token', creds.accessToken);
      const res = await fetch(url.toString(), { signal: AbortSignal.timeout(15000) });
      if (res.ok) data = await res.json() as TokenResponse;
      else console.warn(`[token-refresh] ${platform} HTTP ${res.status}`);
    } catch (err) {
      console.error(`[token-refresh] ${platform} error:`, err);
    }
  }

  if (!data?.access_token) return null;

  const refreshed: OAuthCredentials = {
    accessToken: data.access_token,
    refreshToken: data.refresh_token ?? creds.refreshToken,
    expiresAt: data.expires_in ? Date.now() + data.expires_in * 1000 : undefined,
    scope: creds.scope,
  };

  await storeCredential(customerId, platform, refreshed);
  console.log(`[token-refresh] ${platform} refreshed for customer ${customerId}`);
  return refreshed;
}
