import {act, fireEvent, render, screen, waitFor} from "@testing-library/react";
import React from 'react';
import MockAppWithProviders from "../../../../../../../../../mocks/AppWithProvider";
import * as Yup from "yup";
import {Formik} from "formik";
import PersonalInfo from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo";
import {useTranslations} from "next-intl";
import Province from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province";


const CreateFormMock = ({Component}) => {
    const t = useTranslations();
    const validationSchema = Yup.object().shape({
        full_name: Yup.string().required(t("ExpertMangement.error_message_full_name")),
        email: Yup.string().required(t("ExpertMangement.error_message_email")),
        phone_number: Yup.string().required(t("ExpertMangement.error_message_phone_number")),
        telephone_id: Yup.string().required(t("ExpertMangement.error_message_telephone_id")),
        national_id: Yup.string().required(t("ExpertMangement.error_message_national_id")),
        gender: Yup.string().required(t("ExpertMangement.error_message_gender"))
    });
    return (
        <Formik
            initialValues={{
                full_name: "",
                email: "",
                phone_number: "",
                telephone_id: "",
                national_id: "",
                gender: ""
            }}
            validationSchema={validationSchema}
            onSubmit={(values, {}) => {
            }}
        >
            {formikProps => (<Component formik={formikProps}></Component>)}
        </Formik>
    );
};


describe("PersonalInfo Component From Expert Management (create)", () => {
    describe("Rendering", () => {
        it("full_name TextField Rendered", async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            await waitFor(() => {
                const fullNameTextField = screen.queryByLabelText('نام کامل');
                expect(fullNameTextField).toBeInTheDocument();
            });
        });
        it("Email TextField Rendered", async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            await waitFor(() => {
                const emailTextField = screen.queryByLabelText('پست الکترونیک');
                expect(emailTextField).toBeInTheDocument();
            });
        });
        it("Phone Number TextField Rendered", async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            await waitFor(() => {
                const phoneNumberTextField = screen.queryByLabelText('شماره همراه');
                expect(phoneNumberTextField).toBeInTheDocument();
            });
        });
        it("telephone id TextField Rendered", async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            await waitFor(() => {
                const telephoneIdTextField = screen.queryByLabelText('کد تلفن');
                expect(telephoneIdTextField).toBeInTheDocument();
            });
        });
        it("National Id TextField Rendered", async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            await waitFor(() => {
                const nationalIdTextField = screen.queryByLabelText('کد ملی');
                expect(nationalIdTextField).toBeInTheDocument();
            });
        });
        it("Gender Select Box Rendered", async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            await waitFor(() => {
                const genderSelectBox = screen.getByTestId('select-box');
                expect(genderSelectBox).toBeInTheDocument();
            });
        });
    });
    describe("Behavioral", () => {
        it("Name TextField Work Correctly", async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            const nameTextField = screen.queryByLabelText('نام کامل');
            fireEvent.change(nameTextField, {target: {value: 'exampleName'}});
            await act(() => {
                expect(nameTextField).toHaveValue('exampleName');
            })
        });
        it("Email TextField Work Correctly", async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            const emailTextField = screen.queryByLabelText('پست الکترونیک');
            fireEvent.change(emailTextField, {target: {value: 'exampleEmail'}});
            await act(() => {
                expect(emailTextField).toHaveValue('exampleEmail');
            })
        });
        it("Phone Number TextField Work Correctly", async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            const phoneNumberTextField = screen.queryByLabelText('شماره همراه');
            fireEvent.change(phoneNumberTextField, {target: {value: 'examplePhoneNumber'}});
            await act(() => {
                expect(phoneNumberTextField).toHaveValue('examplePhoneNumber');
            })
        });
        it("Telephone Id TextField Work Correctly", async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            const telephoneIdTextField = screen.queryByLabelText('کد تلفن');
            fireEvent.change(telephoneIdTextField, {target: {value: 'exampleTelephoneId'}});
            await act(() => {
                expect(telephoneIdTextField).toHaveValue('exampleTelephoneId');
            })
        });
        it("National Id TextField Work Correctly", async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            const nationalIdTextField = screen.queryByLabelText('کد ملی');
            fireEvent.change(nationalIdTextField, {target: {value: 'exampleNationalId'}});
            await act(() => {
                expect(nationalIdTextField).toHaveValue('exampleNationalId');
            })
        });
        it("Gender Select Box Work Correctly", async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            const genderSelectBox = screen.getByTestId('select-box');
            const genderSelectOpener = await waitFor(() => screen.getByTestId("option-opener-gender"));

            await waitFor(() => {
                expect(genderSelectBox).toBeInTheDocument();
            });

            fireEvent.mouseDown(genderSelectOpener);
            await waitFor(() => {
                const selectItem = screen.queryByText("مرد");
                expect(selectItem).toBeInTheDocument();
            });

        });
    });
    describe("validation", () => {
        it('Should See Error When Name Input Is Empty', async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);

            const nameInput = screen.queryByLabelText('نام کامل');

            fireEvent.change(nameInput, {target: {value: ''}});
            fireEvent.blur(nameInput);

            await waitFor(() => {
                expect(screen.queryByText("نام کامل خود را وارد کنید")).toBeInTheDocument()
            });
        });
        it('Should See Error When Email Input Is Empty', async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);

            const emailInput = screen.queryByLabelText('پست الکترونیک');

            fireEvent.change(emailInput, {target: {value: ''}});
            fireEvent.blur(emailInput);

            await waitFor(() => {
                expect(screen.queryByText("پست الکترونیک خود را وارد کنید")).toBeInTheDocument()
            });
        });
        it('Should See Error When Phone Number Input Is Empty', async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);

            const phoneNumberInput = screen.queryByLabelText('شماره همراه');

            fireEvent.change(phoneNumberInput, {target: {value: ''}});
            fireEvent.blur(phoneNumberInput);

            await waitFor(() => {
                expect(screen.queryByText("شماره همراه خود را وارد کنید")).toBeInTheDocument()
            });
        });
        it('Should See Error When telephone Id Input Is Empty', async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);

            const telephoneIdTextField = screen.queryByLabelText('کد تلفن');

            fireEvent.change(telephoneIdTextField, {target: {value: ''}});
            fireEvent.blur(telephoneIdTextField);

            await waitFor(() => {
                expect(screen.queryByText("کد تلفن خود را وارد کنید")).toBeInTheDocument()
            });
        });
        it('Should See Error When National Id Input Is Empty', async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);

            const nationalIdInput = screen.queryByLabelText('کد ملی');

            fireEvent.change(nationalIdInput, {target: {value: ''}});
            fireEvent.blur(nationalIdInput);

            await waitFor(() => {
                expect(screen.queryByText("کد ملی خود را وارد کنید")).toBeInTheDocument()
            });
        });
        it('Should Select An Item With Valid Value of gender', async () => {
            render(<MockAppWithProviders><CreateFormMock Component={PersonalInfo}/></MockAppWithProviders>);
            const genderInput = screen.getByTestId("input-gender")
            const genderSelectOpener = await waitFor(() => screen.getByTestId("option-opener-gender"));

            fireEvent.mouseDown(genderSelectOpener);
            const selectItem = await waitFor(() => screen.queryByText("مرد"));
            expect(selectItem).toBeInTheDocument();
            fireEvent.click(selectItem);
            await waitFor(() => {
                expect(genderInput.value).toBe('male')
            });
        });
    })
});