import {
  createTrigger,
  TriggerStrategy,
  PiecePropValueSchema,
  Property,
  OAuth2PropertyValue,
  AppConnectionValueForAuthProperty,
} from '@activepieces/pieces-framework';
import {
  DedupeStrategy,
  Polling,
  pollingHelper,
  HttpMethod,
  getAccessTokenOrThrow,
} from '@activepieces/pieces-common';
import dayjs from 'dayjs';
import { makeRequest } from '../common';
import { pinterestAuth } from '../common/auth';
import { adAccountIdDropdown, boardIdDropdown } from '../common/props';

const polling: Polling<
  AppConnectionValueForAuthProperty<typeof pinterestAuth>,
  Record<string, any>
> = {
  strategy: DedupeStrategy.TIMEBASED,
  items: async ({ propsValue, auth, lastFetchEpochMS }) => {
    const { board_id, ad_account_id, creative_types } = propsValue;
    let bookmark: string | undefined = undefined;
    let pins: any[] = [];
    let pageCount = 0;
    const maxPages = 10; // Limit to prevent excessive API calls
    const initialPageSize = 25; // Smaller initial page size for faster response

    do {
      pageCount++;
      // Build query parameters
      const searchParams = new URLSearchParams();
      searchParams.append('page_size', initialPageSize.toString());
      if (bookmark) {
        searchParams.append('bookmark', bookmark);
      }

      if (ad_account_id) {
        searchParams.append('ad_account_id', ad_account_id);
      }

      // Add creative_types filter if specified
      if (creative_types && creative_types.length > 0) {
        creative_types.forEach((type: string) => {
          searchParams.append('creative_types', type);
        });
      }

      const queryString = searchParams.toString();
      const path = `/boards/${board_id}/pins${
        queryString ? `?${queryString}` : ''
      }`;
      try {
        const response = await makeRequest(
          getAccessTokenOrThrow(auth as OAuth2PropertyValue),
          HttpMethod.GET,
          path
        );
        const items = response.items || [];
        bookmark = response.bookmark;

        // If this is not the first run, filter items by timestamp immediately
        if (lastFetchEpochMS) {
          const newItems = items.filter(
            (item: any) => dayjs(item.created_at).valueOf() > lastFetchEpochMS
          );

          pins = pins.concat(newItems);

          // Break early if no new items found in this page
          if (newItems.length === 0) {
            break;
          }

          // Break early if we found items older than last fetch
          const hasOldItems = items.some(
            (item: any) => dayjs(item.created_at).valueOf() <= lastFetchEpochMS
          );
          if (hasOldItems) {
            break;
          }

          // Rate limiting awareness - add delay between requests
          if (bookmark && pageCount < maxPages) {
            await new Promise((resolve) => setTimeout(resolve, 100)); // 100ms delay
          }
        } else {
          // First run - collect all items
          pins = pins.concat(items);
        }
      } catch (error) {
        console.error(`Error fetching pins for board ${board_id}:`, error);
        break; // Stop pagination on error
      }
    } while (bookmark);

    // Sort by creation date (newest first) for consistent ordering
    pins.sort(
      (a, b) => dayjs(b.created_at).valueOf() - dayjs(a.created_at).valueOf()
    );

    return pins.map((item) => ({
      epochMilliSeconds: dayjs(item.created_at).valueOf(),
      data: item,
    }));
  },
};

export const newPinOnBoard = createTrigger({
  auth: pinterestAuth,
  name: 'newPinOnBoard',
  displayName: 'New Pin on Board',
  description: 'Fires when a new Pin is added to a specific board.',
  aiMetadata: {
    description:
      'Fires when a new Pin is added to a specific board (selected by board_id), emitting the Pin record. Polls that board for Pins created since the last check, optionally filtered by creative type (regular, video, shopping, carousel, idea).',
  },
  props: {
    board_id: boardIdDropdown,
    ad_account_id: adAccountIdDropdown,
    creative_types: Property.StaticMultiSelectDropdown({
      displayName: 'Pin Types to Watch',
      required: false,
      options: {
        options: [
          { label: 'Regular Pins', value: 'REGULAR' },
          { label: 'Video Pins', value: 'VIDEO' },
          { label: 'Shopping Pins', value: 'SHOPPING' },
          { label: 'Carousel Pins', value: 'CAROUSEL' },
          { label: 'Idea Pins', value: 'IDEA' },
        ],
      },
      description:
        'Filter by specific pin types. Leave empty to watch all types.',
    }),
  },
  sampleData: {
    items: [
      {
        id: '813744226420795884',
        created_at: '2020-01-01T20:10:40-00:00',
        link: 'https://www.pinterest.com/',
        title: 'string',
        description: 'string',
        dominant_color: '#6E7874',
        alt_text: 'string',
        creative_type: 'REGULAR',
        board_id: 'string',
        board_section_id: 'string',
        board_owner: {
          username: 'string',
        },
        is_owner: 'false',
        media: {
          media_type: 'string',
          images: {
            '150x150': {
              width: 150,
              height: 150,
              url: 'https://i.pinimg.com/150x150/0d/f6/f1/0df6f1f0bfe7aaca849c1bbc3607a34b.jpg',
            },
            '400x300': {
              width: 400,
              height: 300,
              url: 'https://i.pinimg.com/400x300/0d/f6/f1/0df6f1f0bfe7aaca849c1bbc3607a34b.jpg',
            },
            '600x': {
              width: 600,
              height: 600,
              url: 'https://i.pinimg.com/600x/0d/f6/f1/0df6f1f0bfe7aaca849c1bbc3607a34b.jpg',
            },
            '1200x': {
              width: 1200,
              height: 1200,
              url: 'https://i.pinimg.com/1200x/0d/f6/f1/0df6f1f0bfe7aaca849c1bbc3607a34b.jpg',
            },
          },
        },
        parent_pin_id: 'string',
        is_standard: 'false',
        has_been_promoted: 'false',
        product_tags: [
          {
            pin_id: '903972677830',
          },
        ],
        note: 'string',
        pin_metrics: {
          '90d': {
            pin_click: 7,
            impression: 2,
            clickthrough: 3,
          },
          lifetime_metrics: {
            pin_click: 7,
            impression: 2,
            clickthrough: 3,
            reaction: 10,
            comment: 2,
          },
        },
        is_removable: true,
      },
    ],
    bookmark: 'string',
  },
  type: TriggerStrategy.POLLING,
  async test(context) {
    return await pollingHelper.test(polling, context);
  },
  async onEnable(context) {
    const { store, auth, propsValue } = context;
    await pollingHelper.onEnable(polling, { store, auth, propsValue });
  },
  async onDisable(context) {
    const { store, auth, propsValue } = context;
    await pollingHelper.onDisable(polling, { store, auth, propsValue });
  },
  async run(context) {
    return await pollingHelper.poll(polling, context);
  },
});
