import { z } from 'zod'
import { createIntegrationTool } from '../../../tool'
import type { Tool } from '../../../../types'

/**
 * Create Apify run actor tool
 *
 * Runs an Apify actor, waits for completion, and returns dataset results.
 *
 * @param credentialName - Name of credential in credentials table
 * @returns Tool that runs Apify actors
 *
 * @example
 * const clutchScraper = createApifyRunActorTool('apify-elevasis')
 */
export function createApifyRunActorTool(credentialName: string): Tool {
  return createIntegrationTool({
    name: 'apify_run_actor',
    description: `Run an Apify actor and get results.

USE CASES:
- Run a web scraper or automation actor with custom input
- Wait for completion and get dataset items
- Automate lead generation, data extraction, and web automation tasks

COMMON ACTORS:
- curious_coder/clutch-scraper - Scrape marketing agencies from Clutch.co
- code_crafter/leads-finder - Find leads with ICP filtering
- compass/crawler-google-places - Scrape Google Maps businesses

REQUIRED PARAMETERS:
- actorId: Actor ID (e.g., "curious_coder/clutch-scraper")

OPTIONAL PARAMETERS:
- input: Actor input configuration (object, varies by actor)
- timeoutSecs: Max wait time in seconds (default: 300)
- pollIntervalSecs: Poll interval in seconds (default: 10)
- maxItems: Limit dataset items returned

EXAMPLE:
{
  "actorId": "curious_coder/clutch-scraper",
  "input": {
    "category": "digital-marketing",
    "location": "USA",
    "maxItems": 1000
  },
  "timeoutSecs": 300,
  "pollIntervalSecs": 10
}

OUTPUT:
{
  "status": "SUCCEEDED",
  "runId": "abc123",
  "datasetId": "xyz789",
  "items": [...scraped data...],
  "totalCount": 847,
  "executionTimeMs": 45000
}

TIMEOUT BEHAVIOR:
If actor exceeds timeoutSecs, returns status='TIMED_OUT' with empty items array.
Handle by increasing timeoutSecs or retrying with exponential backoff.`,

    inputSchema: z.object({
      actorId: z.string().describe('Actor ID (e.g., "curious_coder/clutch-scraper")'),
      input: z.record(z.string(), z.unknown()).optional().describe('Actor input configuration'),
      timeoutSecs: z.number().optional().describe('Max wait time in seconds (default: 300)'),
      pollIntervalSecs: z.number().optional().describe('Poll interval in seconds (default: 10)'),
      maxItems: z.number().optional().describe('Limit dataset items returned')
    }),

    outputSchema: z.object({
      status: z.enum(['SUCCEEDED', 'FAILED', 'ABORTED', 'TIMED_OUT']).describe('Run status'),
      runId: z.string().describe('Apify run ID'),
      datasetId: z.string().describe('Dataset ID containing results'),
      items: z.array(z.unknown()).describe('Dataset items (scraped data)'),
      totalCount: z.number().describe('Total items returned'),
      executionTimeMs: z.number().describe('Total execution time')
    }),

    integration: 'apify' as const,
    method: 'runActor' as const,
    credentialName
  })
}

/**
 * Create Apify get dataset items tool
 *
 * Fetches items from an Apify dataset by ID. Useful for recovering data
 * after a runActor timeout or fetching results from a previous run.
 *
 * @param credentialName - Name of credential in credentials table
 * @returns Tool that fetches Apify dataset items
 *
 * @example
 * const datasetFetcher = createApifyGetDatasetItemsTool('apify-elevasis')
 */
export function createApifyGetDatasetItemsTool(credentialName: string): Tool {
  return createIntegrationTool({
    name: 'apify_get_dataset_items',
    description: `Fetch items from an Apify dataset by ID.

USE CASES:
- Recover data after a runActor timeout (actor keeps running on Apify)
- Fetch results from a previously completed actor run
- Paginate through large datasets with offset/maxItems

REQUIRED PARAMETERS:
- datasetId: Dataset ID from a previous runActor result

OPTIONAL PARAMETERS:
- maxItems: Limit number of items returned
- offset: Skip first N items (for pagination)

EXAMPLE:
{
  "datasetId": "xyz789",
  "maxItems": 100,
  "offset": 0
}

OUTPUT:
{
  "items": [...dataset items...],
  "totalCount": 100
}`,

    inputSchema: z.object({
      datasetId: z.string().describe('Dataset ID from a previous Apify run'),
      maxItems: z.number().optional().describe('Limit number of items returned'),
      offset: z.number().optional().describe('Skip first N items (for pagination)')
    }),

    outputSchema: z.object({
      items: z.array(z.unknown()).describe('Dataset items'),
      totalCount: z.number().describe('Total items returned')
    }),

    integration: 'apify' as const,
    method: 'getDatasetItems' as const,
    credentialName
  })
}

/**
 * Create Apify start actor tool
 *
 * Starts an Apify actor run and returns immediately (async, no polling).
 * Results are delivered via webhook when the actor completes.
 *
 * @param credentialName - Name of credential in credentials table
 * @returns Tool that starts Apify actors asynchronously
 *
 * @example
 * const starter = createApifyStartActorTool('apify-elevasis')
 */
export function createApifyStartActorTool(credentialName: string): Tool {
  return createIntegrationTool({
    name: 'apify_start_actor',
    description: `Start an Apify actor run and return immediately (async, no polling).

USE CASES:
- Start a long-running web scraper without blocking the workflow
- Configure webhook to receive results when actor completes
- Fire-and-forget pattern for actors that take 10+ minutes

REQUIRED PARAMETERS:
- actorId: Actor ID (e.g., "apify/website-content-crawler")

OPTIONAL PARAMETERS:
- input: Actor input configuration
- webhooks: Array of webhook configs -- { eventTypes, requestUrl }
- timeoutSecs: Actor timeout on Apify's side (not workflow timeout)
- maxItems: Limit dataset items

EXAMPLE:
{
  "actorId": "apify/website-content-crawler",
  "input": { "startUrls": [{"url": "https://example.com"}] },
  "webhooks": [{ "eventTypes": ["ACTOR.RUN.SUCCEEDED"], "requestUrl": "https://api.elevasis.io/webhooks/apify?org=..." }]
}

OUTPUT:
{
  "status": "STARTED",
  "runId": "abc123",
  "datasetId": "xyz789"
}`,
    inputSchema: z.object({
      actorId: z.string().describe('Actor ID'),
      input: z.record(z.string(), z.unknown()).optional(),
      webhooks: z
        .array(
          z.object({
            eventTypes: z.array(z.string()),
            requestUrl: z.string(),
            payloadTemplate: z.string().optional(),
            headersTemplate: z.string().optional()
          })
        )
        .optional(),
      timeoutSecs: z.number().optional(),
      maxItems: z.number().optional()
    }),
    outputSchema: z.object({
      status: z.literal('STARTED'),
      runId: z.string(),
      datasetId: z.string()
    }),
    integration: 'apify' as const,
    method: 'startActor' as const,
    credentialName
  })
}
