import logger from '../utils/logger.js';
import { TRADE_HISTORY_CONTAINER, clampNumber, queryDocuments } from './tradingRecordStore.js';
import { config } from '../config/index.js';

export interface TradeHistoryKeyRecord {
    trade_id: string;
    profile_id: string | null;
}

export interface TradeHistoryRow {
    id?: string;
    timestamp?: number | string;
    symbol?: string;
    side?: string;
    size?: number;
    entry_price?: number;
    exit_price?: number;
    pnl?: number;
    pnl_percent?: number;
    reason?: string;
    profile_id?: string | null;
    created_at?: string;
    trade_id?: string;
    source?: string;
}

type TradeHistoryDocument = TradeHistoryRow & {
    productId: string;
    type: 'trade_history';
    user_id?: string;
};

const startOfCurrentDayUtc = (): string => {
    const now = new Date();
    return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate())).toISOString();
};

async function listTradeHistoryDocuments(options: {
    userId?: string;
    profileId?: string;
    limit?: number;
}): Promise<TradeHistoryDocument[]> {
    const filters = ['c.productId = @productId', 'c.type = @type'];
    const parameters: Array<{ name: string; value: unknown }> = [
        { name: '@productId', value: config.PRODUCT_ID },
        { name: '@type', value: 'trade_history' },
    ];

    if (options.userId) {
        filters.push('c.user_id = @userId');
        parameters.push({ name: '@userId', value: options.userId });
    }
    if (options.profileId) {
        filters.push('c.profile_id = @profileId');
        parameters.push({ name: '@profileId', value: options.profileId });
    }

    const limit = Math.max(1, Math.min(5000, Math.floor(Number(options.limit || 5000))));
    const query = `SELECT TOP ${limit} * FROM c WHERE ${filters.join(' AND ')} ORDER BY c.created_at DESC`;
    return await queryDocuments<TradeHistoryDocument>(TRADE_HISTORY_CONTAINER, query, parameters);
}

export async function getProfileDailyNetPnlUsd(profileId: string): Promise<number> {
    if (!profileId) return 0;
    try {
        const rows = await listTradeHistoryDocuments({ profileId, limit: 5000 });
        const todayIso = startOfCurrentDayUtc();
        return rows.reduce((sum, row) => {
            if (String(row.created_at || '') < todayIso) return sum;
            return sum + clampNumber(row.pnl);
        }, 0);
    } catch (error: any) {
        logger.error(`[TradeHistoryRepo] Daily net PnL lookup failed for ${profileId}: ${error.message}`);
        return 0;
    }
}

export async function getProfileDailyLossUsd(profileId: string): Promise<number> {
    const netPnl = await getProfileDailyNetPnlUsd(profileId);
    return netPnl < 0 ? Math.abs(netPnl) : 0;
}

export async function getProfileConsecutiveLosses(profileId: string, lookback: number = 100): Promise<number> {
    if (!profileId) return 0;
    try {
        const rows = await listTradeHistoryDocuments({
            profileId,
            limit: Math.max(1, Math.min(500, Math.floor(lookback)))
        });
        let consecutiveLosses = 0;
        for (const row of rows) {
            const pnl = clampNumber(row.pnl);
            if (pnl >= 0) break;
            consecutiveLosses += 1;
        }
        return consecutiveLosses;
    } catch (error: any) {
        logger.error(`[TradeHistoryRepo] Consecutive loss lookup failed for ${profileId}: ${error.message}`);
        return 0;
    }
}

export async function listRecentTradeHistoryKeys(options: {
    userId?: string;
    limit?: number;
}): Promise<TradeHistoryKeyRecord[]> {
    try {
        const rows = await listTradeHistoryDocuments(options);
        return rows
            .map((row) => ({
                trade_id: String(row.trade_id || '').trim(),
                profile_id: row.profile_id ? String(row.profile_id) : null,
            }))
            .filter((row) => Boolean(row.trade_id));
    } catch (error: any) {
        logger.error(`[TradeHistoryRepo] Recent trade key lookup failed: ${error.message}`);
        return [];
    }
}

export async function listRecentTradeHistory(options: {
    userId?: string;
    limit?: number;
}): Promise<TradeHistoryRow[]> {
    try {
        const rows = await listTradeHistoryDocuments(options);
        return rows as TradeHistoryRow[];
    } catch (error: any) {
        logger.error(`[TradeHistoryRepo] Recent trade history lookup failed: ${error.message}`);
        return [];
    }
}
