import { screen, waitFor } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { OpportunityRequestsPage } from "../pages/OpportunityRequestsPage"
import { renderWithProviders } from "./test-utils"
import { SHARED_APP_STATUSES } from "@/testing/constants"
import {
    mockOnboardingService,
    mockAdminService,
    createGlobalMockApplication,
} from "@/testing/mocks"

describe("OpportunityRequestsFlow - Lead Triage Verification", () => {
    beforeEach(() => {
        jest.clearAllMocks()
    })

    const renderPage = (apps: any[] = []) => {
        ;(mockOnboardingService.getApplications as jest.Mock).mockResolvedValue({ 
            success: true, 
            data: apps 
        })
        return renderWithProviders(<OpportunityRequestsPage onViewDetails={jest.fn()} />, {
            preloadedState: {
                auth: { 
                    user: { id: "admin-1", role: "DD Admin" } as any, 
                    token: "test-token", 
                    isAuthenticated: true, 
                    loading: false, 
                    error: null 
                }
            }
        })
    }

    it("should display the list of lead opportunities and support multi-field search", async () => {
        const mockApps = [
            createGlobalMockApplication({ 
                id: "opp-1", 
                applicantName: "Primary Dealer", 
                overallStatus: SHARED_APP_STATUSES.OPP_REQUEST,
                ddLeadShortlisted: false // Opportunities are NOT yet shortlisted
            }),
            createGlobalMockApplication({ 
                id: "opp-2", 
                applicantName: "Secondary Motors", 
                overallStatus: SHARED_APP_STATUSES.OPP_REQUEST,
                ddLeadShortlisted: false
            })
        ]
        
        const user = userEvent.setup()
        renderPage(mockApps)

        expect(await screen.findByText(/Primary Dealer/i)).toBeInTheDocument()
        expect(screen.getByText(/Secondary Motors/i)).toBeInTheDocument()

        const searchInput = screen.getByTestId("onboarding-opp-requests-search-input")
        await user.type(searchInput, "Primary")

        expect(screen.getByText(/Primary Dealer/i)).toBeInTheDocument()
        expect(screen.queryByText(/Secondary Motors/i)).not.toBeInTheDocument()
    })

    it("should handle bulk shortlisting of selected leads", async () => {
        ;(mockAdminService.getAllUsers as jest.Mock).mockResolvedValue({
            success: true,
            data: [{ id: "assign-1", fullName: "Assignee One", email: "assign@test.com" }],
        })
        const mockApps = [
            createGlobalMockApplication({
                id: "app-1",
                applicantName: "Dealer One",
                overallStatus: SHARED_APP_STATUSES.OPP_REQUEST,
                ddLeadShortlisted: false,
                isShortlisted: false,
            }),
            createGlobalMockApplication({
                id: "app-2",
                applicantName: "Dealer Two",
                overallStatus: SHARED_APP_STATUSES.OPP_REQUEST,
                ddLeadShortlisted: false,
                isShortlisted: false,
            }),
        ]
        const user = userEvent.setup()
        renderPage(mockApps)

        await screen.findByText(/Dealer One/i)
        await user.click(
            screen.getByTestId("onboarding-opp-requests-table-select-item-app-1")
        )
        await user.click(
            screen.getByTestId("onboarding-opp-requests-table-select-item-app-2")
        )
        await user.click(screen.getByTestId("onboarding-opp-requests-bulk-shortlist-btn"))

        await screen.findByTestId("onboarding-opp-requests-shortlist-modal")
        await user.click(screen.getByTestId("onboarding-opp-requests-assignee-trigger"))
        await user.click(
            await screen.findByTestId("onboarding-opp-requests-assignee-item-0")
        )
        await user.click(screen.getByTestId("onboarding-opp-requests-shortlist-confirm-btn"))

        await waitFor(() => {
            expect(mockOnboardingService.shortlistApplications).toHaveBeenCalled()
        })
    })

    it("should display an empty state message when no leads match the filters", async () => {
        renderPage([])

        expect(await screen.findByText(/No opportunity requests found/i)).toBeInTheDocument()
    })

    it("should exclude leads already shortlisted by DD Lead", async () => {
        const mockApps = [
            createGlobalMockApplication({
                id: "still-waiting",
                applicantName: "Waiting For DD Lead",
                overallStatus: SHARED_APP_STATUSES.OPP_REQUEST,
                ddLeadShortlisted: false,
                isShortlisted: false,
            }),
            createGlobalMockApplication({
                id: "already-done",
                applicantName: "Already DD Lead Shortlisted",
                overallStatus: SHARED_APP_STATUSES.OPP_REQUEST,
                ddLeadShortlisted: true,
                isShortlisted: true,
            }),
        ]
        renderPage(mockApps)

        expect(await screen.findByText(/Waiting For DD Lead/i)).toBeInTheDocument()
        expect(screen.queryByText(/Already DD Lead Shortlisted/i)).not.toBeInTheDocument()
    })

    it("should exclude applications outside early opportunity statuses", async () => {
        const mockApps = [
            createGlobalMockApplication({
                id: "early",
                applicantName: "Early Stage Lead",
                overallStatus: "Shortlisted",
                ddLeadShortlisted: false,
            }),
            createGlobalMockApplication({
                id: "late-fdd",
                applicantName: "Late FDD Stage",
                overallStatus: SHARED_APP_STATUSES.FDD,
                ddLeadShortlisted: false,
            }),
        ]
        renderPage(mockApps)

        expect(await screen.findByText(/Early Stage Lead/i)).toBeInTheDocument()
        expect(screen.queryByText(/Late FDD Stage/i)).not.toBeInTheDocument()
    })
})
