import {
  createAction,
  Property,
  OAuth2PropertyValue,
} from '@activepieces/pieces-framework';
import { makeRequest } from '../common';
import { pinterestAuth } from '../common/auth';
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
import {
  adAccountIdDropdown,
  boardIdDropdown,
  boardSectionIdDropdown,
  pinIdMultiSelectDropdown,
} from '../common/props';

export const createPin = createAction({
  auth: pinterestAuth,
  name: 'createPin',
  displayName: 'Create Pin',
  description: 'Upload an image or video to create a new Pin on a board.',
  audience: 'both',
  aiMetadata: {
    description:
      'Creates a Pin on a Pinterest board by uploading media from a hosted image/video URL (or base64 image). Use to publish visual content to a board the user owns. Requires a valid board_id and a media source; each call creates a new Pin, so it is not idempotent.',
    idempotent: false,
  },
  props: {
    ad_account_id: adAccountIdDropdown,
    board_id: boardIdDropdown,
    board_section_id: boardSectionIdDropdown,
    title: Property.ShortText({
      displayName: 'Title',
      required: true,
      description: 'The title of the Pin (max 100 characters).',
    }),
    description: Property.LongText({
      displayName: 'Description',
      required: false,
      description: 'The description of the Pin (max 800 characters).',
    }),
    media_source_type: Property.StaticDropdown({
      displayName: 'Media Source Type',
      required: true,
      description: 'The type of media source for the Pin.',
      options: {
        options: [
          { label: 'Image URL', value: 'image_url' },
          { label: 'Base64 Image', value: 'image_base64' },
          { label: 'Video URL', value: 'video_url' },
        ],
      },
    }),
    media_url: Property.ShortText({
      displayName: 'Media URL',
      required: true,
      description:
        'The URL of the image or video to upload. Must be a valid URL.',
    }),
    link: Property.ShortText({
      displayName: 'Destination Link',
      required: false,
      description:
        'The destination URL that the Pin will link to when clicked.',
    }),
    dominant_color: Property.ShortText({
      displayName: 'Dominant Color',
      description:
        'The dominant color of the Pin as a hex color code (e.g., "#6E7874").',
      required: false,
    }),
    alt_text: Property.ShortText({
      displayName: 'Alt Text',
      description:
        'Alternative text for accessibility and screen readers (max 500 characters).',
      required: false,
    }),
    parent_pin_id: Property.ShortText({
      displayName: 'Parent Pin ID',
      description:
        'The ID of the original Pin if this is a saved/repinned Pin.',
      required: false,
    }),
    sponsor_id: Property.ShortText({
      displayName: 'Sponsor ID',
      description:
        'The sponsor account ID for paid partnership content. Available only to select users in closed beta.',
      required: false,
    }),
    product_tags: pinIdMultiSelectDropdown,
    note: Property.ShortText({
      displayName: 'Note',
      description: 'A private note for this Pin that only you can see.',
      required: false,
    }),
    is_removable: Property.Checkbox({
      displayName: 'Is Removable',
      description:
        'Set to true to create an ad-only Pin that can be easily removed.',
      required: false,
      defaultValue: false,
    }),
  },
  async run({ auth, propsValue }) {
    const {
      board_id,
      board_section_id,
      title,
      description,
      media_source_type,
      media_url,
      link,
      dominant_color,
      alt_text,
      parent_pin_id,
      is_removable,
      product_tags,
      ad_account_id,
      note,
      sponsor_id,
    } = propsValue;

    // Validation
    if (title && title.length > 100) {
      throw new Error('Title must be 100 characters or less');
    }

    if (description && description.length > 800) {
      throw new Error('Description must be 800 characters or less');
    }

    if (alt_text && alt_text.length > 500) {
      throw new Error('Alt text must be 500 characters or less');
    }

    // URL validation for media_url
    try {
      new URL(media_url);
    } catch {
      throw new Error('Please enter a valid URL for Image/Video URL');
    }

    // URL validation for link (if provided)
    if (link) {
      try {
        new URL(link);
      } catch {
        throw new Error('Please enter a valid URL for Destination Link');
      }
    }

    // Hex color validation for dominant_color (if provided)
    if (dominant_color) {
      const hexColorRegex = /^#[0-9A-Fa-f]{6}$/;
      if (!hexColorRegex.test(dominant_color)) {
        throw new Error(
          'Pin Color must be a valid hex color format (e.g., #6E7874)'
        );
      }
    }

    // Build request body according to Pinterest API spec
    const body: any = {
      board_id,
      title,
      media_source: {
        source_type: media_source_type,
        url: media_url,
      },
    };

    // Add optional fields only if they have values
    if (board_section_id) body.board_section_id = board_section_id;
    if (description) body.description = description;
    if (link) body.link = link;
    if (dominant_color) body.dominant_color = dominant_color;
    if (alt_text) body.alt_text = alt_text;
    if (parent_pin_id) body.parent_pin_id = parent_pin_id;
    if (note) body.note = note;
    if (sponsor_id) body.sponsor_id = sponsor_id;
    if (typeof is_removable === 'boolean') body.is_removable = is_removable;

    // Handle product_tags array
    if (
      product_tags &&
      Array.isArray(product_tags) &&
      product_tags.length > 0
    ) {
      body.product_tags = product_tags;
    }

    // Build API path
    let path = '/pins';
    if (ad_account_id) {
      path = `/pins?ad_account_id=${encodeURIComponent(ad_account_id)}`;
    }

    return await makeRequest(
      getAccessTokenOrThrow(auth),
      HttpMethod.POST,
      path,
      body
    );
  },
});
