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

/**
 * Create a tool that creates SignatureAPI envelopes for electronic signatures
 *
 * @param credentialName - Name of the SignatureAPI credential to use
 * @returns Tool instance
 *
 * @example
 * ```typescript
 * const tool = createSignatureApiCreateEnvelopeTool('signatureapi-prod')
 * const result = await tool.execute({
 *   input: {
 *     title: 'Elevasis Proposal - Acme Corp',
 *     documents: [{ name: 'proposal.pdf', url: 'https://...', places: [...] }],
 *     recipients: [{ key: 'signer1', type: 'signer', name: 'John', email: 'john@acme.com' }]
 *   },
 *   executionContext: context
 * })
 * // result: { id: 'env_xxx', status: 'processing', signingUrl: 'https://...' }
 * ```
 */
export function createSignatureApiCreateEnvelopeTool(credentialName: string): Tool {
  return createIntegrationTool({
    name: 'signatureapi_create_envelope',
    description: `Create a SignatureAPI envelope for electronic signatures.

Use this tool to send documents for signing. An envelope is a container
that holds documents and manages the signing process.

Examples:
- Create proposal envelope: title, documents with PDF URLs, recipients with signers
- Include signature fields: specify page, x, y positions for signature placement
- Use 'date' for auto-populated signing date (maps to recipient_completed_date)

The envelope will be sent to recipients via email with a signing link.`,
    inputSchema: z.object({
      title: z.string().describe('Envelope title (shown in emails)'),
      message: z.string().optional().describe('Custom message for recipient emails'),
      documents: z
        .array(
          z.object({
            name: z.string().describe('Document filename'),
            url: z.string().url().describe('Publicly accessible URL to PDF document'),
            places: z
              .array(
                z.object({
                  recipientKey: z.string().describe('Links to recipient key'),
                  type: z
                    .enum(['signature', 'date', 'text', 'initials'])
                    .describe('Field type (date maps to recipient_completed_date)'),
                  page: z.number().describe('Page number (1-indexed, -1 for last)'),
                  x: z.number().describe('X position in points'),
                  y: z.number().describe('Y position in points'),
                  width: z.number().optional(),
                  height: z.number().optional()
                })
              )
              .optional()
              .describe('Signature field placements')
          })
        )
        .describe('Documents to sign'),
      recipients: z
        .array(
          z.object({
            key: z.string().describe('Unique identifier for this recipient'),
            type: z.enum(['signer', 'viewer', 'approver']),
            name: z.string().describe('Recipient full name'),
            email: EmailSchema.describe('Recipient email'),
            language: z.string().optional().describe('Language code (en, es, fr)')
          })
        )
        .describe('Recipients/signers'),
      metadata: z.record(z.string(), z.string()).optional().describe('Custom metadata (e.g., deal_id)'),
      webhookUrl: z.string().url().optional().describe('Override default webhook URL'),
      routing: z.enum(['parallel', 'sequential']).optional().describe('How to route to multiple recipients')
    }),
    outputSchema: z.object({
      id: z.string().describe('Envelope ID (env_xxx)'),
      status: z.string().describe('Envelope status'),
      signingUrl: z.string().optional().describe('URL for first signer')
    }),
    integration: 'signature-api' as const,
    method: 'createEnvelope' as const,
    credentialName
  })
}

/**
 * Create a tool that voids/cancels SignatureAPI envelopes
 *
 * @param credentialName - Name of the SignatureAPI credential to use
 * @returns Tool instance
 *
 * @example
 * ```typescript
 * const tool = createSignatureApiVoidEnvelopeTool('signatureapi-prod')
 * const result = await tool.execute({
 *   input: {
 *     envelopeId: 'env_xxx',
 *     reason: 'Revision requested by recipient'
 *   },
 *   executionContext: context
 * })
 * // result: { id: 'env_xxx', status: 'voided' }
 * ```
 */
export function createSignatureApiVoidEnvelopeTool(credentialName: string): Tool {
  return createIntegrationTool({
    name: 'signatureapi_void_envelope',
    description: `Void/cancel a pending SignatureAPI envelope.

Use this tool to cancel an envelope that hasn't been completed yet.
Voided envelopes cannot be signed.

Common reasons:
- Revision requested by recipient
- Error in document content
- Deal cancelled`,
    inputSchema: z.object({
      envelopeId: z.string().describe('Envelope ID to void (env_xxx)'),
      reason: z.string().optional().describe('Reason for voiding')
    }),
    outputSchema: z.object({
      id: z.string().describe('Envelope ID'),
      status: z.literal('voided').describe('Status after voiding')
    }),
    integration: 'signature-api' as const,
    method: 'voidEnvelope' as const,
    credentialName
  })
}

/**
 * Create a tool that downloads signed documents from SignatureAPI
 *
 * @param credentialName - Name of the SignatureAPI credential to use
 * @returns Tool instance
 *
 * @example
 * ```typescript
 * const tool = createSignatureApiDownloadDocumentTool('signatureapi-prod')
 * const result = await tool.execute({
 *   input: {
 *     envelopeId: 'env_xxx',
 *     documentType: 'combined'
 *   },
 *   executionContext: context
 * })
 * // result: { content: Buffer, contentType: 'application/pdf', filename: 'env_xxx-signed.pdf' }
 * ```
 */
export function createSignatureApiDownloadDocumentTool(credentialName: string): Tool {
  return createIntegrationTool({
    name: 'signatureapi_download_document',
    description: `Download signed document from a completed envelope.

Use this tool to retrieve the signed PDF after all recipients have signed.
The combined document includes all documents and an audit trail.

Document types:
- combined: All documents merged with audit trail (default)
- original: Original unsigned documents
- audit: Audit trail only`,
    inputSchema: z.object({
      envelopeId: z.string().describe('Envelope ID (env_xxx)'),
      documentType: z.enum(['combined', 'original', 'audit']).optional().describe('Type of document to download')
    }),
    outputSchema: z.object({
      content: z.instanceof(Buffer).describe('PDF content as Buffer'),
      contentType: z.string().describe('MIME type'),
      filename: z.string().describe('Suggested filename')
    }),
    integration: 'signature-api' as const,
    method: 'downloadDocument' as const,
    credentialName
  })
}
