/**
 * OHLC data types and utilities
 *
 * Handles conversion between:
 * - TradingView datafeed format (seconds, OHLCV structure)
 * - Backend/Iceberg format (nanoseconds, Nautilus ticker)
 * - ZMQ protocol format (protobuf messages)
 */

/**
 * TradingView bar format (used by web frontend)
 */
export interface TradingViewBar {
  time: number;   // Unix timestamp in SECONDS
  open: number;   // always non-null — ingestor forward-fills interior gaps
  high: number;
  low: number;
  close: number;
  volume?: number | null;
  // Optional extra columns from ohlc.proto
  buy_vol?: number;
  sell_vol?: number;
  open_time?: number;
  high_time?: number;
  low_time?: number;
  close_time?: number;
  open_interest?: number;
}

/**
 * Backend OHLC format (from Iceberg)
 */
export interface BackendOHLC {
  timestamp: bigint;  // Unix timestamp in NANOSECONDS — kept as bigint to preserve precision
  ticker: string;     // Nautilus format: "BTC/USDT.BINANCE"
  period_seconds: number;
  open: number;       // always non-null — ingestor forward-fills interior gaps
  high: number;
  low: number;
  close: number;
  volume: number | null;
}

/**
 * Datafeed configuration (TradingView format)
 */
export interface DatafeedConfig {
  supported_resolutions: string[];
  supports_search: boolean;
  supports_group_request: boolean;
  supports_marks: boolean;
  supports_timescale_marks: boolean;
  supports_time: boolean;
}

/**
 * Symbol info (TradingView format)
 * Matches backend.old/src/datasource/schema.py SymbolInfo
 */
export interface SymbolInfo {
  symbol: string;                    // Clean format (e.g., "BTC/USDT")
  ticker: string;                    // Nautilus format (e.g., "BTC/USDT.BINANCE")
  name: string;                      // Display name
  description: string;               // Human-readable description
  type: string;                      // "crypto", "spot", "futures", etc.
  exchange: string;                  // Exchange identifier
  timezone: string;                  // IANA timezone
  session: string;                   // Trading session (e.g., "24x7")
  supported_resolutions: string[];   // Supported time resolutions
  has_intraday: boolean;
  has_daily: boolean;
  has_weekly_and_monthly: boolean;
  pricescale: number;                // 10^price_precision
  minmov: number;                    // Minimum price movement
  base_currency?: string;            // Base asset (e.g., "BTC")
  quote_currency?: string;           // Quote asset (e.g., "USDT")
  data_status?: string;              // "streaming", "delayed", etc.
  // Nautilus Instrument fields
  price_precision?: number;
  size_precision?: number;
  tick_size?: number;
  lot_size?: number;
  maker_fee?: number;
  taker_fee?: number;
}

/**
 * History result (TradingView format)
 */
export interface HistoryResult {
  bars: TradingViewBar[];
  noData: boolean;
  nextTime?: number;    // Unix timestamp in SECONDS for pagination
}

/**
 * Search result (TradingView format)
 * Matches backend.old/src/datasource/schema.py SearchResult
 */
export interface SearchResult {
  symbol: string;           // Clean format (e.g., "BTC/USDT")
  ticker: string;           // Nautilus format (e.g., "BTC/USDT.BINANCE")
  full_name: string;        // Full display name (e.g., "BTC/USDT (BINANCE)")
  description: string;      // Human-readable description
  exchange: string;         // Exchange identifier
  type: string;             // Instrument type ("spot", "futures", etc.)
}

/**
 * ZMQ Protocol Messages (simplified TypeScript representations)
 */

export enum SubmitStatus {
  QUEUED = 0,
  DUPLICATE = 1,
  INVALID = 2,
  ERROR = 3,
}

export enum NotificationStatus {
  OK = 0,
  NOT_FOUND = 1,
  ERROR = 2,
  TIMEOUT = 3,
}

export interface SubmitHistoricalRequest {
  request_id: string;
  ticker: string;          // Nautilus format: "BTC/USDT.BINANCE"
  start_time: bigint;      // nanoseconds
  end_time: bigint;        // nanoseconds
  period_seconds: number;
  limit?: number;
  client_id?: string;
}

export interface SubmitResponse {
  request_id: string;
  status: SubmitStatus;
  error_message?: string;
  notification_topic: string;
}

export interface HistoryReadyNotification {
  request_id: string;
  ticker: string;          // Nautilus format: "BTC/USDT.BINANCE"
  period_seconds: number;
  start_time: bigint;      // nanoseconds
  end_time: bigint;        // nanoseconds
  status: NotificationStatus;
  error_message?: string;
  iceberg_namespace: string;
  iceberg_table: string;
  row_count: number;
  completed_at: bigint;    // nanoseconds
}

/**
 * Conversion utilities
 */

export function secondsToNanos(seconds: number): bigint {
  return BigInt(Math.floor(seconds)) * 1_000_000_000n;
}

export function nanosToSeconds(nanos: bigint | number): number {
  return Number(BigInt(nanos) / 1_000_000_000n);
}

export function backendToTradingView(backend: BackendOHLC): TradingViewBar {
  return {
    time: nanosToSeconds(backend.timestamp),
    open: backend.open,
    high: backend.high,
    low: backend.low,
    close: backend.close,
    volume: backend.volume ?? undefined,
  };
}

/**
 * Convert TradingView resolution to seconds
 * Examples: "1" -> 60, "5" -> 300, "60" -> 3600, "1D" -> 86400
 */
export function resolutionToSeconds(resolution: string): number {
  // Handle numeric resolutions (minutes)
  if (/^\d+$/.test(resolution)) {
    return parseInt(resolution, 10) * 60;
  }

  // Handle day/week/month resolutions
  if (resolution.endsWith('D')) {
    const days = parseInt(resolution.slice(0, -1), 10);
    return days * 86400;
  }
  if (resolution.endsWith('W')) {
    const weeks = parseInt(resolution.slice(0, -1), 10);
    return weeks * 7 * 86400;
  }
  if (resolution.endsWith('M')) {
    const months = parseInt(resolution.slice(0, -1), 10);
    return months * 30 * 86400; // Approximate
  }

  throw new Error(`Unsupported resolution: ${resolution}`);
}

/**
 * Default supported resolutions
 */
export const DEFAULT_SUPPORTED_RESOLUTIONS = [
  '1', '5', '15', '30', '60', '240', '1D', '1W'
];

/**
 * Symbol metadata from Iceberg (backend format)
 * Maps to Market protobuf and Iceberg symbol_metadata table
 */
export interface SymbolMetadata {
  exchange_id: string;
  market_id: string;
  market_type?: string;
  description?: string;
  base_asset?: string;
  quote_asset?: string;
  supported_period_seconds?: number[];
  earliest_time?: bigint;   // nanoseconds
  updated_at: bigint;       // nanoseconds
  // Nautilus Instrument fields
  price_precision?: number;
  size_precision?: number;
  tick_size?: number;
  lot_size?: number;
  min_notional?: number;
  margin_init?: number;
  margin_maint?: number;
  maker_fee?: number;
  taker_fee?: number;
  contract_multiplier?: number;
}
