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

const {
    authState,
    fromMock,
    confirmMock
} = vi.hoisted(() => ({
    authState: {
        user: { id: 'user-1', email: 'test@demo.test' } as any,
        profile: { role: 'user' } as any
    },
    fromMock: vi.fn(),
    confirmMock: vi.fn()
}));

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

vi.mock('../lib/supabaseClient', () => ({
    supabase: {
        from: fromMock
    }
}));

vi.mock('../components/EntryForm', () => ({
    EntryForm: ({ onSuccess, initialData }: any) => (
        <div>
            <span data-testid="initial-data">{initialData ? initialData.symbol : 'none'}</span>
            <button onClick={onSuccess}>SubmitEntry</button>
        </div>
    )
}));

const createMockQuery = (data: any, error: any = null) => {
    const chain: any = {
        select: vi.fn(),
        eq: vi.fn(),
        order: vi.fn(),
        then: vi.fn()
    };
    chain.select.mockReturnValue(chain);
    chain.eq.mockReturnValue(chain);
    chain.order.mockReturnValue(chain);
    chain.then.mockImplementation((cb: any) => Promise.resolve({ data, error }).then(cb));
    return chain;
};

describe('EntriesTab master suite', () => {
    const mockEntry = {
        stock_instance_id: 'entry-1',
        symbol: 'BTC/USDT',
        active: true,
        user_id: 'user-1',
        buy_price: '50000',
        sell_price: '55000',
        quantity: '1',
        status: 'active',
        is_crypto: true,
        is_real_trade: false,
        label: 'Test Entry'
    };

    const mockBotState: any = {
        orders: [],
        symbols: {},
        alerts: [],
        positions: [],
        history: [],
        settings: { executionMode: 'Paper' }
    };

    beforeEach(() => {
        vi.clearAllMocks();
        authState.user = { id: 'user-1', email: 'test@demo.test' };
        authState.profile = { role: 'user' };
        vi.stubGlobal('confirm', confirmMock);
        vi.stubGlobal('crypto', { randomUUID: () => 'uuid-123' });

        fromMock.mockImplementation((table: string) => {
            if (table === tableNameStocks) {
                return {
                    select: () => createMockQuery([mockEntry]),
                    delete: () => ({ eq: () => Promise.resolve({ error: null }) }),
                    insert: () => Promise.resolve({ error: null })
                };
            }
            return {
                select: () => createMockQuery([])
            };
        });
    });

    it('handles entry drawer interactions', async () => {
        const user = userEvent.setup();
        render(<EntriesTab botState={mockBotState} />);
        await waitFor(() => expect(screen.getByText('BTC/USDT')).toBeInTheDocument());

        await user.click(screen.getByText(/Manual Entry Injection/i));
        expect(screen.getByText(/New Opportunity Initialization/i)).toBeInTheDocument();
        await user.click(screen.getByText('SubmitEntry'));
        expect(screen.queryByText(/New Opportunity Initialization/i)).not.toBeInTheDocument();
    });

    it('derives diverse entry states (LOCKED, BLOCKED, SUBMITTED, CONFIRMED, ORPHAN)', async () => {
        const user = userEvent.setup();
        const entries = [
            { stock_instance_id: 's1', symbol: 'S1', active: true, status: 'active', is_real_trade: false },
            { stock_instance_id: 's2', symbol: 'S2', active: false, status: 'cooldown', is_real_trade: false }, // Use 'cooldown' instead of 'blocked' because 'blocked' contains 'lock'
            { stock_instance_id: 's3', symbol: 'S3', active: false, status: 'submitted', is_real_trade: false },
            { stock_instance_id: 's4', symbol: 'S4', active: false, status: 'confirmed', is_real_trade: false },
            { stock_instance_id: 's5', symbol: 'S5', active: false, status: 'orphan', is_real_trade: false },
        ];
        fromMock.mockImplementation(() => ({ select: () => createMockQuery(entries) }));

        render(<EntriesTab botState={mockBotState} />);

        await waitFor(() => expect(screen.getByText('S1')).toBeInTheDocument());
        expect(screen.getByText('LOCKED')).toBeInTheDocument();

        const suspendedTab = screen.getByRole('button', { name: /Suspended/i });
        await user.click(suspendedTab);

        await waitFor(() => expect(screen.getByText('S2')).toBeInTheDocument(), { timeout: 3000 });
        expect(screen.getByText('BLOCKED')).toBeInTheDocument();
        expect(screen.getByText('SUBMITTED')).toBeInTheDocument();
        expect(screen.getByText('CONFIRMED')).toBeInTheDocument();
        expect(screen.getByText('ORPHAN')).toBeInTheDocument();
    });

    it('covers clone and delete triggers', async () => {
        render(<EntriesTab botState={mockBotState} />);
        await waitFor(() => expect(screen.getByText('BTC/USDT')).toBeInTheDocument());

        const card = screen.getByText('BTC/USDT').closest('.group');
        const buttons = within(card as HTMLElement).getAllByRole('button');

        await fireEvent.click(buttons[1]);
        expect(fromMock).toHaveBeenCalledWith(tableNameStocks);

        confirmMock.mockReturnValue(true);
        await fireEvent.click(buttons[2]);
        expect(fromMock).toHaveBeenCalledWith(tableNameStocks);
    });
});
