/**
 * MT4 Trading Tools
 *
 * - mt4_execute_trade: Execute BUY/SELL market orders
 * - mt4_modify_position: Modify SL/TP of existing positions
 */

import { z } from 'zod';
import { getMT4Client, TradeResult } from '../services/mt4-client';

// ==========================================
// mt4_execute_trade
// ==========================================

/**
 * mt4_execute_trade - Execute a market order (BUY or SELL)
 *
 * @description Opens a new trading position with optional SL/TP levels.
 * Supports market orders only (pending orders not implemented).
 *
 * @param symbol - Trading symbol (e.g., "XAUUSD", "EURUSD")
 * @param action - Trade direction: "buy" or "sell"
 * @param lots - Volume in lots (e.g., 0.01, 0.1, 1.0)
 * @param stopLoss - Optional stop loss price
 * @param takeProfit - Optional take profit price
 * @param slippage - Optional max slippage in points (default: 3)
 * @param magic - Optional magic number for EA identification
 * @param comment - Optional order comment
 * @returns Trade result with ticket number
 *
 * @example
 * // Simple buy order
 * const result = await mt4_execute_trade({
 *   symbol: "XAUUSD",
 *   action: "buy",
 *   lots: 0.1
 * });
 *
 * // Buy with SL/TP
 * const result = await mt4_execute_trade({
 *   symbol: "XAUUSD",
 *   action: "buy",
 *   lots: 0.1,
 *   stopLoss: 2640.00,
 *   takeProfit: 2680.00,
 *   comment: "AI Signal"
 * });
 */

export const mt4ExecuteTradeSchema = {
  name: 'mt4_execute_trade',
  description: 'Execute a market order (BUY or SELL) on MT4 with optional stop loss and take profit',
  inputSchema: {
    type: 'object' as const,
    properties: {
      symbol: {
        type: 'string',
        description: 'Trading symbol (e.g., XAUUSD, EURUSD, GBPUSD)',
      },
      action: {
        type: 'string',
        enum: ['buy', 'sell'],
        description: 'Trade direction: buy or sell',
      },
      lots: {
        type: 'number',
        description: 'Volume in lots (e.g., 0.01, 0.1, 1.0)',
      },
      stopLoss: {
        type: 'number',
        description: 'Optional: Stop loss price level',
      },
      takeProfit: {
        type: 'number',
        description: 'Optional: Take profit price level',
      },
      slippage: {
        type: 'number',
        description: 'Optional: Maximum slippage in points (default: 3)',
      },
      magic: {
        type: 'number',
        description: 'Optional: Magic number for EA identification (default: 12345)',
      },
      comment: {
        type: 'string',
        description: 'Optional: Order comment (max 31 chars)',
      },
    },
    required: ['symbol', 'action', 'lots'] as string[],
  },
};

export const Mt4ExecuteTradeInputSchema = z.object({
  symbol: z.string().min(1).max(20),
  action: z.enum(['buy', 'sell']),
  lots: z.number().positive().max(100),
  stopLoss: z.number().positive().optional(),
  takeProfit: z.number().positive().optional(),
  slippage: z.number().int().min(0).max(100).optional(),
  magic: z.number().int().optional(),
  comment: z.string().max(31).optional(),
});

export type Mt4ExecuteTradeInput = z.infer<typeof Mt4ExecuteTradeInputSchema>;

export interface Mt4ExecuteTradeResult {
  success: boolean;
  data?: TradeResult & {
    symbol: string;
    action: string;
    lots: number;
  };
  error?: string;
}

export async function mt4_execute_trade(
  params: Mt4ExecuteTradeInput
): Promise<Mt4ExecuteTradeResult> {
  try {
    const client = getMT4Client();

    // Check connection
    const isConnected = await client.isConnected();
    if (!isConnected) {
      return {
        success: false,
        error: 'MT4 terminal is not connected',
      };
    }

    // Validate SL/TP logic (basic check)
    if (params.stopLoss !== undefined && params.takeProfit !== undefined) {
      if (params.action === 'buy') {
        // For buy: SL should be below current price, TP above
        if (params.stopLoss >= params.takeProfit) {
          return {
            success: false,
            error: 'For BUY orders, stop loss must be below take profit',
          };
        }
      } else {
        // For sell: SL should be above current price, TP below
        if (params.stopLoss <= params.takeProfit) {
          return {
            success: false,
            error: 'For SELL orders, stop loss must be above take profit',
          };
        }
      }
    }

    // Execute trade
    const result = await client.executeTrade({
      symbol: params.symbol.toUpperCase(),
      action: params.action,
      lots: params.lots,
      stopLoss: params.stopLoss,
      takeProfit: params.takeProfit,
      slippage: params.slippage,
      magic: params.magic,
      comment: params.comment,
    });

    if (result.success) {
      return {
        success: true,
        data: {
          ...result,
          symbol: params.symbol.toUpperCase(),
          action: params.action,
          lots: params.lots,
        },
      };
    }

    return {
      success: false,
      error: result.message || 'Trade execution failed',
    };
  } catch (error) {
    return {
      success: false,
      error: error instanceof Error ? error.message : 'Unknown error occurred',
    };
  }
}

