import { createAction, Property } from '@activepieces/pieces-framework';
import { ApitemplateAuth } from '../common/auth';
import { ApitemplateRegion, makeRequest } from '../common/client';
import { HttpMethod } from '@activepieces/pieces-common';

export const createPdfFromUrl = createAction({
  auth: ApitemplateAuth,
  name: 'createPdfFromUrl',
  displayName: 'Create PDF From URL',
  description: 'Creates a PDF from a webpage URL.',
  audience: 'both',
  aiMetadata: { description: 'Renders a new PDF by loading and capturing a live webpage at the given URL, with optional page settings (size, orientation, margins), viewport sizing, full-page capture, and wait-for-selector/timeout controls for dynamic content. Use when the source is a public web page rather than supplied HTML or a saved template. Requires the URL. Not idempotent: each call generates and stores a new PDF.', idempotent: false },
  props: {
    url: Property.ShortText({
      displayName: 'URL',
      description: 'The URL of the webpage to convert to PDF',
      required: true,
    }),
    expiration: Property.Number({
      displayName: 'Expiration (minutes)',
      description: 'Expiration of the generated PDF in minutes. Use 0 to store permanently, or 1-10080 minutes (7 days) to specify expiration.',
      required: false,
    }),
    pageSize: Property.StaticDropdown({
      displayName: 'Page Size',
      description: 'PDF page size format',
      required: false,
      defaultValue: 'A4',
      options: {
        options: [
          { label: 'A4', value: 'A4' },
          { label: 'A3', value: 'A3' },
          { label: 'A5', value: 'A5' },
          { label: 'Letter', value: 'Letter' },
          { label: 'Legal', value: 'Legal' },
          { label: 'Tabloid', value: 'Tabloid' },
        ],
      },
    }),
    orientation: Property.StaticDropdown({
      displayName: 'Page Orientation',
      description: 'PDF page orientation',
      required: false,
      defaultValue: 'portrait',
      options: {
        options: [
          { label: 'Portrait', value: 'portrait' },
          { label: 'Landscape', value: 'landscape' },
        ],
      },
    }),
    marginTop: Property.Number({
      displayName: 'Margin Top (mm)',
      description: 'Top margin in millimeters',
      required: false,
    }),
    marginBottom: Property.Number({
      displayName: 'Margin Bottom (mm)',
      description: 'Bottom margin in millimeters',
      required: false,
    }),
    marginLeft: Property.Number({
      displayName: 'Margin Left (mm)',
      description: 'Left margin in millimeters',
      required: false,
    }),
    marginRight: Property.Number({
      displayName: 'Margin Right (mm)',
      description: 'Right margin in millimeters',
      required: false,
    }),
    printBackground: Property.Checkbox({
      displayName: 'Print Background',
      description: 'Whether to print background graphics and colors',
      required: false,
      defaultValue: true,
    }),
    headerFontSize: Property.ShortText({
      displayName: 'Header Font Size',
      description: 'Font size for header (e.g., "9px")',
      required: false,
    }),
    displayHeaderFooter: Property.Checkbox({
      displayName: 'Display Header/Footer',
      description: 'Whether to display header and footer',
      required: false,
      defaultValue: false,
    }),
    customHeader: Property.LongText({
      displayName: 'Custom Header HTML',
      description: 'Custom HTML content for header',
      required: false,
    }),
    customFooter: Property.LongText({
      displayName: 'Custom Footer HTML',
      description: 'Custom HTML content for footer',
      required: false,
    }),
    scale: Property.Number({
      displayName: 'Scale',
      description: 'Scale factor for the PDF (0.1 to 2.0)',
      required: false,
    }),
    waitForTimeout: Property.Number({
      displayName: 'Wait Timeout (ms)',
      description: 'Time to wait for page to load before generating PDF (in milliseconds)',
      required: false,
    }),
    waitForSelector: Property.ShortText({
      displayName: 'Wait for Selector',
      description: 'CSS selector to wait for before generating PDF (e.g., ".content-loaded")',
      required: false,
    }),
    viewportWidth: Property.Number({
      displayName: 'Viewport Width',
      description: 'Browser viewport width in pixels (default: 1920)',
      required: false,
      defaultValue: 1920,
    }),
    viewportHeight: Property.Number({
      displayName: 'Viewport Height',
      description: 'Browser viewport height in pixels (default: 1080)',
      required: false,
      defaultValue: 1080,
    }),
    fullPage: Property.Checkbox({
      displayName: 'Full Page',
      description: 'Capture the full scrollable page',
      required: false,
      defaultValue: true,
    }),
    meta: Property.ShortText({
      displayName: 'External Reference ID',
      description: 'Specify an external reference ID for your own reference',
      required: false,
    }),
  },
  async run({ auth, propsValue }) {
    const authConfig = auth.props;
    const {
      url,
      expiration,
      pageSize,
      orientation,
      marginTop,
      marginBottom,
      marginLeft,
      marginRight,
      printBackground,
      headerFontSize,
      displayHeaderFooter,
      customHeader,
      customFooter,
      scale,
      waitForTimeout,
      waitForSelector,
      viewportWidth,
      viewportHeight,
      fullPage,
      meta,
    } = propsValue;

    // Build query parameters for basic options
    const queryParams = new URLSearchParams();


    if (expiration !== undefined && expiration !== 0) {
      queryParams.append('expiration', expiration.toString());
    }

    if (meta) {
      queryParams.append('meta', meta);
    }

    const endpoint = `/create-pdf-from-url${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;

    // Build settings object for page configuration
    const settings: any = {};

    if (pageSize && pageSize !== 'A4') {
      settings.paper_size = pageSize;
    }

    if (orientation) {
      settings.orientation = orientation === 'landscape' ? '1' : '0';
    }

    if (marginTop !== undefined) {
      settings.margin_top = marginTop.toString();
    }

    if (marginBottom !== undefined) {
      settings.margin_bottom = marginBottom.toString();
    }

    if (marginLeft !== undefined) {
      settings.margin_left = marginLeft.toString();
    }

    if (marginRight !== undefined) {
      settings.margin_right = marginRight.toString();
    }

    if (printBackground !== undefined) {
      settings.print_background = printBackground ? '1' : '0';
    }

    if (headerFontSize) {
      settings.header_font_size = headerFontSize;
    }

    if (displayHeaderFooter !== undefined) {
      settings.displayHeaderFooter = displayHeaderFooter;
    }

    if (customHeader) {
      settings.custom_header = customHeader;
    }

    if (customFooter) {
      settings.custom_footer = customFooter;
    }

    if (scale !== undefined) {
      settings.scale = scale.toString();
    }

    if (waitForTimeout !== undefined) {
      settings.wait_for_timeout = waitForTimeout.toString();
    }

    if (waitForSelector) {
      settings.wait_for_selector = waitForSelector;
    }

    if (viewportWidth !== undefined && viewportWidth !== 1920) {
      settings.viewport_width = viewportWidth.toString();
    }

    if (viewportHeight !== undefined && viewportHeight !== 1080) {
      settings.viewport_height = viewportHeight.toString();
    }

    if (fullPage !== undefined) {
      settings.full_page = fullPage ? '1' : '0';
    }

    // Build request body
    const requestBody: any = {
      url: url,
    };

    if (Object.keys(settings).length > 0) {
      requestBody.settings = settings;
    }

    try {
      const response = await makeRequest(
        authConfig.apiKey,
        HttpMethod.POST,
        endpoint,
        requestBody,
        undefined,
        authConfig.region as ApitemplateRegion
      );

      return response;
    } catch (error: any) {
    
      if (error.message.includes('502') && authConfig.region !== 'default') {
        throw new Error(
          `${error.message}\n\nThe ${authConfig.region} region appears to be experiencing issues. ` +
          `Consider switching to the 'default' region in your authentication settings or try again later.`
        );
      }
      throw error;
    }
  },
});