import { render, screen, waitFor } from "@testing-library/react";
import JobDetailPage from "./page";
import { jobsApi } from "@/lib/api";

// Mock React.use
jest.mock("react", () => ({
    ...jest.requireActual("react"),
    use: (promise: Promise<any>) => {
        // A simple mock implementation that unwraps the resolved value
        // This is a naive implementation for testing purposes
        // In a real environment, we might need a better way to test 'use'
        let status = "pending";
        let result: any;
        let suspender = promise.then(
            (r) => {
                status = "success";
                result = r;
            },
            (e) => {
                status = "error";
                result = e;
            }
        );
        // Since we are not in a real suspense boundary, we cheat a bit for sync usage in tests if possible
        // But honestly, it's easier to just mock 'use' as a function that returns the value if the promise is already resolved
        // or just pass a resolved object if we mocking the hook.
        // However, since 'use' is imported from 'react', we can mock it.
        return { id: "1" }; // simplified return for now matching param
    },
}));

// Better approach: mock the component if we can't easily mock `use`
// But we want to test the component.
// Let's assume params is passed as a Promise.

// Mock Next.js hooks
jest.mock("next/navigation", () => ({
    useRouter: () => ({
        push: jest.fn(),
    }),
}));

// Mock API
jest.mock("@/lib/api", () => ({
    jobsApi: {
        getById: jest.fn(),
    },
}));

// Mock components
jest.mock("@/components/navbar", () => ({ Navbar: () => <div>Navbar</div> }));
jest.mock("@/components/footer", () => ({ Footer: () => <div>Footer</div> }));
jest.mock("@/components/ui/button", () => ({ Button: ({ children, ...props }: any) => <button {...props}>{children}</button> }));
jest.mock("@/components/ui/card", () => ({
    Card: ({ children }: any) => <div>{children}</div>,
    CardHeader: ({ children }: any) => <div>{children}</div>,
    CardTitle: ({ children }: any) => <h1>{children}</h1>,
    CardDescription: ({ children }: any) => <div>{children}</div>,
    CardContent: ({ children }: any) => <div>{children}</div>,
}));
jest.mock("@/components/ui/badge", () => ({ Badge: ({ children }: any) => <span>{children}</span> }));
jest.mock("@/components/ui/avatar", () => ({
    Avatar: ({ children }: any) => <div>{children}</div>,
    AvatarFallback: ({ children }: any) => <div>{children}</div>,
    AvatarImage: ({ src }: any) => <img src={src} alt="avatar" />,
}));
jest.mock("@/components/ui/separator", () => ({ Separator: () => <hr /> }));

// Mock framer-motion
jest.mock("framer-motion", () => ({
    motion: {
        div: ({ children }: any) => <div>{children}</div>,
    }
}));

describe("JobDetailPage", () => {
    const mockJob = {
        id: "1",
        title: "Senior Go Developer",
        companyName: "GoHorse Inc",
        description: "Great job",
        location: "Remote",
        salaryMin: 10000,
        salaryMax: 20000,
        createdAt: new Date().toISOString(),
    };

    beforeEach(() => {
        jest.clearAllMocks();
    });

    it("renders job details when found", async () => {
        (jobsApi.getById as jest.Mock).mockResolvedValue(mockJob);

        // We can't easily test the `await params` unwrapping in simple Jest without complex setup.
        // We will assume the mock of `React.use` works or we pass a resolved promise?
        // Actually, `use` is a hook.

        // Simplification: We will rendering the component.
        // However, `use(params)` inside the component will call our mocked `use`.

        const paramsPromise = Promise.resolve({ id: "1" });
        render(<JobDetailPage params={paramsPromise} />);

        expect(screen.getByText("Loading job...")).toBeInTheDocument();

        await waitFor(() => {
            expect(screen.queryByText("Loading job...")).not.toBeInTheDocument();
            expect(screen.getByText("Senior Go Developer")).toBeInTheDocument();
            expect(screen.getByText("GoHorse Inc")).toBeInTheDocument();
        });
    });

    it("renders not found state", async () => {
        (jobsApi.getById as jest.Mock).mockResolvedValue(null);
        const paramsPromise = Promise.resolve({ id: "999" });
        render(<JobDetailPage params={paramsPromise} />);

        await waitFor(() => {
            expect(screen.getByText("Job not found")).toBeInTheDocument();
        });
    });
});
