import { z } from 'zod';

// Trading modes
export const TradingModeSchema = z.enum(['backtest', 'paper', 'live']);
export type TradingMode = z.infer<typeof TradingModeSchema>;

// Mode configurations
export const BacktestConfigSchema = z.object({
  mode: z.literal('backtest'),
  startDate: z.string().datetime(),
  endDate: z.string().datetime(),
  symbols: z.array(z.string()),
  initialCapital: z.number().positive(),
  dataFrequency: z.enum(['1m', '5m', '15m', '1h', '1d']),
  strategy: z.string(),
  strategies: z.array(z.object({
    name: z.string(),
    enabled: z.boolean().default(true),
    config: z.record(z.any()).optional()
  })).optional(),
  commission: z.number().optional(),
  slippage: z.number().optional(),
  fillModel: z.object({
    slippage: z.enum(['zero', 'conservative', 'realistic', 'aggressive']),
    marketImpact: z.boolean(),
    partialFills: z.boolean()
  }).optional(),
  speed: z.enum(['max', 'realtime', '2x', '5x', '10x']).default('max')
});

export const PaperConfigSchema = z.object({
  mode: z.literal('paper'),
  startingCapital: z.number().positive(),
  fillModel: z.object({
    useRealOrderBook: z.boolean().default(true),
    addLatency: z.number().min(0).default(100)
  }).optional()
});

export const LiveConfigSchema = z.object({
  mode: z.literal('live'),
  broker: z.string(),
  accountId: z.string(),
  accountType: z.enum(['cash', 'margin']),
  riskLimits: z.object({
    maxPositionSize: z.number().positive(),
    maxDailyLoss: z.number().positive(),
    maxOrderSize: z.number().positive(),
    maxGrossExposure: z.number().positive(),
    maxSymbolExposure: z.number().positive()
  })
});

export const ModeConfigSchema = z.discriminatedUnion('mode', [
  BacktestConfigSchema,
  PaperConfigSchema,
  LiveConfigSchema
]);

export type ModeConfig = z.infer<typeof ModeConfigSchema>;

// Market data types
export const QuoteSchema = z.object({
  symbol: z.string(),
  bid: z.number(),
  ask: z.number(),
  bidSize: z.number(),
  askSize: z.number(),
  timestamp: z.number()
});

export const TradeSchema = z.object({
  symbol: z.string(),
  price: z.number(),
  size: z.number(),
  side: z.enum(['buy', 'sell']),
  timestamp: z.number()
});

export const BarSchema = z.object({
  symbol: z.string(),
  open: z.number(),
  high: z.number(),
  low: z.number(),
  close: z.number(),
  volume: z.number(),
  vwap: z.number().optional(),
  timestamp: z.number()
});

export const MarketDataSchema = z.discriminatedUnion('type', [
  z.object({ type: z.literal('quote'), data: QuoteSchema }),
  z.object({ type: z.literal('trade'), data: TradeSchema }),
  z.object({ type: z.literal('bar'), data: BarSchema })
]);

export type MarketData = z.infer<typeof MarketDataSchema>;
export type Quote = z.infer<typeof QuoteSchema>;
export type Trade = z.infer<typeof TradeSchema>;
export type Bar = z.infer<typeof BarSchema>;

// Order types
export const OrderSideSchema = z.enum(['buy', 'sell']);
export const OrderTypeSchema = z.enum(['market', 'limit', 'stop', 'stop_limit']);
export const TimeInForceSchema = z.enum(['DAY', 'GTC', 'IOC', 'FOK']);

export const OrderRequestSchema = z.object({
  symbol: z.string(),
  side: OrderSideSchema,
  quantity: z.number().positive(),
  orderType: OrderTypeSchema,
  limitPrice: z.number().positive().optional(),
  stopPrice: z.number().positive().optional(),
  timeInForce: TimeInForceSchema.default('DAY'),
  clientOrderId: z.string().optional()
});

export type OrderRequest = z.infer<typeof OrderRequestSchema>;

// Position types
export const PositionSchema = z.object({
  symbol: z.string(),
  quantity: z.number(),
  averagePrice: z.number(),
  realizedPnl: z.number(),
  unrealizedPnl: z.number(),
  totalCost: z.number(),
  lastUpdate: z.string().datetime()
});

export type Position = z.infer<typeof PositionSchema>;

// Strategy types
export const StrategyConfigSchema = z.object({
  id: z.string(),
  name: z.string(),
  enabled: z.boolean(),
  parameters: z.record(z.any()),
  symbols: z.array(z.string()),
  allocation: z.number().min(0).max(1)
});

export type StrategyConfig = z.infer<typeof StrategyConfigSchema>;

// Analytics types
export const PerformanceMetricsSchema = z.object({
  totalReturn: z.number(),
  sharpeRatio: z.number(),
  sortinoRatio: z.number(),
  maxDrawdown: z.number(),
  winRate: z.number(),
  profitFactor: z.number(),
  avgWin: z.number(),
  avgLoss: z.number(),
  totalTrades: z.number()
});

export type PerformanceMetrics = z.infer<typeof PerformanceMetricsSchema>;

// Risk types
export const RiskMetricsSchema = z.object({
  currentExposure: z.number(),
  dailyPnl: z.number(),
  positionCount: z.number(),
  grossExposure: z.number(),
  var95: z.number().optional(),
  cvar95: z.number().optional()
});

export type RiskMetrics = z.infer<typeof RiskMetricsSchema>;

// Re-export specialized types
export type { MarketMicrostructure, PriceLevel, OrderBookSnapshot } from './types/MarketMicrostructure';