/**
 * Xero Account Tools
 * Handles chart of accounts - bank accounts, expense accounts, revenue accounts, etc.
 */

import { z } from 'zod';
import { XeroClient } from '../clients/xero.js';
import type { Tool } from '@modelcontextprotocol/sdk/types.js';

export function getTools(_client: XeroClient): Tool[] {
  return [
    // List accounts
    {
      name: 'xero_list_accounts',
      description: 'List all accounts in the chart of accounts. Use where clause to filter by Type, Class, or Status.',
      inputSchema: {
        type: 'object',
        properties: {
          where: { type: 'string', description: 'Filter expression (e.g., Type=="BANK" or Status=="ACTIVE")' },
          order: { type: 'string', description: 'Order by field (e.g., Code ASC)' },
          includeArchived: { type: 'boolean', description: 'Include archived accounts' },
          ifModifiedSince: { type: 'string', description: 'ISO date to get only records modified since' }
        }
      }
    },

    // Get single account
    {
      name: 'xero_get_account',
      description: 'Get a specific account by ID. Returns full account details.',
      inputSchema: {
        type: 'object',
        properties: {
          accountId: { type: 'string', description: 'Account ID (GUID)' }
        },
        required: ['accountId']
      }
    },

    // Create account
    {
      name: 'xero_create_account',
      description: 'Create a new account in the chart of accounts. Code and Type are required.',
      inputSchema: {
        type: 'object',
        properties: {
          code: { type: 'string', description: 'Account code (e.g., 200, 310)' },
          name: { type: 'string', description: 'Account name' },
          type: {
            type: 'string',
            enum: [
              'BANK', 'CURRENT', 'CURRLIAB', 'DEPRECIATN', 'DIRECTCOSTS',
              'EQUITY', 'EXPENSE', 'FIXED', 'INVENTORY', 'LIABILITY',
              'NONCURRENT', 'OTHERINCOME', 'OVERHEADS', 'PREPAYMENT',
              'REVENUE', 'SALES', 'TERMLIAB', 'PAYGLIABILITY',
              'SUPERANNUATIONEXPENSE', 'SUPERANNUATIONLIABILITY', 'WAGESEXPENSE'
            ],
            description: 'Account type'
          },
          description: { type: 'string', description: 'Account description' },
          taxType: { type: 'string', description: 'Tax type (e.g., INPUT, OUTPUT, NONE)' },
          enablePaymentsToAccount: { type: 'boolean', description: 'Enable payments to this account (for bank accounts)' },
          showInExpenseClaims: { type: 'boolean', description: 'Show in expense claims' },
          bankAccountNumber: { type: 'string', description: 'Bank account number (for BANK type)' },
          bankAccountType: {
            type: 'string',
            enum: ['BANK', 'CREDITCARD', 'PAYPAL'],
            description: 'Bank account type (for BANK type accounts)'
          },
          currencyCode: { type: 'string', description: 'Currency code (e.g., USD)' }
        },
        required: ['code', 'type']
      }
    },

    // Update account
    {
      name: 'xero_update_account',
      description: 'Update an existing account. Can update name, description, tax type, and other fields.',
      inputSchema: {
        type: 'object',
        properties: {
          accountId: { type: 'string', description: 'Account ID (GUID)' },
          code: { type: 'string', description: 'Account code' },
          name: { type: 'string', description: 'Account name' },
          description: { type: 'string', description: 'Account description' },
          taxType: { type: 'string', description: 'Tax type' },
          enablePaymentsToAccount: { type: 'boolean', description: 'Enable payments to this account' },
          showInExpenseClaims: { type: 'boolean', description: 'Show in expense claims' }
        },
        required: ['accountId']
      }
    },

    // Archive account
    {
      name: 'xero_archive_account',
      description: 'Archive an account. Archived accounts are hidden but can be restored.',
      inputSchema: {
        type: 'object',
        properties: {
          accountId: { type: 'string', description: 'Account ID (GUID)' }
        },
        required: ['accountId']
      }
    },

    // Delete account
    {
      name: 'xero_delete_account',
      description: 'Delete an account. Only accounts with no transactions can be deleted.',
      inputSchema: {
        type: 'object',
        properties: {
          accountId: { type: 'string', description: 'Account ID (GUID)' }
        },
        required: ['accountId']
      }
    }
  ];
}