export async function handleMt4ExecuteTrade(
  params: unknown
): Promise<{ content: Array<{ type: string; text: string }> }> {
  const validatedParams = Mt4ExecuteTradeInputSchema.parse(params);
  const result = await mt4_execute_trade(validatedParams);

  if (result.success && result.data) {
    const formattedOutput = `
Trade Executed Successfully
===========================
Ticket: #${result.data.ticket}
Symbol: ${result.data.symbol}
Direction: ${result.data.action.toUpperCase()}
Volume: ${result.data.lots} lots
${validatedParams.stopLoss ? `Stop Loss: ${validatedParams.stopLoss}` : 'Stop Loss: Not set'}
${validatedParams.takeProfit ? `Take Profit: ${validatedParams.takeProfit}` : 'Take Profit: Not set'}
Message: ${result.data.message || 'Order placed successfully'}
`.trim();

    return {
      content: [
        {
          type: 'text',
          text: formattedOutput,
        },
      ],
    };
  }

  return {
    content: [
      {
        type: 'text',
        text: `Error executing trade: ${result.error}`,
      },
    ],
  };
}

// ==========================================
// mt4_modify_position
// ==========================================

/**
 * mt4_modify_position - Modify SL/TP of an existing position
 *
 * @description Updates the stop loss and/or take profit levels of an open position.
 *
 * @param ticket - Position ticket number to modify
 * @param stopLoss - New stop loss price (null to remove)
 * @param takeProfit - New take profit price (null to remove)
 * @returns Modification result
 *
 * @example
 * // Set both SL and TP
 * const result = await mt4_modify_position({
 *   ticket: 123456,
 *   stopLoss: 2640.00,
 *   takeProfit: 2680.00
 * });
 *
 * // Update only TP
 * const result = await mt4_modify_position({
 *   ticket: 123456,
 *   takeProfit: 2700.00
 * });
 */

export const mt4ModifyPositionSchema = {
  name: 'mt4_modify_position',
  description: 'Modify stop loss and/or take profit of an existing position',
  inputSchema: {
    type: 'object' as const,
    properties: {
      ticket: {
        type: 'number',
        description: 'Position ticket number to modify',
      },
      stopLoss: {
        type: 'number',
        description: 'New stop loss price level (optional)',
      },
      takeProfit: {
        type: 'number',
        description: 'New take profit price level (optional)',
      },
    },
    required: ['ticket'] as string[],
  },
};

export const Mt4ModifyPositionInputSchema = z.object({
  ticket: z.number().int().positive(),
  stopLoss: z.number().positive().optional(),
  takeProfit: z.number().positive().optional(),
});

export type Mt4ModifyPositionInput = z.infer<typeof Mt4ModifyPositionInputSchema>;

export interface Mt4ModifyPositionResult {
  success: boolean;
  data?: TradeResult;
  error?: string;
}

export async function mt4_modify_position(
  params: Mt4ModifyPositionInput
): Promise<Mt4ModifyPositionResult> {
  try {
    const client = getMT4Client();

    // Check connection
    const isConnected = await client.isConnected();
    if (!isConnected) {
      return {
        success: false,
        error: 'MT4 terminal is not connected',
      };
    }

    // Validate at least one parameter is provided
    if (params.stopLoss === undefined && params.takeProfit === undefined) {
      return {
        success: false,
        error: 'At least one of stopLoss or takeProfit must be provided',
      };
    }

    // Verify position exists
    const position = await client.getPosition(params.ticket);
    if (!position) {
      return {
        success: false,
        error: `Position with ticket ${params.ticket} not found`,
      };
    }

    // Validate SL/TP based on position type
    const sl = params.stopLoss;
    const tp = params.takeProfit;

    if (sl !== undefined && tp !== undefined) {
      if (position.type === 'buy') {
        if (sl >= tp) {
          return {
            success: false,
            error: 'For BUY positions, stop loss must be below take profit',
          };
        }
      } else {
        if (sl <= tp) {
          return {
            success: false,
            error: 'For SELL positions, stop loss must be above take profit',
          };
        }
      }
    }

    // Modify position
    const result = await client.modifyPosition({
      ticket: params.ticket,
      stopLoss: params.stopLoss,
      takeProfit: params.takeProfit,
    });

    return {
      success: result.success,
      data: result,
      error: result.success ? undefined : result.message,
    };
  } catch (error) {
    return {
      success: false,
      error: error instanceof Error ? error.message : 'Unknown error occurred',
    };
  }
}

export async function handleMt4ModifyPosition(
  params: unknown
): Promise<{ content: Array<{ type: string; text: string }> }> {
  const validatedParams = Mt4ModifyPositionInputSchema.parse(params);
  const result = await mt4_modify_position(validatedParams);

  if (result.success && result.data) {
    const formattedOutput = `
Position Modified Successfully
==============================
Ticket: #${validatedParams.ticket}
${validatedParams.stopLoss !== undefined ? `New Stop Loss: ${validatedParams.stopLoss}` : 'Stop Loss: Unchanged'}
${validatedParams.takeProfit !== undefined ? `New Take Profit: ${validatedParams.takeProfit}` : 'Take Profit: Unchanged'}
Message: ${result.data.message || 'Position modified successfully'}
`.trim();

    return {
      content: [
        {
          type: 'text',
          text: formattedOutput,
        },
      ],
    };
  }

  return {
    content: [
      {
        type: 'text',
        text: `Error modifying position: ${result.error}`,
      },
    ],
  };
}
