import { z } from 'zod'
import type { Tool } from '../../../../types'
import { createIntegrationTool } from '../../../tool'
import { EmailSchema } from '../../../../../../../platform/utils/validation'

/**
 * Create a tool that generates Stripe payment links
 *
 * @param credentialName - Name of the Stripe credential to use
 * @returns Tool instance
 *
 * @example
 * ```typescript
 * const tool = createStripeCreatePaymentLinkTool('elevasis-stripe')
 * const result = await tool.execute({
 *   priceId: 'price_xxx',
 *   metadata: { deal_id: 'deal-123' },
 *   redirectUrl: 'https://app.elevasis.io/payment-success'
 * }, context)
 * ```
 */
export function createStripeCreatePaymentLinkTool(credentialName: string): Tool {
  return createIntegrationTool({
    name: 'stripe_create_payment_link',
    description: `Create a Stripe payment link for collecting payments.

Use this tool to generate a payment URL that can be sent to customers.
The link directs to Stripe's hosted checkout page.

Examples:
- Create link for proposal payment: priceId, metadata with deal_id, redirectUrl
- Create link with invoice: set invoiceCreation=true`,
    inputSchema: z.object({
      priceId: z.string().describe('Stripe price ID (price_xxx)'),
      quantity: z.number().optional().default(1).describe('Quantity of items'),
      metadata: z.record(z.string(), z.string()).optional().describe('Custom metadata'),
      afterCompletionType: z
        .enum(['redirect', 'hosted_confirmation'])
        .optional()
        .describe('What happens after payment'),
      redirectUrl: z.string().url().optional().describe('URL to redirect after payment'),
      allowPromotionCodes: z.boolean().optional().describe('Allow promo codes'),
      automaticTax: z.boolean().optional().describe('Enable automatic tax'),
      billingAddressCollection: z.enum(['auto', 'required']).optional().describe('Billing address mode'),
      invoiceCreation: z.boolean().optional().describe('Generate invoice')
    }),
    outputSchema: z.object({
      id: z.string().describe('Payment link ID (plink_xxx)'),
      url: z.string().describe('Shareable payment URL'),
      active: z.boolean().describe('Whether the link is active'),
      livemode: z.boolean().describe('Whether in production mode')
    }),
    integration: 'stripe' as const,
    method: 'createPaymentLink' as const,
    credentialName
  })
}

/**
 * Create a tool that retrieves a Stripe payment link
 *
 * @param credentialName - Name of the Stripe credential to use
 * @returns Tool instance
 *
 * @example
 * ```typescript
 * const tool = createStripeGetPaymentLinkTool('elevasis-stripe')
 * const result = await tool.execute({
 *   paymentLinkId: 'plink_xxx'
 * }, context)
 * ```
 */
export function createStripeGetPaymentLinkTool(credentialName: string): Tool {
  return createIntegrationTool({
    name: 'stripe_get_payment_link',
    description: `Get details of a Stripe payment link.

Use this tool to retrieve information about an existing payment link,
including its URL, status, and metadata.

Useful for:
- Checking if a payment link is still active
- Retrieving the URL for a previously created link
- Accessing metadata associated with the link`,
    inputSchema: z.object({
      paymentLinkId: z.string().describe('Payment link ID (plink_xxx)')
    }),
    outputSchema: z.object({
      id: z.string().describe('Payment link ID'),
      url: z.string().describe('Shareable payment URL'),
      active: z.boolean().describe('Whether the link is active'),
      livemode: z.boolean().describe('Whether in production mode'),
      metadata: z.record(z.string(), z.string()).describe('Custom metadata')
    }),
    integration: 'stripe' as const,
    method: 'getPaymentLink' as const,
    credentialName
  })
}

/**
 * Create a tool that updates a Stripe payment link
 *
 * @param credentialName - Name of the Stripe credential to use
 * @returns Tool instance
 *
 * @example
 * ```typescript
 * const tool = createStripeUpdatePaymentLinkTool('elevasis-stripe')
 * const result = await tool.execute({
 *   paymentLinkId: 'plink_xxx',
 *   active: false // Deactivate the link
 * }, context)
 * ```
 */
