/**
 * Xero Quote Tools
 * Handles quotes/estimates for customers
 */

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

const LineItemSchema = z.object({
  Description: z.string().optional(),
  Quantity: z.number().optional(),
  UnitAmount: z.number().optional(),
  ItemCode: z.string().optional(),
  AccountCode: z.string().optional(),
  TaxType: z.string().optional(),
  DiscountRate: z.number().optional(),
  LineAmount: z.number().optional()
});

const ContactSchema = z.object({
  ContactID: z.string().optional(),
  Name: z.string().optional()
});

export function getTools(_client: XeroClient): Tool[] {
  return [
    // List quotes
    {
      name: 'xero_list_quotes',
      description: 'List all quotes. Use where clause to filter by Status (DRAFT, SENT, ACCEPTED, DECLINED, INVOICED).',
      inputSchema: {
        type: 'object',
        properties: {
          page: { type: 'number', description: 'Page number (default 1)' },
          pageSize: { type: 'number', description: 'Page size (max 100)' },
          where: { type: 'string', description: 'Filter expression (e.g., Status=="SENT")' },
          order: { type: 'string', description: 'Order by field (e.g., Date DESC)' },
          ifModifiedSince: { type: 'string', description: 'ISO date to get only records modified since' }
        }
      }
    },

    // Get single quote
    {
      name: 'xero_get_quote',
      description: 'Get a specific quote by ID. Returns full details including line items.',
      inputSchema: {
        type: 'object',
        properties: {
          quoteId: { type: 'string', description: 'Quote ID (GUID)' }
        },
        required: ['quoteId']
      }
    },

    // Create quote
    {
      name: 'xero_create_quote',
      description: 'Create a new quote/estimate for a customer. Quotes can be converted to invoices.',
      inputSchema: {
        type: 'object',
        properties: {
          contact: {
            type: 'object',
            properties: {
              ContactID: { type: 'string', description: 'Customer contact ID (GUID)' },
              Name: { type: 'string', description: 'Customer name' }
            },
            description: 'Customer contact'
          },
          lineItems: {
            type: 'array',
            items: {
              type: 'object',
              properties: {
                Description: { type: 'string' },
                Quantity: { type: 'number' },
                UnitAmount: { type: 'number' },
                ItemCode: { type: 'string' },
                AccountCode: { type: 'string' },
                TaxType: { type: 'string' },
                DiscountRate: { type: 'number' }
              }
            },
            description: 'Line items (at least one required)'
          },
          date: { type: 'string', description: 'Quote date (YYYY-MM-DD)' },
          expiryDate: { type: 'string', description: 'Quote expiry date (YYYY-MM-DD)' },
          reference: { type: 'string', description: 'Reference text' },
          quoteNumber: { type: 'string', description: 'Quote number (optional, auto-generated)' },
          title: { type: 'string', description: 'Quote title' },
          summary: { type: 'string', description: 'Quote summary text' },
          terms: { type: 'string', description: 'Terms and conditions' },
          status: {
            type: 'string',
            enum: ['DRAFT', 'SENT'],
            description: 'Quote status (default: DRAFT)'
          },
          lineAmountTypes: {
            type: 'string',
            enum: ['Exclusive', 'Inclusive', 'NoTax'],
            description: 'How line amounts are calculated (default: Exclusive)'
          },
          currencyCode: { type: 'string', description: 'Currency code (e.g., USD)' }
        },
        required: ['contact', 'lineItems']
      }
    },

    // Update quote
    {
      name: 'xero_update_quote',
      description: 'Update an existing quote. Can update status, expiry date, terms, and line items.',
      inputSchema: {
        type: 'object',
        properties: {
          quoteId: { type: 'string', description: 'Quote ID (GUID)' },
          status: {
            type: 'string',
            enum: ['DRAFT', 'SENT', 'ACCEPTED', 'DECLINED'],
            description: 'New status'
          },
          expiryDate: { type: 'string', description: 'Quote expiry date (YYYY-MM-DD)' },
          title: { type: 'string', description: 'Quote title' },
          summary: { type: 'string', description: 'Quote summary' },
          terms: { type: 'string', description: 'Terms and conditions' },
          reference: { type: 'string', description: 'Reference text' },
          lineItems: {
            type: 'array',
            items: {
              type: 'object',
              properties: {
                Description: { type: 'string' },
                Quantity: { type: 'number' },
                UnitAmount: { type: 'number' },
                AccountCode: { type: 'string' }
              }
            }
          }
        },
        required: ['quoteId']
      }
    },

    // Convert quote to invoice
    {
      name: 'xero_convert_quote_to_invoice',
      description: 'Convert an ACCEPTED quote to an invoice. The quote status must be ACCEPTED.',
      inputSchema: {
        type: 'object',
        properties: {
          quoteId: { type: 'string', description: 'Quote ID (GUID)' }
        },
        required: ['quoteId']
      }
    }
  ];
}

