// @vitest-environment jsdom
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { HistoryTab } from './HistoryTab';

const {
    authState,
    fetchTradeProfilesMock,
    fetchTradeHistoryMock,
    fetchPositionsBootstrapMock
} = vi.hoisted(() => ({
    authState: {
        user: { id: 'u1' },
        profile: { role: 'user' },
        refreshProfile: vi.fn(),
        session: { access_token: 'session-token' }
    },
    fetchTradeProfilesMock: vi.fn(),
    fetchTradeHistoryMock: vi.fn(),
    fetchPositionsBootstrapMock: vi.fn()
}));

vi.mock('../components/AuthContext', () => ({
    useAuth: () => authState
}));

vi.mock('../lib/profileApi', () => ({
    fetchTradeProfiles: fetchTradeProfilesMock
}));

vi.mock('../lib/tradeHistoryApi', () => ({
    fetchTradeHistory: fetchTradeHistoryMock
}));

vi.mock('../lib/positionsApi', () => ({
    fetchPositionsBootstrap: fetchPositionsBootstrapMock
}));

vi.mock('../hooks/useCanonicalLifecycle', () => ({
    useCanonicalLifecycle: () => ({
        snapshot: {
            lifecycleRows: [{ tradeId: 'TRD-1' }],
            realizedTrades: [],
            openPositions: [],
            diagnostics: { truncated: false }
        },
        loading: false,
        error: null
    })
}));

describe('HistoryTab Master Suite', () => {
    const historyData = [
        { id: 'h1', symbol: 'BTC', entry_price: 50000, exit_price: 51000, pnl: 1000, pnl_percent: 2, created_at: '2024-01-01T10:00:00Z', side: 'BUY', source: 'BOT', profile_id: 'p1', size: 1, reason: 'Trend' }
    ];

    beforeEach(() => {
        vi.clearAllMocks();
        authState.user = { id: 'u1' };
        authState.profile = { role: 'user' };
        authState.session = { access_token: 'session-token' };
        fetchTradeProfilesMock.mockResolvedValue([{ id: 'p1', name: 'Alpha', allocated_capital: 1000 }]);
        fetchTradeHistoryMock.mockResolvedValue(historyData);
        fetchPositionsBootstrapMock.mockResolvedValue({
            entries: [],
            orders: [{
                id: 'o1',
                order_id: 'o1',
                profile_id: 'p1',
                symbol: 'BTC',
                side: 'BUY',
                qty: 1,
                price: 50000,
                status: 'filled',
                timestamp: '2024-01-01T09:00:00Z',
                trade_id: 'TRD-1',
                action: 'ENTRY',
                source: 'BOT'
            }],
            historyTradeKeys: [{ trade_id: 'TRD-1', profile_id: 'p1' }],
            profiles: [{ id: 'p1', name: 'Alpha' }]
        });
    });

    it('processes metrics and handles sort toggles', async () => {
        const user = userEvent.setup();
        render(<HistoryTab />);

        await waitFor(() => expect(screen.getByText(/Total Trades/i)).toBeInTheDocument());
        await waitFor(() => expect(screen.getByText('BTC')).toBeInTheDocument());

        const sortBtn = await screen.findByRole('button', { name: /Newest/i });
        await user.click(sortBtn);
        await waitFor(() => expect(screen.queryByText(/Oldest/i)).toBeInTheDocument());

        await user.click(screen.getByText(/Oldest/i));
        await waitFor(() => expect(screen.queryByText(/Newest/i)).toBeInTheDocument());
    });

    it('covers date filtering and pagination', async () => {
        const user = userEvent.setup();
        const manyRecords = Array.from({ length: 25 }, (_, i) => ({
            id: `h${i}`,
            symbol: 'BTC',
            entry_price: 50000,
            exit_price: 51000,
            pnl: 1000,
            pnl_percent: 2,
            created_at: `2024-01-01T12:${String(i % 60).padStart(2, '0')}:00`,
            side: 'BUY',
            source: 'BOT',
            profile_id: 'p1',
            size: 1,
            reason: 'Trend',
            trade_id: `TRD-${i}`
        }));

        fetchTradeHistoryMock.mockResolvedValue(manyRecords);
        fetchPositionsBootstrapMock.mockResolvedValue({
            entries: [],
            orders: manyRecords.map((row) => ({
                id: row.id,
                order_id: row.id,
                profile_id: 'p1',
                symbol: row.symbol,
                side: row.side,
                qty: row.size,
                price: row.entry_price,
                status: 'filled',
                timestamp: row.created_at,
                trade_id: row.trade_id,
                action: 'ENTRY',
                source: 'BOT'
            })),
            historyTradeKeys: manyRecords.map((row) => ({ trade_id: row.trade_id, profile_id: 'p1' })),
            profiles: [{ id: 'p1', name: 'Alpha' }]
        });

        const { container } = render(<HistoryTab />);
        await screen.findByText(/Page 1 \/ 2/i, {}, { timeout: 5000 });

        const dateInputs = container.querySelectorAll('input[type="date"]');
        if (dateInputs.length >= 2) {
            fireEvent.change(dateInputs[0], { target: { value: '2024-01-01' } });
            fireEvent.change(dateInputs[1], { target: { value: '2024-01-02' } });
        }

        const nextBtn = await screen.findByRole('button', { name: /Next/i });
        await user.click(nextBtn);
        await screen.findByText(/Page 2 \/ 2/i);

        const prevBtn = await screen.findByRole('button', { name: /Prev/i });
        await user.click(prevBtn);
        await screen.findByText(/Page 1 \/ 2/i);

        await user.click(screen.getByText(/Clear/i));
    });

    it('covers empty fallback and source mapping', async () => {
        fetchTradeHistoryMock.mockResolvedValue([
            { ...historyData[0], source: 'MANUAL', profile_id: null }
        ]);
        render(<HistoryTab />);
        await waitFor(() => expect(screen.queryByText(/MANUAL/i)).toBeInTheDocument());
    });
});