export function createStripeUpdatePaymentLinkTool(credentialName: string): Tool {
  return createIntegrationTool({
    name: 'stripe_update_payment_link',
    description: `Update a Stripe payment link.

Use this tool to modify an existing payment link.
Common operations:
- Deactivate a link (set active=false)
- Update metadata

Note: You cannot change the price after creation.`,
    inputSchema: z.object({
      paymentLinkId: z.string().describe('Payment link ID (plink_xxx)'),
      active: z.boolean().optional().describe('Enable or disable the link'),
      metadata: z.record(z.string(), z.string()).optional().describe('Update metadata')
    }),
    outputSchema: z.object({
      id: z.string().describe('Payment link ID'),
      active: z.boolean().describe('Whether the link is active'),
      url: z.string().describe('Shareable payment URL')
    }),
    integration: 'stripe' as const,
    method: 'updatePaymentLink' as const,
    credentialName
  })
}

/**
 * Create a tool that lists Stripe payment links
 *
 * @param credentialName - Name of the Stripe credential to use
 * @returns Tool instance
 *
 * @example
 * ```typescript
 * const tool = createStripeListPaymentLinksTool('elevasis-stripe')
 * const result = await tool.execute({
 *   active: true,
 *   limit: 10
 * }, context)
 * ```
 */
export function createStripeListPaymentLinksTool(credentialName: string): Tool {
  return createIntegrationTool({
    name: 'stripe_list_payment_links',
    description: `List Stripe payment links.

Use this tool to retrieve a list of payment links.
Supports filtering by active status and pagination.

Useful for:
- Finding active payment links
- Auditing created links
- Paginating through large numbers of links`,
    inputSchema: z.object({
      active: z.boolean().optional().describe('Filter by active status'),
      limit: z.number().min(1).max(100).optional().describe('Number of links to return (1-100)'),
      startingAfter: z.string().optional().describe('Cursor for pagination (payment link ID)'),
      endingBefore: z.string().optional().describe('Cursor for pagination (payment link ID)')
    }),
    outputSchema: z.object({
      data: z
        .array(
          z.object({
            id: z.string().describe('Payment link ID'),
            url: z.string().describe('Shareable payment URL'),
            active: z.boolean().describe('Whether the link is active'),
            metadata: z.record(z.string(), z.string()).describe('Custom metadata')
          })
        )
        .describe('List of payment links'),
      hasMore: z.boolean().describe('Whether more results are available')
    }),
    integration: 'stripe' as const,
    method: 'listPaymentLinks' as const,
    credentialName
  })
}

/**
 * Create a tool that generates Stripe checkout sessions for custom amounts
 *
 * Use this for variable/custom pricing where the amount comes from the proposal.
 * Unlike payment links (which require pre-defined price IDs), checkout sessions
 * support price_data with any unit_amount.
 *
 * @param credentialName - Name of the Stripe credential to use
 * @returns Tool instance
 *
 * @example
 * ```typescript
 * const tool = createStripeCheckoutSessionTool('elevasis-stripe')
 * const result = await tool.execute({
 *   amount: 2400000, // $24,000 in cents
 *   metadata: { deal_id: 'deal-123' },
 *   successUrl: 'https://app.elevasis.io/payment-success',
 *   cancelUrl: 'https://app.elevasis.io/payment-cancelled'
 * }, context)
 * ```
 */
