import { describe, expect, it, vi } from 'vitest';

vi.mock('../lib/supabaseClient', () => {
    const query: any = {
        select: vi.fn(() => query),
        order: vi.fn(() => query),
        eq: vi.fn(() => query),
        limit: vi.fn(() => Promise.resolve({ data: [], error: null }))
    };

    return {
        supabase: {
            from: vi.fn(() => query)
        }
    };
});

vi.mock('./AuthContext', () => ({
    useAuth: () => ({ user: null, profile: { role: 'admin' } })
}));

import {
    filterProfilesBySearch,
    normalizeSessionPresetValue,
    normalizeStrategyConfig,
    resolveSessionPresetSelection,
    summarizePortfolioStats
} from './TradeProfileManager';

describe('normalizeStrategyConfig', () => {
    it('normalizes legacy session aliases into canonical preset values', () => {
        expect(normalizeSessionPresetValue('London,NY')).toBe('LDN,NY');
        expect(normalizeSessionPresetValue('LDN | NY | TOK | SYD')).toBe('24/7');
        expect(normalizeSessionPresetValue('24x7')).toBe('24/7');
        expect(resolveSessionPresetSelection('Tokyo,Sydney')).toBe('TOK,SYD');
        expect(resolveSessionPresetSelection('LDN,NY,custom')).toBe('LDN,NY');
        expect(resolveSessionPresetSelection('LATAM')).toBe('custom');
    });

    it('returns safe defaults when config is missing', () => {
        const normalized = normalizeStrategyConfig(undefined as any);

        expect(normalized.rules).toEqual([]);
        expect(normalized.riskLimits.maxDailyLossUsd).toBe(50);
        expect(normalized.riskLimits.maxOpenTrades).toBe(3);
        expect(normalized.execution.orderType).toBe('market');
        expect(normalized.execution.cooldownMinutes).toBe(30);
        expect(normalized.execution.entryMode).toBe('both');
    });

    it('normalizes legacy session and AI confidence parameters', () => {
        const normalized = normalizeStrategyConfig({
            rules: [
                {
                    ruleId: 'SessionRule',
                    enabled: true,
                    params: { allowedSessions: 'London,NY' }
                },
                {
                    ruleId: 'AIAnalysisRule',
                    enabled: true,
                    params: { confidenceThreshold: 0.72 }
                }
            ],
            riskLimits: {
                maxDailyLossUsd: 100,
                maxOpenTrades: 4,
                maxConsecutiveLosses: 3
            },
            execution: {
                orderType: 'limit',
                cooldownMinutes: 12,
                entryMode: 'long_only'
            }
        } as any);

        const sessionRule = normalized.rules.find((rule) => rule.ruleId === 'SessionRule');
        const aiRule = normalized.rules.find((rule) => rule.ruleId === 'AIAnalysisRule');

        expect(sessionRule?.params?.sessions).toBe('London,NY');
        expect(aiRule?.params?.minConfidence).toBe(72);
        expect(normalized.execution.orderType).toBe('limit');
        expect(normalized.execution.entryMode).toBe('long_only');
    });

    it('coerces invalid numeric values back to defaults', () => {
        const normalized = normalizeStrategyConfig({
            rules: [],
            riskLimits: {
                maxDailyLossUsd: Number.NaN,
                maxOpenTrades: 0,
                maxConsecutiveLosses: -1
            },
            execution: {
                orderType: 'unknown',
                cooldownMinutes: -5,
                longOnly: true
            }
        } as any);

        expect(normalized.riskLimits.maxDailyLossUsd).toBe(50);
        expect(normalized.riskLimits.maxOpenTrades).toBe(3);
        expect(normalized.riskLimits.maxConsecutiveLosses).toBe(2);
        expect(normalized.execution.orderType).toBe('market');
        expect(normalized.execution.cooldownMinutes).toBe(30);
        expect(normalized.execution.entryMode).toBe('long_only');
    });

    it('preserves maxConsecutiveLosses=0 as disabled', () => {
        const normalized = normalizeStrategyConfig({
            rules: [],
            riskLimits: {
                maxDailyLossUsd: 100,
                maxOpenTrades: 3,
                maxConsecutiveLosses: 0
            },
            execution: {
                orderType: 'market',
                cooldownMinutes: 10
            }
        } as any);

        expect(normalized.riskLimits.maxConsecutiveLosses).toBe(0);
    });

    it('filters profiles by search term case-insensitively', () => {
        const filtered = filterProfilesBySearch([
            { id: '1', user_id: 'u1', name: 'High Risk Scalper', allocated_capital: 1000, risk_per_trade_percent: 1, symbols: 'BTC/USDT', is_active: true },
            { id: '2', user_id: 'u1', name: 'Conservative Bag', allocated_capital: 2000, risk_per_trade_percent: 0.5, symbols: 'ETH/USDT', is_active: false }
        ] as any, 'conservative');

        expect(filtered).toHaveLength(1);
        expect(filtered[0].name).toBe('Conservative Bag');
    });

    it('summarizes capital and pnl metrics', () => {
        const summary = summarizePortfolioStats(
            [
                { id: '1', user_id: 'u1', name: 'A', allocated_capital: 1000, risk_per_trade_percent: 1, symbols: 'BTC/USDT', is_active: true },
                { id: '2', user_id: 'u1', name: 'B', allocated_capital: 1500, risk_per_trade_percent: 1, symbols: 'ETH/USDT', is_active: false }
            ] as any,
            {
                '1': { winRate: 60, totalPnl: 120, tradeCount: 4 },
                '2': { winRate: 50, totalPnl: -20, tradeCount: 2 }
            }
        );

        expect(summary.activeCount).toBe(1);
        expect(summary.totalCapital).toBe(2500);
        expect(summary.totalPnl).toBe(100);
        expect(summary.totalTrades).toBe(6);
    });
});
