import type { GustoClient } from '../clients/gusto.js';
import type { Payroll, PayPeriod } from '../types/index.js';

export function createPayrollTools(client: GustoClient) {
  return {
    // List payrolls for a company
    list_payrolls: async (args: {
      company_id: string;
      start_date?: string;
      end_date?: string;
      page?: number;
      per?: number;
    }) => {
      const params: any = { page: args.page, per: args.per };
      if (args.start_date) params.start_date = args.start_date;
      if (args.end_date) params.end_date = args.end_date;

      const payrolls = await client.getPaginated<Payroll>(
        `/companies/${args.company_id}/payrolls`,
        params
      );
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(payrolls, null, 2),
          },
        ],
      };
    },

    // Get a specific payroll
    get_payroll: async (args: { payroll_id: string; show_calculation?: boolean }) => {
      const params: any = {};
      if (args.show_calculation) params.show_calculation = 'true';

      const payroll = await client.get<Payroll>(`/payrolls/${args.payroll_id}`, params);
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(payroll, null, 2),
          },
        ],
      };
    },

    // Create a new off-cycle payroll
    create_payroll: async (args: {
      company_id: string;
      start_date: string;
      end_date: string;
      check_date: string;
      employee_ids?: string[];
    }) => {
      const payroll = await client.post<Payroll>(`/companies/${args.company_id}/payrolls`, {
        start_date: args.start_date,
        end_date: args.end_date,
        check_date: args.check_date,
        employee_ids: args.employee_ids,
      });
      return {
        content: [
          {
            type: 'text',
            text: `Payroll created successfully:\n${JSON.stringify(payroll, null, 2)}`,
          },
        ],
      };
    },

    // Update a payroll
    update_payroll: async (args: {
      payroll_id: string;
      version: string;
      employee_compensations?: any[];
    }) => {
      const payroll = await client.put<Payroll>(`/payrolls/${args.payroll_id}`, {
        version: args.version,
        employee_compensations: args.employee_compensations,
      });
      return {
        content: [
          {
            type: 'text',
            text: `Payroll updated successfully:\n${JSON.stringify(payroll, null, 2)}`,
          },
        ],
      };
    },

    // Calculate a payroll
    calculate_payroll: async (args: { payroll_id: string }) => {
      const payroll = await client.put<Payroll>(`/payrolls/${args.payroll_id}/calculate`, {});
      return {
        content: [
          {
            type: 'text',
            text: `Payroll calculated successfully:\n${JSON.stringify(payroll, null, 2)}`,
          },
        ],
      };
    },

    // Submit a payroll
    submit_payroll: async (args: { payroll_id: string }) => {
      const payroll = await client.put<Payroll>(`/payrolls/${args.payroll_id}/submit`, {});
      return {
        content: [
          {
            type: 'text',
            text: `Payroll submitted successfully:\n${JSON.stringify(payroll, null, 2)}`,
          },
        ],
      };
    },

    // Cancel a payroll
    cancel_payroll: async (args: { payroll_id: string }) => {
      const payroll = await client.put<Payroll>(`/payrolls/${args.payroll_id}/cancel`, {});
      return {
        content: [
          {
            type: 'text',
            text: `Payroll cancelled successfully:\n${JSON.stringify(payroll, null, 2)}`,
          },
        ],
      };
    },

    // List pay periods for a company
    list_pay_periods: async (args: {
      company_id: string;
      start_date?: string;
      end_date?: string;
    }) => {
      const params: any = {};
      if (args.start_date) params.start_date = args.start_date;
      if (args.end_date) params.end_date = args.end_date;

      const payPeriods = await client.get<PayPeriod[]>(
        `/companies/${args.company_id}/pay_periods`,
        params
      );
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(payPeriods, null, 2),
          },
        ],
      };
    },
  };
}

export const payrollToolDefinitions = [
  {
    name: 'list_payrolls',
    description: 'List all payrolls for a company with optional date filtering',
    inputSchema: {
      type: 'object',
      properties: {
        company_id: { type: 'string', description: 'Company ID' },
        start_date: { type: 'string', description: 'Filter by start date (YYYY-MM-DD)' },
        end_date: { type: 'string', description: 'Filter by end date (YYYY-MM-DD)' },
        page: { type: 'number', description: 'Page number (default: 1)' },
        per: { type: 'number', description: 'Results per page (default: 25)' },
      },
      required: ['company_id'],
    },
  },
  {
    name: 'get_payroll',
    description: 'Get detailed information about a specific payroll',
    inputSchema: {
      type: 'object',
      properties: {
        payroll_id: { type: 'string', description: 'Payroll ID' },
        show_calculation: {
          type: 'boolean',
          description: 'Include calculation details',
        },
      },
      required: ['payroll_id'],
    },
  },
  {
    name: 'create_payroll',
    description: 'Create a new off-cycle payroll',
    inputSchema: {
      type: 'object',
      properties: {
        company_id: { type: 'string', description: 'Company ID' },
        start_date: { type: 'string', description: 'Pay period start date (YYYY-MM-DD)' },
        end_date: { type: 'string', description: 'Pay period end date (YYYY-MM-DD)' },
        check_date: { type: 'string', description: 'Check date (YYYY-MM-DD)' },
        employee_ids: {
          type: 'array',
          items: { type: 'string' },
          description: 'Employee IDs to include in payroll',
        },
      },
      required: ['company_id', 'start_date', 'end_date', 'check_date'],
    },
  },
  {
    name: 'update_payroll',
    description: 'Update employee compensations in a payroll',
    inputSchema: {
      type: 'object',
      properties: {
        payroll_id: { type: 'string', description: 'Payroll ID' },
        version: { type: 'string', description: 'Version for optimistic locking' },
        employee_compensations: {
          type: 'array',
          description: 'Employee compensation details',
        },
      },
      required: ['payroll_id', 'version'],
    },
  },
  {
    name: 'calculate_payroll',
    description: 'Calculate taxes and deductions for a payroll',
    inputSchema: {
      type: 'object',
      properties: {
        payroll_id: { type: 'string', description: 'Payroll ID' },
      },
      required: ['payroll_id'],
    },
  },
  {
    name: 'submit_payroll',
    description: 'Submit a payroll for processing',
    inputSchema: {
      type: 'object',
      properties: {
        payroll_id: { type: 'string', description: 'Payroll ID' },
      },
      required: ['payroll_id'],
    },
  },
  {
    name: 'cancel_payroll',
    description: 'Cancel a payroll before it is processed',
    inputSchema: {
      type: 'object',
      properties: {
        payroll_id: { type: 'string', description: 'Payroll ID' },
      },
      required: ['payroll_id'],
    },
  },
  {
    name: 'list_pay_periods',
    description: 'List pay periods for a company',
    inputSchema: {
      type: 'object',
      properties: {
        company_id: { type: 'string', description: 'Company ID' },
        start_date: { type: 'string', description: 'Filter by start date (YYYY-MM-DD)' },
        end_date: { type: 'string', description: 'Filter by end date (YYYY-MM-DD)' },
      },
      required: ['company_id'],
    },
  },
];