export function createStripeCheckoutSessionTool(credentialName: string): Tool {
  return createIntegrationTool({
    name: 'stripe_create_checkout_session',
    description: `Create a Stripe checkout session for custom-amount payments.

Use this tool for variable pricing where the amount comes from the proposal.
Creates a one-time payment URL that expires in 24 hours.

Key differences from payment links:
- Supports any amount (no pre-defined price IDs needed)
- URL expires in 24 hours (must recreate if needed)
- Created per-transaction (not reusable)

Examples:
- Collect payment for signed proposal: amount from proposal, metadata with deal_id
- Customer receives hosted Stripe checkout page`,
    inputSchema: z.object({
      amount: z.number().int().positive().describe('Amount in cents (e.g., 2400000 for $24,000)'),
      currency: z.string().optional().default('usd').describe('Currency code (default: usd)'),
      productName: z.string().optional().describe('Product name shown in checkout'),
      productDescription: z.string().optional().describe('Product description'),
      metadata: z.record(z.string(), z.string()).optional().describe('Metadata (deal_id, etc.)'),
      successUrl: z.string().url().describe('URL after successful payment'),
      cancelUrl: z.string().url().describe('URL if customer cancels'),
      customerEmail: EmailSchema.optional().describe('Pre-fill customer email')
    }),
    outputSchema: z.object({
      id: z.string().describe('Session ID (cs_xxx)'),
      url: z.string().describe('Payment URL (expires in 24h)'),
      expiresAt: z.number().describe('Expiration timestamp (Unix seconds)')
    }),
    integration: 'stripe' as const,
    method: 'createCheckoutSession' as const,
    credentialName
  })
}

/**
 * Create a tool that generates Stripe payment links with dynamic pricing
 *
 * Unlike standard payment links (which require pre-created Price IDs),
 * this tool uses inline price_data for dynamic pricing. Supports both
 * one-time setup fees and recurring monthly subscriptions.
 *
 * @param credentialName - Name of the Stripe credential to use
 * @returns Tool instance
 *
 * @example
 * ```typescript
 * const tool = createStripeAutoPaymentLinkTool('elevasis-stripe')
 * const result = await tool.execute({
 *   dealId: 'deal-123',
 *   companyName: 'Acme Corp',
 *   contactEmail: 'john@acme.com',
 *   initialFee: 3000,  // $3,000 one-time
 *   monthlyFee: 500    // $500/month recurring
 * }, context)
 * ```
 */
export function createStripeAutoPaymentLinkTool(credentialName: string): Tool {
  return createIntegrationTool({
    name: 'stripe_create_auto_payment_link',
    description: `Create a Stripe payment link with dynamic pricing (inline price_data).

Use this tool for variable pricing with both one-time and recurring fees.
URLs NEVER EXPIRE - same link can be used in all reminder emails.

Key features:
- Supports dynamic amounts (no pre-defined Price IDs needed)
- Can include both one-time setup fee AND monthly recurring in one link
- URL never expires (unlike checkout sessions)
- Metadata propagates to all webhooks (checkout.session.completed, etc.)

Examples:
- Setup + monthly: initialFee=3000, monthlyFee=500 ($3,000 one-time + $500/month)
- Monthly only: initialFee=0, monthlyFee=500 ($500/month subscription)
- One-time only: initialFee=3000, monthlyFee=0 ($3,000 one-time payment)`,
    inputSchema: z.object({
      dealId: z.string().describe('Local deal ID for metadata'),
      companyName: z.string().describe('Company name for product description'),
      contactEmail: EmailSchema.describe('Contact email for metadata'),
      initialFee: z.number().min(0).describe('One-time setup fee in dollars (e.g., 3000 for $3,000)'),
      monthlyFee: z.number().min(0).describe('Recurring monthly fee in dollars (e.g., 500 for $500/month)')
    }),
    outputSchema: z.object({
      paymentLinkId: z.string().describe('Payment link ID (plink_xxx)'),
      url: z.string().describe('Payment URL (NEVER EXPIRES)'),
      hasInitialFee: z.boolean().describe('Whether link includes one-time fee'),
      hasRecurring: z.boolean().describe('Whether link includes recurring subscription')
    }),
    integration: 'stripe' as const,
    method: 'createAutoPaymentLink' as const,
    credentialName
  })
}