export async function handleAccountTool(
  toolName: string,
  args: Record<string, unknown>,
  client: XeroClient
): Promise<unknown> {
  switch (toolName) {
    case 'xero_list_accounts': {
      const options = {
        where: args.where as string | undefined,
        order: args.order as string | undefined,
        includeArchived: args.includeArchived as boolean | undefined,
        ifModifiedSince: args.ifModifiedSince ? new Date(args.ifModifiedSince as string) : undefined
      };
      return await client.getAccounts(options);
    }

    case 'xero_get_account': {
      const { accountId } = z.object({ accountId: z.string() }).parse(args);
      return await client.getAccount(accountId as any);
    }

    case 'xero_create_account': {
      const schema = z.object({
        code: z.string(),
        name: z.string().optional(),
        type: z.enum([
          'BANK', 'CURRENT', 'CURRLIAB', 'DEPRECIATN', 'DIRECTCOSTS',
          'EQUITY', 'EXPENSE', 'FIXED', 'INVENTORY', 'LIABILITY',
          'NONCURRENT', 'OTHERINCOME', 'OVERHEADS', 'PREPAYMENT',
          'REVENUE', 'SALES', 'TERMLIAB', 'PAYGLIABILITY',
          'SUPERANNUATIONEXPENSE', 'SUPERANNUATIONLIABILITY', 'WAGESEXPENSE'
        ]),
        description: z.string().optional(),
        taxType: z.string().optional(),
        enablePaymentsToAccount: z.boolean().optional(),
        showInExpenseClaims: z.boolean().optional(),
        bankAccountNumber: z.string().optional(),
        bankAccountType: z.enum(['BANK', 'CREDITCARD', 'PAYPAL']).optional(),
        currencyCode: z.string().optional()
      });
      const data = schema.parse(args);
      
      const account: any = {
        Code: data.code,
        Type: data.type
      };
      
      if (data.name) account.Name = data.name;
      if (data.description) account.Description = data.description;
      if (data.taxType) account.TaxType = data.taxType;
      if (data.enablePaymentsToAccount !== undefined) account.EnablePaymentsToAccount = data.enablePaymentsToAccount;
      if (data.showInExpenseClaims !== undefined) account.ShowInExpenseClaims = data.showInExpenseClaims;
      if (data.bankAccountNumber) account.BankAccountNumber = data.bankAccountNumber;
      if (data.bankAccountType) account.BankAccountType = data.bankAccountType;
      if (data.currencyCode) account.CurrencyCode = data.currencyCode;
      
      return await client.createAccount(account);
    }

    case 'xero_update_account': {
      const schema = z.object({
        accountId: z.string(),
        code: z.string().optional(),
        name: z.string().optional(),
        description: z.string().optional(),
        taxType: z.string().optional(),
        enablePaymentsToAccount: z.boolean().optional(),
        showInExpenseClaims: z.boolean().optional()
      });
      const data = schema.parse(args);
      
      const updates: any = {};
      if (data.code) updates.Code = data.code;
      if (data.name) updates.Name = data.name;
      if (data.description) updates.Description = data.description;
      if (data.taxType) updates.TaxType = data.taxType;
      if (data.enablePaymentsToAccount !== undefined) updates.EnablePaymentsToAccount = data.enablePaymentsToAccount;
      if (data.showInExpenseClaims !== undefined) updates.ShowInExpenseClaims = data.showInExpenseClaims;
      
      return await client.updateAccount(data.accountId as any, updates);
    }

    case 'xero_archive_account': {
      const { accountId } = z.object({ accountId: z.string() }).parse(args);
      return await client.updateAccount(accountId as any, { Status: 'ARCHIVED' });
    }

    case 'xero_delete_account': {
      const { accountId } = z.object({ accountId: z.string() }).parse(args);
      await client.deleteAccount(accountId as any);
      return { success: true, message: 'Account deleted' };
    }

    default:
      throw new Error(`Unknown account tool: ${toolName}`);
  }
}