export async function handleQuoteTool(
  toolName: string,
  args: Record<string, unknown>,
  client: XeroClient
): Promise<unknown> {
  switch (toolName) {
    case 'xero_list_quotes': {
      const options = {
        page: args.page as number | undefined,
        pageSize: args.pageSize as number | undefined,
        where: args.where as string | undefined,
        order: args.order as string | undefined,
        ifModifiedSince: args.ifModifiedSince ? new Date(args.ifModifiedSince as string) : undefined
      };
      return await client.getQuotes(options);
    }

    case 'xero_get_quote': {
      const { quoteId } = z.object({ quoteId: z.string() }).parse(args);
      return await client.getQuote(quoteId as any);
    }

    case 'xero_create_quote': {
      const schema = z.object({
        contact: ContactSchema,
        lineItems: z.array(LineItemSchema).min(1),
        date: z.string().optional(),
        expiryDate: z.string().optional(),
        reference: z.string().optional(),
        quoteNumber: z.string().optional(),
        title: z.string().optional(),
        summary: z.string().optional(),
        terms: z.string().optional(),
        status: z.enum(['DRAFT', 'SENT']).default('DRAFT'),
        lineAmountTypes: z.enum(['Exclusive', 'Inclusive', 'NoTax']).default('Exclusive'),
        currencyCode: z.string().optional()
      });
      const data = schema.parse(args);
      
      const quote: any = {
        Contact: data.contact,
        LineItems: data.lineItems,
        Status: data.status,
        LineAmountTypes: data.lineAmountTypes
      };
      
      if (data.date) quote.Date = data.date;
      if (data.expiryDate) quote.ExpiryDate = data.expiryDate;
      if (data.reference) quote.Reference = data.reference;
      if (data.quoteNumber) quote.QuoteNumber = data.quoteNumber;
      if (data.title) quote.Title = data.title;
      if (data.summary) quote.Summary = data.summary;
      if (data.terms) quote.Terms = data.terms;
      if (data.currencyCode) quote.CurrencyCode = data.currencyCode;
      
      return await client.createQuote(quote);
    }

    case 'xero_update_quote': {
      const schema = z.object({
        quoteId: z.string(),
        status: z.enum(['DRAFT', 'SENT', 'ACCEPTED', 'DECLINED']).optional(),
        expiryDate: z.string().optional(),
        title: z.string().optional(),
        summary: z.string().optional(),
        terms: z.string().optional(),
        reference: z.string().optional(),
        lineItems: z.array(LineItemSchema).optional()
      });
      const data = schema.parse(args);
      
      const updates: any = {};
      if (data.status) updates.Status = data.status;
      if (data.expiryDate) updates.ExpiryDate = data.expiryDate;
      if (data.title) updates.Title = data.title;
      if (data.summary) updates.Summary = data.summary;
      if (data.terms) updates.Terms = data.terms;
      if (data.reference) updates.Reference = data.reference;
      if (data.lineItems) updates.LineItems = data.lineItems;
      
      return await client.updateQuote(data.quoteId as any, updates);
    }

    case 'xero_convert_quote_to_invoice': {
      const { quoteId } = z.object({ quoteId: z.string() }).parse(args);
      
      // Get the quote first
      const quote = await client.getQuote(quoteId as any);
      
      // Verify it's ACCEPTED
      if ((quote as any).Status !== 'ACCEPTED') {
        throw new Error('Quote must be ACCEPTED before converting to invoice');
      }
      
      // Create an invoice from the quote
      const invoice: any = {
        Type: 'ACCREC',
        Contact: (quote as any).Contact,
        LineItems: (quote as any).LineItems,
        Reference: `Quote ${(quote as any).QuoteNumber || quoteId}`,
        Status: 'DRAFT',
        LineAmountTypes: (quote as any).LineAmountTypes
      };
      
      const createdInvoice = await client.createInvoice(invoice);
      
      // Update quote status to INVOICED
      await client.updateQuote(quoteId as any, { Status: 'INVOICED' as any });
      
      return {
        success: true,
        message: 'Quote converted to invoice',
        invoice: createdInvoice,
        quoteId
      };
    }

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