import { z } from 'zod';
import { StripeClient } from '../clients/stripe.js';
import { Price } 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_prices',
    description: 'List all prices with optional filtering and pagination',
    inputSchema: z.object({
      limit: z.number().min(1).max(100).optional().describe('Number of prices to return (1-100)'),
      starting_after: z.string().optional().describe('Cursor for pagination'),
      ending_before: z.string().optional().describe('Cursor for pagination'),
      active: z.boolean().optional().describe('Filter by active status'),
      currency: z.string().optional().describe('Filter by currency (e.g., "usd")'),
      product: z.string().optional().describe('Filter by product ID'),
      type: z.enum(['one_time', 'recurring']).optional().describe('Filter by price type'),
      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'),
      recurring: z.object({
        interval: z.enum(['day', 'week', 'month', 'year']).optional(),
        usage_type: z.enum(['metered', 'licensed']).optional()
      }).optional().describe('Filter recurring prices')
    }),
    handler: async (client: StripeClient, args: any) => {
      return await client.list<Price>('/prices', args);
    }
  },
  {
    name: 'stripe_get_price',
    description: 'Retrieve a specific price by ID',
    inputSchema: z.object({
      price_id: z.string().describe('The ID of the price to retrieve'),
      expand: z.array(z.string()).optional().describe('Fields to expand (e.g., ["product"])')
    }),
    handler: async (client: StripeClient, args: any) => {
      const { price_id, expand } = args;
      const params = expand ? { expand } : undefined;
      return await client.retrieve<Price>('/prices', price_id, params);
    }
  },
  {
    name: 'stripe_create_price',
    description: 'Create a new price',
    inputSchema: z.object({
      currency: z.string().describe('Three-letter ISO currency code (e.g., "usd")'),
      product: z.string().optional().describe('Product ID (or use product_data to create inline)'),
      product_data: z.object({
        name: z.string(),
        active: z.boolean().optional(),
        metadata: metadataSchema
      }).optional().describe('Create product inline'),
      unit_amount: z.number().optional().describe('Amount in cents (e.g., 1000 = $10.00). Omit for custom prices.'),
      unit_amount_decimal: z.string().optional().describe('Decimal string for sub-cent precision'),
      active: z.boolean().optional().describe('Whether price is active (default true)'),
      metadata: metadataSchema,
      nickname: z.string().optional().describe('Brief description of the price'),
      recurring: z.object({
        interval: z.enum(['day', 'week', 'month', 'year']),
        interval_count: z.number().optional().describe('Number of intervals (default 1)'),
        aggregate_usage: z.enum(['sum', 'last_during_period', 'last_ever', 'max']).optional().describe('For metered usage'),
        usage_type: z.enum(['metered', 'licensed']).optional().describe('Default: licensed'),
        trial_period_days: z.number().optional().describe('Trial days for subscriptions')
      }).optional().describe('Recurring price configuration'),
      billing_scheme: z.enum(['per_unit', 'tiered']).optional().describe('Default: per_unit'),
      tiers: z.array(z.object({
        up_to: z.union([z.number(), z.literal('inf')]),
        unit_amount: z.number().optional(),
        unit_amount_decimal: z.string().optional(),
        flat_amount: z.number().optional(),
        flat_amount_decimal: z.string().optional()
      })).optional().describe('Tiers for tiered billing'),
      tiers_mode: z.enum(['graduated', 'volume']).optional().describe('For tiered billing'),
      tax_behavior: z.enum(['inclusive', 'exclusive', 'unspecified']).optional().describe('Tax calculation'),
      custom_unit_amount: z.object({
        enabled: z.boolean(),
        minimum: z.number().optional(),
        maximum: z.number().optional(),
        preset: z.number().optional()
      }).optional().describe('Customer chooses price'),
      lookup_key: z.string().optional().describe('Lookup key for price'),
      transfer_lookup_key: z.boolean().optional().describe('Transfer lookup_key from product')
    }),
    handler: async (client: StripeClient, args: any) => {
      return await client.create<Price>('/prices', args, {
        idempotencyKey: client.generateIdempotencyKey()
      });
    }
  },
  {
    name: 'stripe_update_price',
    description: 'Update a price (limited fields can be updated)',
    inputSchema: z.object({
      price_id: z.string().describe('The ID of the price to update'),
      active: z.boolean().optional().describe('Activate or deactivate price'),
      metadata: metadataSchema,
      nickname: z.string().optional(),
      lookup_key: z.string().optional(),
      tax_behavior: z.enum(['inclusive', 'exclusive', 'unspecified']).optional()
    }),
    handler: async (client: StripeClient, args: any) => {
      const { price_id, ...data } = args;
      return await client.update<Price>('/prices', price_id, data);
    }
  }
];
