/**
 * Case management tools
 */

import type { SalesforceClient } from '../clients/salesforce.js';
import type { Case } from '../types/index.js';

export function getTools(client: SalesforceClient) {
  return [
    {
      name: 'sf_list_cases',
      description: 'List cases with optional filters. Returns up to 200 cases by default.',
      inputSchema: {
        type: 'object',
        properties: {
          limit: {
            type: 'number',
            description: 'Maximum number of cases to return (default: 200)',
            default: 200,
          },
          offset: {
            type: 'number',
            description: 'Number of records to skip (for pagination)',
          },
          orderBy: {
            type: 'string',
            description: 'Field to sort by (e.g., "CreatedDate DESC", "Priority ASC")',
            default: 'CreatedDate DESC',
          },
          status: {
            type: 'string',
            description: 'Filter by case status (e.g., "New", "Working", "Escalated")',
          },
          priority: {
            type: 'string',
            description: 'Filter by priority (e.g., "High", "Medium", "Low")',
          },
          accountId: {
            type: 'string',
            description: 'Filter by account ID',
          },
          isClosed: {
            type: 'boolean',
            description: 'Filter by closed status',
          },
        },
      },
      handler: async (args: {
        limit?: number;
        offset?: number;
        orderBy?: string;
        status?: string;
        priority?: string;
        accountId?: string;
        isClosed?: boolean;
      }) => {
        const conditions: string[] = [];
        if (args.status) conditions.push(`Status = '${args.status}'`);
        if (args.priority) conditions.push(`Priority = '${args.priority}'`);
        if (args.accountId) conditions.push(`AccountId = '${args.accountId}'`);
        if (args.isClosed !== undefined) conditions.push(`IsClosed = ${args.isClosed}`);

        const soql = client.buildSOQL({
          select: ['Id', 'CaseNumber', 'Subject', 'Status', 'Priority', 'Origin', 'Type', 'Reason', 'Account.Name', 'Contact.Name', 'IsClosed', 'Owner.Name', 'CreatedDate'],
          from: 'Case',
          where: conditions.length > 0 ? conditions.join(' AND ') : undefined,
          orderBy: args.orderBy || 'CreatedDate DESC',
          limit: args.limit || 200,
          offset: args.offset,
        });

        const result = await client.query<Case>(soql);
        return {
          totalSize: result.totalSize,
          records: result.records,
          hasMore: !result.done,
        };
      },
    },

    {
      name: 'sf_get_case',
      description: 'Get detailed information about a specific case by ID',
      inputSchema: {
        type: 'object',
        properties: {
          caseId: {
            type: 'string',
            description: 'The Salesforce ID of the case (15 or 18 characters)',
          },
        },
        required: ['caseId'],
      },
      handler: async (args: { caseId: string }) => {
        const caseRecord = await client.getRecord<Case>('Case', args.caseId);
        return caseRecord;
      },
    },

    {
      name: 'sf_create_case',
      description: 'Create a new case',
      inputSchema: {
        type: 'object',
        properties: {
          status: {
            type: 'string',
            description: 'Case status (required, e.g., "New", "Working")',
          },
          subject: {
            type: 'string',
            description: 'Case subject/title',
          },
          description: {
            type: 'string',
            description: 'Case description',
          },
          priority: {
            type: 'string',
            description: 'Priority (e.g., "High", "Medium", "Low")',
          },
          origin: {
            type: 'string',
            description: 'Case origin (e.g., "Phone", "Email", "Web")',
          },
          type: {
            type: 'string',
            description: 'Case type',
          },
          reason: {
            type: 'string',
            description: 'Case reason',
          },
          accountId: {
            type: 'string',
            description: 'Associated account ID',
          },
          contactId: {
            type: 'string',
            description: 'Associated contact ID',
          },
        },
        required: ['status'],
      },
      handler: async (args: {
        status: string;
        subject?: string;
        description?: string;
        priority?: string;
        origin?: string;
        type?: string;
        reason?: string;
        accountId?: string;
        contactId?: string;
      }) => {
        const caseData: Partial<Case> = {
          Status: args.status,
          Subject: args.subject,
          Description: args.description,
          Priority: args.priority,
          Origin: args.origin,
          Type: args.type,
          Reason: args.reason,
          AccountId: args.accountId as any,
          ContactId: args.contactId as any,
        };

        const result = await client.createRecord('Case', caseData);
        return result;
      },
    },

    {
      name: 'sf_update_case',
      description: 'Update an existing case',
      inputSchema: {
        type: 'object',
        properties: {
          caseId: {
            type: 'string',
            description: 'The Salesforce ID of the case to update',
          },
          status: { type: 'string' },
          subject: { type: 'string' },
          description: { type: 'string' },
          priority: { type: 'string' },
          origin: { type: 'string' },
          type: { type: 'string' },
          reason: { type: 'string' },
          accountId: { type: 'string' },
          contactId: { type: 'string' },
        },
        required: ['caseId'],
      },
      handler: async (args: {
        caseId: string;
        status?: string;
        subject?: string;
        description?: string;
        priority?: string;
        origin?: string;
        type?: string;
        reason?: string;
        accountId?: string;
        contactId?: string;
      }) => {
        const { caseId, ...updates } = args;
        const caseData: Partial<Case> = {
          Status: updates.status,
          Subject: updates.subject,
          Description: updates.description,
          Priority: updates.priority,
          Origin: updates.origin,
          Type: updates.type,
          Reason: updates.reason,
          AccountId: updates.accountId as any,
          ContactId: updates.contactId as any,
        };

        // Remove undefined values
        Object.keys(caseData).forEach((key) => {
          if (caseData[key as keyof Case] === undefined) {
            delete caseData[key as keyof Case];
          }
        });

        await client.updateRecord('Case', caseId, caseData);
        return { success: true, id: caseId };
      },
    },

    {
      name: 'sf_delete_case',
      description: 'Delete a case by ID',
      inputSchema: {
        type: 'object',
        properties: {
          caseId: {
            type: 'string',
            description: 'The Salesforce ID of the case to delete',
          },
        },
        required: ['caseId'],
      },
      handler: async (args: { caseId: string }) => {
        await client.deleteRecord('Case', args.caseId);
        return { success: true, id: args.caseId };
      },
    },

    {
      name: 'sf_close_case',
      description: 'Close a case by updating its status to a closed status',
      inputSchema: {
        type: 'object',
        properties: {
          caseId: {
            type: 'string',
            description: 'The Salesforce ID of the case to close',
          },
          closedStatus: {
            type: 'string',
            description: 'The closed status to set (e.g., "Closed", "Closed - Resolved")',
            default: 'Closed',
          },
        },
        required: ['caseId'],
      },
      handler: async (args: { caseId: string; closedStatus?: string }) => {
        const updateData: Partial<Case> = {
          Status: args.closedStatus || 'Closed',
        };
        await client.updateRecord('Case', args.caseId, updateData);
        return { success: true, id: args.caseId, status: args.closedStatus || 'Closed' };
      },
    },

    {
      name: 'sf_escalate_case',
      description: 'Escalate a case by updating priority and/or status',
      inputSchema: {
        type: 'object',
        properties: {
          caseId: {
            type: 'string',
            description: 'The Salesforce ID of the case to escalate',
          },
          priority: {
            type: 'string',
            description: 'New priority (e.g., "High", "Critical")',
            default: 'High',
          },
          status: {
            type: 'string',
            description: 'New status (e.g., "Escalated")',
          },
        },
        required: ['caseId'],
      },
      handler: async (args: { caseId: string; priority?: string; status?: string }) => {
        const updates: Partial<Case> = {};
        if (args.priority) updates.Priority = args.priority;
        if (args.status) updates.Status = args.status;

        await client.updateRecord('Case', args.caseId, updates);
        return { success: true, id: args.caseId, updates };
      },
    },

    {
      name: 'sf_search_cases',
      description: 'Search cases using SOQL with flexible criteria',
      inputSchema: {
        type: 'object',
        properties: {
          searchText: {
            type: 'string',
            description: 'Text to search in Subject and Description fields',
          },
          whereClause: {
            type: 'string',
            description: 'Custom WHERE clause (e.g., "Priority = \'High\' AND IsClosed = false")',
          },
          limit: {
            type: 'number',
            description: 'Maximum number of results',
            default: 100,
          },
        },
      },
      handler: async (args: { searchText?: string; whereClause?: string; limit?: number }) => {
        let where = args.whereClause;
        
        if (args.searchText) {
          const searchCondition = `(Subject LIKE '%${args.searchText}%' OR Description LIKE '%${args.searchText}%')`;
          where = where ? `${searchCondition} AND (${where})` : searchCondition;
        }

        const soql = client.buildSOQL({
          select: ['Id', 'CaseNumber', 'Subject', 'Status', 'Priority', 'Origin', 'Account.Name', 'Contact.Name', 'IsClosed', 'CreatedDate'],
          from: 'Case',
          where,
          orderBy: 'CreatedDate DESC',
          limit: args.limit || 100,
        });

        const result = await client.query<Case>(soql);
        return result.records;
      },
    },
  ];
}
