import { screen, waitFor } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { ApplicationDetails } from "../pages/ApplicationDetails"
import { renderWithProvidersAndRoute } from "./test-utils"
import { onboardingService } from "@/services/onboarding.service"
import { SHARED_APP_STATUSES, TEST_STRINGS } from "@/testing/constants"
import { mockOnboardingService, createGlobalMockApplication } from "@/testing/mocks"

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

  const renderDetails = (overrides = {}) => {
    const appData = createGlobalMockApplication(overrides)
    ;(mockOnboardingService.getApplicationById as jest.Mock).mockResolvedValue(appData)
    return renderWithProvidersAndRoute(<ApplicationDetails />, {
      initialEntry: `/applications/${appData.id}`,
      routePath: "/applications/:id",
      preloadedState: {
        auth: { 
          user: { id: "admin-1", role: "DD Admin" } as any, 
          token: "tok", 
          isAuthenticated: true, 
          loading: false, 
          error: null 
        }
      }
    })
  }

  it("should verify statutory information update logic", async () => {
    const user = userEvent.setup()
    renderDetails()

    const editBtn = await screen.findByTestId("onboarding-applicant-info-edit-statutory")
    await user.click(editBtn)

    const panInput = screen.getByTestId("onboarding-applicant-info-input-pan")
    await user.clear(panInput)
    await user.type(panInput, TEST_STRINGS.VALID_PAN)

    const saveBtn = screen.getByTestId("onboarding-applicant-info-statutory-save")
    await user.click(saveBtn)

    await waitFor(() => {
      expect(onboardingService.updateApplication).toHaveBeenCalledWith(
        expect.any(String),
        expect.objectContaining({ panNumber: TEST_STRINGS.VALID_PAN })
      )
    })
  })

  it("should enforce mandatory remarks for rejection actions", async () => {
    const user = userEvent.setup()
    
    // Status must be an administrative stage for Reject button to appear
    renderDetails({ overallStatus: SHARED_APP_STATUSES.LOA })

    const rejectBtn = await screen.findByTestId("onboarding-details-reject-button")
    await user.click(rejectBtn)

    // Attempt to submit without remarks
    const submitBtn = screen.getByTestId("onboarding-reject-submit-button")
    await user.click(submitBtn)
    
    // API should NOT be called if remarks are empty (verifying business constraint)
    expect(onboardingService.submitStageDecision).not.toHaveBeenCalled()
  })

  it("should verify the full approval workflow with remarks", async () => {
    const user = userEvent.setup()
    renderDetails({ overallStatus: SHARED_APP_STATUSES.LOA })

    const approveBtn = await screen.findByTestId("onboarding-details-approve-button")
    await user.click(approveBtn)

    const remarkInput = screen.getByTestId("onboarding-approve-remark-textarea")
    await user.type(remarkInput, "Decision: Approved based on secondary verification.")

    const submitBtn = screen.getByTestId("onboarding-approve-submit-button")
    await user.click(submitBtn)

    await waitFor(() => {
        expect(onboardingService.submitStageDecision).toHaveBeenCalledWith(expect.objectContaining({
            decision: "Approved",
            remarks: "Decision: Approved based on secondary verification."
        }))
    })
  })
})
