/**
 * mt4_get_quote - Get current price quote for a symbol
 *
 * @description Retrieves the current bid/ask prices for a trading symbol.
 * Also calculates the spread in points.
 *
 * @param symbol - Trading symbol to get quote for (e.g., "XAUUSD")
 * @returns Current bid, ask, spread, and timestamp
 *
 * @example
 * const result = await mt4_get_quote({ symbol: "XAUUSD" });
 * // Returns:
 * // {
 * //   symbol: "XAUUSD",
 * //   bid: 2650.50,
 * //   ask: 2650.80,
 * //   spread: 0.30,
 * //   timestamp: "2026-01-04T12:00:00.000Z"
 * // }
 */

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

// ==========================================
// Schema Definition
// ==========================================

export const mt4GetQuoteSchema = {
  name: 'mt4_get_quote',
  description: 'Get current price quote (bid/ask/spread) for a trading symbol',
  inputSchema: {
    type: 'object' as const,
    properties: {
      symbol: {
        type: 'string',
        description: 'Trading symbol to get quote for (e.g., XAUUSD, EURUSD, GBPUSD)',
      },
    },
    required: ['symbol'] as string[],
  },
};

export const Mt4GetQuoteInputSchema = z.object({
  symbol: z.string().min(1).max(20),
});

export type Mt4GetQuoteInput = z.infer<typeof Mt4GetQuoteInputSchema>;

// ==========================================
// Tool Implementation
// ==========================================

export interface Mt4GetQuoteResult {
  success: boolean;
  data?: MT4Tick;
  error?: string;
}

export async function mt4_get_quote(
  params: Mt4GetQuoteInput
): Promise<Mt4GetQuoteResult> {
  try {
    const client = getMT4Client();

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

    // Get tick data
    const tick = await client.getTick(params.symbol.toUpperCase());

    // Validate we got valid data
    if (tick.bid === 0 && tick.ask === 0) {
      return {
        success: false,
        error: `No quote data available for ${params.symbol}. Symbol may not be available on this broker.`,
      };
    }

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

// ==========================================
// MCP Tool Handler
// ==========================================

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

  if (result.success && result.data) {
    // Determine decimal places based on symbol
    const decimals = getDecimalPlaces(result.data.symbol);
    const spreadPips = calculateSpreadPips(result.data.spread, result.data.symbol);

    const formattedOutput = `
Price Quote: ${result.data.symbol}
${'='.repeat(25)}
Bid: ${result.data.bid.toFixed(decimals)}
Ask: ${result.data.ask.toFixed(decimals)}
Spread: ${result.data.spread.toFixed(decimals)} (${spreadPips.toFixed(1)} pips)
Time: ${result.data.timestamp}
`.trim();

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

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

// ==========================================
// Helper Functions
// ==========================================

/**
 * Determine decimal places based on symbol type
 */
function getDecimalPlaces(symbol: string): number {
  const upperSymbol = symbol.toUpperCase();

  // JPY pairs have 3 decimals, most forex 5 decimals
  if (upperSymbol.includes('JPY')) {
    return 3;
  }

  // Gold and metals typically 2 decimals
  if (upperSymbol.startsWith('XAU') || upperSymbol.startsWith('XAG')) {
    return 2;
  }

  // Indices vary, use 2 as default
  if (
    upperSymbol.includes('US30') ||
    upperSymbol.includes('US500') ||
    upperSymbol.includes('NAS')
  ) {
    return 2;
  }

  // Default forex pairs
  return 5;
}

/**
 * Calculate spread in pips based on symbol
 */
function calculateSpreadPips(spread: number, symbol: string): number {
  const upperSymbol = symbol.toUpperCase();

  // JPY pairs: 1 pip = 0.01
  if (upperSymbol.includes('JPY')) {
    return spread * 100;
  }

  // Gold: 1 pip = 0.10
  if (upperSymbol.startsWith('XAU')) {
    return spread * 10;
  }

  // Default forex: 1 pip = 0.0001
  return spread * 10000;
}
