/**
 * Ad Library Flow — navigate to Facebook's Ad Library for a page and
 * scrape all available ad creatives and metadata.
 */

import type { BrowserContext } from '../cdp.js';
import type { NetworkInterceptor, GraphQLResponse } from '../network.js';
import type { FbAdData } from '../../../types.js';
import { delay, naturalScroll, idlePause } from '../human.js';
import { extractAds } from '../extract/index.js';

function ts(): string {
  return new Date().toISOString();
}

const AD_LIBRARY_BASE = 'https://www.facebook.com/ads/library/';

/**
 * Navigate to the Ad Library for a given page and collect all ads.
 */
export async function collectAds(
  ctx: BrowserContext,
  interceptor: NetworkInterceptor,
  pageId: string,
): Promise<FbAdData[]> {
  const url =
    `${AD_LIBRARY_BASE}?active_status=all&ad_type=all&country=ALL&view_all_page_id=${pageId}`;

  console.log(`[${ts()}] ▶ ad-library: navigating to Ad Library for page ${pageId}`);

  const collected = new Map<string, FbAdData>();

  const onGraphQL = (response: GraphQLResponse) => {
    try {
      const ads = extractAds(response.body);
      if (!ads) return;
      for (const ad of ads) {
        if (ad.ad_id && !collected.has(ad.ad_id)) {
          collected.set(ad.ad_id, ad);
        }
      }
    } catch {
      // Ignore unrelated responses
    }
  };

  interceptor.on('graphql', onGraphQL);

  try {
    await ctx.evaluate(`window.location.href = ${JSON.stringify(url)}`);
    await delay(4000 + Math.random() * 2000);

    console.log(`[${ts()}]   Ad Library loaded, scrolling through results…`);

    // Scroll to load more ads
    const MAX_SCROLLS = 15;
    const MAX_EMPTY_SCROLLS = 3;
    let emptyScrolls = 0;

    for (let s = 0; s < MAX_SCROLLS && emptyScrolls < MAX_EMPTY_SCROLLS; s++) {
      const sizeBefore = collected.size;

      await naturalScroll(ctx, 600 + Math.random() * 400);
      await delay(2000 + Math.random() * 1500);

      // Click "See more" or "Load more" buttons if present
      await tryClickLoadMore(ctx);

      if (collected.size === sizeBefore) {
        emptyScrolls++;
        console.log(
          `[${ts()}]   no new ads after scroll (${emptyScrolls}/${MAX_EMPTY_SCROLLS})`,
        );
      } else {
        emptyScrolls = 0;
        console.log(`[${ts()}]   ${collected.size} ads collected so far`);
      }
    }

    await idlePause();

    console.log(`[${ts()}] ✓ ad-library: collected ${collected.size} ads`);
    return Array.from(collected.values());
  } finally {
    interceptor.off('graphql', onGraphQL);
  }
}

/**
 * Click "See more results" or similar pagination buttons in the Ad Library.
 */
async function tryClickLoadMore(ctx: BrowserContext): Promise<void> {
  try {
    await ctx.evaluate(`
      (() => {
        const btns = [...document.querySelectorAll('button, [role="button"], a')];
        const loadMore = btns.find(el => {
          const text = el.textContent?.trim().toLowerCase() ?? '';
          return text.includes('see more') ||
                 text.includes('load more') ||
                 text.includes('show more');
        });
        if (loadMore) (loadMore as HTMLElement).click();
      })()
    `);
  } catch {
    // Non-critical
  }
}
