import type { Candle } from '../connectors/types.js';

export type BacktestMode = 'backtest';
export type BacktestTimeframe = '1m' | '15m' | '1h' | '4h';
export type BacktestOrderType = 'market' | 'limit';
export type BacktestDataSourceType = 'csv' | 'json' | 'replay' | 'kraken';
export type BacktestWindowClosePolicy = 'OPEN_AT_END' | 'FORCE_CLOSE';
export type BacktestIntraCandlePolicy = 'stop_loss_first' | 'take_profit_first' | 'ohlc_path';
export type BacktestTriggerTimeframe = 'off' | '1m';

export interface BacktestRawCandle {
    symbol: string;
    timeframe: string;
    timestamp: number | string;
    open: number | string;
    high: number | string;
    low: number | string;
    close: number | string;
    volume: number | string;
}

export interface NormalizedBacktestCandle extends Candle {
    symbol: string;
    timeframe: BacktestTimeframe;
}

export interface BacktestCsvSource {
    type: 'csv';
    payload: string;
}

export interface BacktestJsonSource {
    type: 'json';
    payload: {
        candles: BacktestRawCandle[] | Record<string, Partial<Record<BacktestTimeframe, Candle[]>>>;
    };
}

export interface BacktestReplaySource {
    type: 'replay';
    payload: {
        candles: BacktestRawCandle[] | Record<string, Partial<Record<BacktestTimeframe, Candle[]>>>;
    };
}

export interface BacktestKrakenSource {
    type: 'kraken';
    payload?: {
        exchange?: 'kraken';
        lookbackCandles?: number;
        timeframe?: BacktestTimeframe;
        limitPerRequest?: number;
        disableCache?: boolean;
    };
}

export type BacktestDataSource = BacktestCsvSource | BacktestJsonSource | BacktestReplaySource | BacktestKrakenSource;

export interface BacktestExecutionConfig {
    initialCapitalUsd: number;
    orderType: BacktestOrderType;
    slippageBps: number;
    feeBps: number;
    partialFillPct: number;
    fillOnNextBar: boolean;
    intraCandlePolicy: BacktestIntraCandlePolicy;
    triggerTimeframe: BacktestTriggerTimeframe;
    allowNegativeCash: boolean;
    enforceWarmup: boolean;
    forceCloseAtWindowEnd: boolean;
}

export interface BacktestDateRange {
    from: string;
    to: string;
}

export interface BacktestRequest {
    mode: BacktestMode;
    profileId?: string;
    strategyConfig?: any;
    symbols: string[];
    timeframe: BacktestTimeframe;
    dateRange: BacktestDateRange;
    dataSource: BacktestDataSource;
    execution?: Partial<BacktestExecutionConfig>;
}

export interface BacktestReplayWindow {
    fromTimestamp: number;
    toTimestamp: number;
    fromIso: string;
    toIso: string;
    timezone: 'UTC';
}

export interface BacktestWarmupReport {
    startTimestamp: number;
    endTimestamp: number;
    candlesRequired: {
        '15m': number;
        '1h': number;
        '4h': number;
    };
    signalsIgnored: number;
}

export interface BacktestTrade {
    id: string;
    symbol: string;
    side: 'BUY' | 'SELL';
    entryTimestamp: number;
    exitTimestamp: number;
    durationMinutes: number;
    size: number;
    entryPrice: number;
    exitPrice: number;
    pnlUsd: number;
    pnlPct: number;
    entryReason: string;
    exitReason: string;
    blockedRules?: string[];
}

export interface BacktestOpenPositionAtEnd {
    status: 'OPEN_AT_END';
    symbol: string;
    side: 'BUY' | 'SELL';
    entryTimestamp: number;
    size: number;
    entryPrice: number;
    markPrice: number;
    unrealizedPnlUsd: number;
    unrealizedPnlPct: number;
    reason: string;
}

export interface EquityPoint {
    timestamp: number;
    equityUsd: number;
    drawdownPct: number;
    cashUsd: number;
    reservedUsd: number;
}

export interface BacktestSummary {
    netPnlUsd: number;
    winRate: number;
    maxDrawdownPct: number;
    sharpe: number;
    totalTrades: number;
}

export interface BacktestAssumptions {
    fillModel: string;
    slippageModel: string;
    feeModel: string;
    latencyModel: string;
    intraCandleModel: string;
    triggerResolution: string;
    warmupEnforced: boolean;
    deterministicReplay: boolean;
    replayWindow: string;
    endOfWindowPolicy: BacktestWindowClosePolicy;
    disclaimer: string;
}

export interface BacktestDiagnostics {
    blockedRuleCounts: Record<string, number>;
    entryRejections: Record<string, number>;
    lossReasons: Record<string, number>;
    connectorCalls: {
        fetchOHLCV: number;
        placeOrder: number;
        getPosition: number;
    };
}

export interface BacktestWindowMeta {
    fromTimestamp: number;
    toTimestamp: number;
    fromIso: string;
    toIso: string;
    timezone: 'UTC';
    includesWarmupCandles: boolean;
    endOfWindowPolicy: BacktestWindowClosePolicy;
}

export interface BacktestResult {
    mode: BacktestMode;
    trades: BacktestTrade[];
    summary: BacktestSummary;
    timeline: EquityPoint[];
    window: BacktestWindowMeta;
    warmup: BacktestWarmupReport;
    openPositionsAtEnd: BacktestOpenPositionAtEnd[];
    assumptions: BacktestAssumptions;
    diagnostics: BacktestDiagnostics;
}

export type HistoricalDataset = Record<string, Record<BacktestTimeframe, Candle[]>>;

export interface HistoricalLoadResult {
    dataset: HistoricalDataset;
    window: BacktestReplayWindow;
    source: BacktestDataSourceType;
}
