import { z } from 'zod';
import { StripeClient } from '../clients/stripe.js';
import { Payout } from '../types/index.js';

const metadataSchema = z.record(z.string()).optional().describe('Set of key-value pairs for storing additional information');

export default [
  {
    name: 'stripe_list_payouts',
    description: 'List all payouts with optional filtering and pagination',
    inputSchema: z.object({
      limit: z.number().min(1).max(100).optional().describe('Number of payouts to return (1-100)'),
      starting_after: z.string().optional().describe('Cursor for pagination'),
      ending_before: z.string().optional().describe('Cursor for pagination'),
      arrival_date: z.union([
        z.number(),
        z.object({
          gt: z.number().optional(),
          gte: z.number().optional(),
          lt: z.number().optional(),
          lte: z.number().optional(),
        })
      ]).optional().describe('Filter by arrival date timestamp or range'),
      created: z.union([
        z.number(),
        z.object({
          gt: z.number().optional(),
          gte: z.number().optional(),
          lt: z.number().optional(),
          lte: z.number().optional(),
        })
      ]).optional().describe('Filter by creation timestamp or range'),
      destination: z.string().optional().describe('Filter by destination bank account ID'),
      status: z.enum(['paid', 'pending', 'in_transit', 'canceled', 'failed']).optional().describe('Filter by status')
    }),
    handler: async (client: StripeClient, args: any) => {
      return await client.list<Payout>('/payouts', args);
    }
  },
  {
    name: 'stripe_get_payout',
    description: 'Retrieve a specific payout by ID',
    inputSchema: z.object({
      payout_id: z.string().describe('The ID of the payout to retrieve'),
      expand: z.array(z.string()).optional().describe('Fields to expand (e.g., ["destination"])')
    }),
    handler: async (client: StripeClient, args: any) => {
      const { payout_id, expand } = args;
      const params = expand ? { expand } : undefined;
      return await client.retrieve<Payout>('/payouts', payout_id, params);
    }
  },
  {
    name: 'stripe_create_payout',
    description: 'Create a manual payout',
    inputSchema: z.object({
      amount: z.number().positive().describe('Amount in cents to pay out'),
      currency: z.string().describe('Three-letter ISO currency code (e.g., "usd")'),
      description: z.string().optional().describe('Arbitrary description'),
      metadata: metadataSchema,
      destination: z.string().optional().describe('Bank account ID (defaults to default bank account)'),
      method: z.enum(['standard', 'instant']).optional().describe('Payout method (default: standard)'),
      source_type: z.enum(['card', 'bank_account', 'fpx']).optional().describe('Source balance type'),
      statement_descriptor: z.string().optional().describe('Statement descriptor')
    }),
    handler: async (client: StripeClient, args: any) => {
      return await client.create<Payout>('/payouts', args, {
        idempotencyKey: client.generateIdempotencyKey()
      });
    }
  },
  {
    name: 'stripe_update_payout',
    description: 'Update a payout (limited fields can be updated)',
    inputSchema: z.object({
      payout_id: z.string().describe('The ID of the payout to update'),
      metadata: metadataSchema
    }),
    handler: async (client: StripeClient, args: any) => {
      const { payout_id, ...data } = args;
      return await client.update<Payout>('/payouts', payout_id, data);
    }
  },
  {
    name: 'stripe_cancel_payout',
    description: 'Cancel a pending payout',
    inputSchema: z.object({
      payout_id: z.string().describe('The ID of the payout to cancel')
    }),
    handler: async (client: StripeClient, args: any) => {
      return await client.post<Payout>(`/payouts/${args.payout_id}/cancel`, {});
    }
  },
  {
    name: 'stripe_reverse_payout',
    description: 'Reverse a payout (creates a new payout that reverses the original)',
    inputSchema: z.object({
      payout_id: z.string().describe('The ID of the payout to reverse'),
      metadata: metadataSchema
    }),
    handler: async (client: StripeClient, args: any) => {
      const { payout_id, ...data } = args;
      return await client.post<Payout>(`/payouts/${payout_id}/reverse`, data);
    }
  }
];
