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

describe("ApplicationsPage - Robust Feature Verification", () => {
    beforeEach(() => {
        jest.clearAllMocks()
    })

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

    it("should correctly filter Dealership Requests based on business rules", async () => {
        // Business Rules:
        // 1. Must be shortlisted (ddLeadShortlisted: true)
        // 2. Must NOT be in initial Questionnaire/Submitted states
        // 3. Must NOT be an excluded ID (5, 6, 7, 8)
        const mockApps = [
            createGlobalMockApplication({ 
                id: "valid-1", 
                applicantName: "Visible Application", 
                overallStatus: SHARED_APP_STATUSES.FDD, 
                ddLeadShortlisted: true 
            }),
            createGlobalMockApplication({ 
                id: "invalid-status", 
                applicantName: "Hidden By Status", 
                overallStatus: SHARED_APP_STATUSES.SUBMITTED, 
                ddLeadShortlisted: true 
            }),
            createGlobalMockApplication({ 
                id: "not-shortlisted", 
                applicantName: "Hidden By Shortlist", 
                overallStatus: SHARED_APP_STATUSES.ARCH, 
                ddLeadShortlisted: false,
                isShortlisted: false,
            }),
            createGlobalMockApplication({ 
                id: "5", // Excluded ID
                applicantName: "Hidden By Excluded ID", 
                overallStatus: SHARED_APP_STATUSES.LOI, 
                ddLeadShortlisted: true 
            })
        ]
        
        renderPage(mockApps)

        // Verify positive visibility
        expect(await screen.findByText("Visible Application")).toBeInTheDocument()

        // Verify negative visibility (proving the filter logic is actually working, not bypassed)
        expect(screen.queryByText("Hidden By Status")).not.toBeInTheDocument()
        expect(screen.queryByText("Hidden By Shortlist")).not.toBeInTheDocument()
        expect(screen.queryByText("Hidden By Excluded ID")).not.toBeInTheDocument()
    })

    it("should search across name, ID, and email with case-insensitivity", async () => {
        const user = userEvent.setup()
        const mockApps = [
            createGlobalMockApplication({ 
                id: "app-search", 
                applicationId: "REG-SEARCH-001",
                applicantName: "Specific Dealer Name", 
                overallStatus: SHARED_APP_STATUSES.LOI, 
                ddLeadShortlisted: true 
            })
        ]
        renderPage(mockApps)

        const searchInput = await screen.findByTestId("onboarding-applications-search-input")
        
        // 1. Search by name (case-insensitive)
        await user.type(searchInput, "specific")
        expect(await screen.findByText("Specific Dealer Name")).toBeInTheDocument()

        // 2. Search by Registration ID
        await user.clear(searchInput)
        await user.type(searchInput, "REG-SEARCH")
        expect(await screen.findByText("Specific Dealer Name")).toBeInTheDocument()
    })

    it("should hide applications still in questionnaire stages (including Questionnaire Completed)", async () => {
        const mockApps = [
            createGlobalMockApplication({
                id: "qc-1",
                applicantName: "Hidden Questionnaire Completed",
                overallStatus: "Questionnaire Completed",
                ddLeadShortlisted: true,
            }),
            createGlobalMockApplication({
                id: "show-1",
                applicantName: "Visible Post Questionnaire",
                overallStatus: SHARED_APP_STATUSES.LOI,
                ddLeadShortlisted: true,
            }),
        ]
        renderPage(mockApps)

        expect(await screen.findByText("Visible Post Questionnaire")).toBeInTheDocument()
        expect(screen.queryByText("Hidden Questionnaire Completed")).not.toBeInTheDocument()
    })

    it("should filter by My Assignments when checkbox is enabled", async () => {
        const user = userEvent.setup()
        const mockApps = [
            createGlobalMockApplication({
                id: "mine-1",
                applicantName: "Assigned To Me",
                overallStatus: SHARED_APP_STATUSES.LOI,
                ddLeadShortlisted: true,
                assignedTo: "admin-1",
            }),
            createGlobalMockApplication({
                id: "other-1",
                applicantName: "Assigned To Someone Else",
                overallStatus: SHARED_APP_STATUSES.LOI,
                ddLeadShortlisted: true,
                assignedTo: "other-user",
            }),
        ]
        renderPage(mockApps)

        expect(await screen.findByText("Assigned To Me")).toBeInTheDocument()
        expect(screen.getByText("Assigned To Someone Else")).toBeInTheDocument()

        await user.click(screen.getByTestId("onboarding-applications-assignments-checkbox"))

        expect(screen.getByText("Assigned To Me")).toBeInTheDocument()
        expect(screen.queryByText("Assigned To Someone Else")).not.toBeInTheDocument()
    })

    it("should handle API failures gracefully without crashing the dashboard", async () => {
        // Mock a 500 or Network error
        ;(mockOnboardingService.getApplications as jest.Mock).mockRejectedValue(new Error("Network Error"))
        
        // Suppress console.error for this test to keep logs clean
        const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
        
        renderPage([])

        // The dashboard should still render its UI shell and empty table, not crash
        expect(await screen.findByTestId("onboarding-applications-search-input")).toBeInTheDocument()
        expect(screen.getByTestId("onboarding-applications-count-text")).toHaveTextContent("0 applications")
        
        consoleSpy.mockRestore()
    })
})
