/**
 * QuestDB Client Configuration and Types
 */

/**
 * QuestDB Client Configuration
 */
export interface QuestDBClientConfig {
  host: string;
  httpPort: number;
  pgPort: number;
  influxPort: number;
  user?: string;
  password?: string;
  database?: string;
  tls?: {
    enabled: boolean;
    verifyServerCert: boolean;
  };
  timeouts?: {
    connection: number;
    request: number;
  };
  retryAttempts?: number;
}

/**
 * QuestDB Connection Options
 */
export interface QuestDBConnectionOptions {
  protocol?: 'http' | 'pg' | 'influx';
  retryAttempts?: number;
  retryDelay?: number;
  healthCheckInterval?: number;
}

/**
 * Health Status Types
 */
export type QuestDBHealthStatus = 'healthy' | 'degraded' | 'unhealthy';

export interface QuestDBHealthCheck {
  status: QuestDBHealthStatus;
  timestamp: Date;
  latency: number;
  protocols: {
    http: boolean;
    pg: boolean;
    influx: boolean;
  };
  errors?: string[];
}

export interface QuestDBMetrics {
  queriesPerSecond: number;
  insertsPerSecond: number;
  averageQueryTime: number;
  errorRate: number;
  dataIngestionRate: number;
  storageSize: number;
}

/**
 * Table Names for Time-Series Data
 */
export type TableNames =
  | 'ohlcv'
  | 'trades'
  | 'quotes'
  | 'indicators'
  | 'performance'
  | 'risk_metrics'
  | 'market_events'
  | 'strategy_signals'
  | 'portfolio_snapshots';

/**
 * Time-Series Data Types
 */
export interface BaseTimeSeriesData {
  timestamp: Date;
  symbol?: string;
}

export interface OHLCVData extends BaseTimeSeriesData {
  open: number;
  high: number;
  low: number;
  close: number;
  volume: number;
  timeframe: string; // '1m', '5m', '1h', '1d', etc.
  source: string;
}

export interface TradeData extends BaseTimeSeriesData {
  trade_id: string;
  price: number;
  quantity: number;
  side: 'buy' | 'sell';
  exchange: string;
  conditions?: string[];
}

export interface QuoteData extends BaseTimeSeriesData {
  bid_price: number;
  bid_size: number;
  ask_price: number;
  ask_size: number;
  exchange: string;
  spread: number;
}

export interface IndicatorData extends BaseTimeSeriesData {
  indicator_name: string;
  value: number;
  parameters?: Record<string, any>;
  timeframe: string;
}

export interface PerformanceData extends BaseTimeSeriesData {
  portfolio_id: string;
  total_value: number;
  cash_balance: number;
  unrealized_pnl: number;
  realized_pnl: number;
  daily_return: number;
  cumulative_return: number;
}

export interface RiskMetrics extends BaseTimeSeriesData {
  portfolio_id?: string;
  strategy_id?: string;
  metric_name: string;
  value: number;
  threshold?: number;
  status: 'normal' | 'warning' | 'breach';
}

/**
 * Query Result Types
 */
export interface QueryResult<T = any> {
  rows: T[];
  rowCount: number;
  executionTime: number;
  metadata?: {
    columns: Array<{
      name: string;
      type: string;
    }>;
  };
}

export interface InsertResult {
  rowsInserted: number;
  executionTime: number;
  errors?: string[];
}

/**
 * Schema Definition Types
 */
export interface ColumnDefinition {
  name: string;
  type:
    | 'SYMBOL'
    | 'STRING'
    | 'DOUBLE'
    | 'FLOAT'
    | 'LONG'
    | 'INT'
    | 'BOOLEAN'
    | 'TIMESTAMP'
    | 'DATE'
    | 'BINARY';
  indexed?: boolean;
  capacity?: number; // For SYMBOL type
}

export interface TableDefinition {
  name: string;
  columns: ColumnDefinition[];
  partitionBy?: 'NONE' | 'DAY' | 'MONTH' | 'YEAR';
  timestamp?: string; // Column name to use as designated timestamp
  dedup?: boolean;
}

/**
 * Connection Pool Types
 */
export interface ConnectionPoolConfig {
  minConnections: number;
  maxConnections: number;
  idleTimeout: number;
  acquireTimeout: number;
}

/**
 * Health Monitoring Types
 */
export interface HealthStatus {
  isHealthy: boolean;
  lastCheck: Date;
  responseTime: number;
  message: string;
  error?: Error;
  details?: {
    pgPool: boolean;
    httpEndpoint: boolean;
    uptime: number;
  };
}

export interface PerformanceMetrics {
  totalQueries: number;
  successfulQueries: number;
  failedQueries: number;
  averageResponseTime: number;
  lastQueryTime: Date | null;
  connectionUptime: number;
  memoryUsage: number;
}

/**
 * Query Builder Types
 */
export interface TimeSeriesQuery {
  table: TableNames | string;
  columns?: string[];
  timeRange?: TimeRange;
  groupBy?: string[];
  aggregations?: Record<string, string>;
  sampleBy?: string;
  latestBy?: string[];
  orderBy?: Array<{ column: string; direction: 'ASC' | 'DESC' }>;
  limit?: number;
}

export interface AggregationQuery {
  aggregations: Record<string, string>;
  groupBy?: string[];
  having?: string[];
}

export interface TimeRange {
  startTime: Date;
  endTime: Date;
}

/**
 * InfluxDB Line Protocol Types
 */
export interface InfluxLineData {
  measurement: string;
  tags: Record<string, string>;
  fields: Record<string, number | string | boolean>;
  timestamp?: Date;
}

export interface InfluxWriteOptions {
  batchSize?: number;
  flushInterval?: number;
  autoFlush?: boolean;
  precision?: 'ns' | 'us' | 'ms' | 's';
  retryAttempts?: number;
  retryDelay?: number;
}

/**
 * Schema Management Types
 */
export interface TableSchema {
  tableName: string;
  columns: ColumnSchema[];
  partitionBy?: 'NONE' | 'HOUR' | 'DAY' | 'MONTH' | 'YEAR';
  orderBy?: string[];
  indices?: IndexDefinition[];
  dedup?: boolean;
}

export interface ColumnSchema {
  name: string;
  type:
    | 'SYMBOL'
    | 'STRING'
    | 'DOUBLE'
    | 'FLOAT'
    | 'LONG'
    | 'INT'
    | 'BOOLEAN'
    | 'TIMESTAMP'
    | 'DATE'
    | 'BINARY';
  nullable?: boolean;
  designated?: boolean; // For designated timestamp column
  capacity?: number; // For SYMBOL type
  indexed?: boolean;
}

export interface IndexDefinition {
  columns: string[];
  type: 'HASH' | 'BTREE';
  unique?: boolean;
}
