import { describe, expect, it, vi } from 'vitest';
import {
    filterHistoryByProfileAndDate,
    paginateHistory,
    parseDateEnd,
    parseDateStart,
    sortHistoryByTimestamp,
    toTimestampMs
} from './HistoryTab';
import { buildClonedEntryPayload, filterEntriesByTab } from './EntriesTab';
import { buildConfigUpsertPayload, cloneConfigItems, hasConfigChanges } from './ConfigTab';
import { mapProfileToFormData, parseNumericSettings } from './SettingsTab';

vi.mock('../lib/supabaseClient', () => ({
    supabase: {
        from: vi.fn(() => ({
            select: vi.fn(),
            order: vi.fn(),
            eq: vi.fn(),
            insert: vi.fn(),
            update: vi.fn(),
            upsert: vi.fn(),
            delete: vi.fn()
        }))
    }
}));

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

describe('tab helper coverage', () => {
    it('parses and normalizes history timestamps and date bounds', () => {
        expect(toTimestampMs(1700000000000)).toBe(1700000000000);
        expect(toTimestampMs('2026-02-15T10:00:00.000Z')).toBeGreaterThan(0);
        expect(toTimestampMs(undefined, '2026-02-15T10:00:00.000Z')).toBeGreaterThan(0);
        expect(toTimestampMs('invalid')).toBe(0);

        expect(parseDateStart('')).toBeNull();
        expect(parseDateEnd('')).toBeNull();
        expect(parseDateStart('2026-02-15')).toBeGreaterThan(0);
        expect(parseDateEnd('2026-02-15')).toBeGreaterThan(0);
    });

    it('filters, sorts and paginates history rows deterministically', () => {
        const records = [
            { id: 'b', profile_id: 'p1', timestamp: 20, created_at: '', symbol: 'BTC', side: 'BUY', entry_price: 1, exit_price: 2, pnl: 1, pnl_percent: 1, reason: 'r' },
            { id: 'a', profile_id: 'p1', timestamp: 20, created_at: '', symbol: 'BTC', side: 'BUY', entry_price: 1, exit_price: 2, pnl: 1, pnl_percent: 1, reason: 'r' },
            { id: 'c', profile_id: 'p2', timestamp: 10, created_at: '', symbol: 'ETH', side: 'SELL', entry_price: 2, exit_price: 1, pnl: -1, pnl_percent: -1, reason: 'r' }
        ] as any;

        const filtered = filterHistoryByProfileAndDate(records, 'p1', { from: 0, to: 25 });
        expect(filtered).toHaveLength(2);

        const desc = sortHistoryByTimestamp(filtered, 'desc');
        const asc = sortHistoryByTimestamp(filtered, 'asc');
        expect(desc[0].id).toBe('b');
        expect(asc[0].id).toBe('a');

        const paged = paginateHistory(desc, 1, 1);
        expect(paged).toHaveLength(1);
        expect(paged[0].id).toBe('b');
    });

    it('filters entries by tab and builds clone payload safely', () => {
        const entries = [
            { stock_instance_id: '1', is_real_trade: false, active: true, status: 'active' },
            { stock_instance_id: '2', is_real_trade: false, active: false, status: 'sellCompleted' },
            { stock_instance_id: '3', is_real_trade: true, active: true, status: 'active' }
        ] as any;

        expect(filterEntriesByTab(entries, 'paperActive')).toHaveLength(1);
        expect(filterEntriesByTab(entries, 'paperCompleted')).toHaveLength(1);
        expect(filterEntriesByTab(entries, 'realActive')).toHaveLength(1);
        expect(filterEntriesByTab(entries, 'unknown')).toHaveLength(0);

        const cloned = buildClonedEntryPayload({
            stock_instance_id: 'old',
            id: 'legacy',
            created_at: 't1',
            updated_at: 't2',
            symbol: 'BTC/USDT',
            active: true,
            user_id: 'u1',
            status: 'active',
            is_crypto: true,
            is_real_trade: false
        } as any, 'new-id');
        expect(cloned.stock_instance_id).toBe('new-id');
        expect(cloned.active).toBe(false);
        expect(cloned.status).toBe('active');
        expect((cloned as any).id).toBeUndefined();
    });

    it('clones, diffs and maps config upsert payloads', () => {
        const configs = [{ key: 'A', value: '1', description: 'd' }];
        const cloned = cloneConfigItems(configs as any);
        cloned[0].value = '2';

        expect(configs[0].value).toBe('1');
        expect(hasConfigChanges(configs as any, cloned as any)).toBe(true);
        expect(hasConfigChanges(configs as any, configs as any)).toBe(false);

        const payload = buildConfigUpsertPayload(configs as any, '2026-02-16T00:00:00.000Z');
        expect(payload[0]).toEqual({ key: 'A', value: '1', updated_at: '2026-02-16T00:00:00.000Z' });
    });

    it('maps settings form data and validates numeric fields', () => {
        const mapped = mapProfileToFormData({
            first_name: 'Sam',
            last_name: 'Trader',
            trade_enable: true,
            drop_threshold_for_buy: 0.05,
            gain_threshold_for_sell: 0.02,
            market_poll_interval_in_seconds: 30000
        });

        expect(mapped.first_name).toBe('Sam');
        expect(mapped.trade_enable).toBe(true);
        expect(mapped.drop_threshold_for_buy).toBe('0.05');

        const parsed = parseNumericSettings(mapped);
        expect(parsed.buyThreshold).toBe(0.05);
        expect(parsed.sellThreshold).toBe(0.02);
        expect(parsed.interval).toBe(30000);

        expect(() => parseNumericSettings({
            ...mapped,
            drop_threshold_for_buy: 'x'
        })).toThrow('Please enter valid numbers for thresholds and interval.');
    });
});
