import {act, findByText, fireEvent, getByText, render, screen, waitFor} from '@testing-library/react';
import MockAppWithProviders from '../../../../mocks/AppWithProvider';
import mockRouter from 'next-router-mock'
import LoginExpertComponent from "@/components/login-expert/LoginExpertComponent";
import LoginLinkRouting from "@/components/login-expert/LoginLinkRouting";

describe('Login expert component from login page', () => {

    describe('Rendering', () => {
        it('LoginExpertComponent should see login expert text on the page',() => {
            render(
                <MockAppWithProviders>
                    <LoginExpertComponent />
                </MockAppWithProviders>
            );
            const loginExpertElement = screen.getByRole('heading', { level: 4 });
            expect(loginExpertElement).toHaveTextContent('ورود کارشناس');
        });

        it('LoginExpertComponent from LoginComponent Button should render login text', () => {
            render(
                <MockAppWithProviders>
                    <LoginExpertComponent />
                </MockAppWithProviders>
            );
            const button = screen.getByText("ورود");
            // Assertions for button props
            expect(button).toHaveAttribute('type', 'submit');
            expect(button).toHaveTextContent('ورود');
        });

        it("Show error when username is empty", async ()=>{
            render(
                <MockAppWithProviders>
                    <LoginExpertComponent />
                </MockAppWithProviders>
            );

            const usernameInput = screen.getByLabelText("نام کاربری")

            expect(screen.queryByText("وارد کردن نام کاربری الزامیست")).not.toBeInTheDocument()

            fireEvent.blur(usernameInput);

            await waitFor(()=>{
            expect(screen.queryByText("وارد کردن نام کاربری الزامیست")).toBeInTheDocument()
            })

            fireEvent.change(usernameInput, {target : {value : "testuser"}})

            await waitFor(()=>{
                expect(screen.queryByText("وارد کردن نام کاربری الزامیست")).not.toBeInTheDocument()
            })
        })
        it("Show error when password is empty", async ()=>{
            render(
                <MockAppWithProviders>
                    <LoginExpertComponent />
                </MockAppWithProviders>
            );

            const passwordInput = screen.getByLabelText("رمز عبور")

            expect(screen.queryByText("وارد کردن رمز عبور الزامیست")).not.toBeInTheDocument()

            fireEvent.blur(passwordInput);

            await waitFor(()=>{
                expect(screen.queryByText("وارد کردن رمز عبور الزامیست")).toBeInTheDocument()
            })

            fireEvent.change(passwordInput, {target : {value : "testuser"}})

            await waitFor(()=>{
                expect(screen.queryByText("وارد کردن رمز عبور الزامیست")).not.toBeInTheDocument()
            })
        })
    });

    describe("Behavior", ()=>{
        it('Should fill the username field', async () => {
            render(
                <MockAppWithProviders>
                    <LoginExpertComponent />
                </MockAppWithProviders>
            );
            // Get username and password input elements by their name attributes
            const usernameInput = screen.getByLabelText('نام کاربری');

            fireEvent.change(usernameInput, {target: {value: 'testuser'}});
            await act(async ()=>{
                // Simulate user input
                expect(usernameInput).toHaveValue('testuser');
            })
        });

        it('Should fill the password fields', async () => {
            render(
                <MockAppWithProviders>
                    <LoginExpertComponent />
                </MockAppWithProviders>
            );
            // Get username and password input elements by their name attributes
            const passwordInput = screen.getByLabelText('رمز عبور');
            fireEvent.change(passwordInput, {target: {value: 'password123'}});

            await act(async ()=>{
                // Simulate user input
                expect(passwordInput).toHaveValue('password123');
            })
        });

        // this test is for when back url does not exist to run this test you should comment if in mock func
        it('Should get main page when back url dos not exist', async () => {
            render(
                <MockAppWithProviders>
                    <LoginLinkRouting/>
                </MockAppWithProviders>
            )
            const linkElement = await screen.findByTestId("link_routing")
            expect(linkElement).toHaveTextContent("بازگشت به صفحه اصلی")
        });

    })
    describe("validation", ()=>{
        it("Disabled submit button until fields completed", async ()=> {

            render(
                <MockAppWithProviders>
                    <LoginExpertComponent/>
                </MockAppWithProviders>
            )
            const usernameInput = screen.getByLabelText('نام کاربری');
            const passwordInput = screen.getByLabelText('رمز عبور');
            const submitButton = screen.getByText('ورود');

            expect(submitButton).toBeDisabled();

            fireEvent.change(usernameInput, {target: {value: 'testuser'}});

            await waitFor(async () => {
                // Now, the submit button should be enabled because both fields are completed
                expect(submitButton).toBeDisabled();
            });

            fireEvent.change(passwordInput, {target: {value: 'password123'}});

            await waitFor(async () => {
                // Now, the submit button should be enabled because both fields are completed
                expect(submitButton).toBeEnabled();
            });
        })
    })
});