import { forwardRef , ReactElement , Ref, useEffect, useState } from "react"
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import { useDispatch } from "react-redux";
import { AppDispatch, useAppSelector } from "@/redux/store";
import { setAddPopUp , add } from "@/redux/features/members-slice"
import { useTranslations } from "next-intl";
import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
import Slide from '@mui/material/Slide';
import { TransitionProps } from '@mui/material/transitions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogActions from '@mui/material/DialogActions';
import CircularProgress from '@mui/material/CircularProgress';
import { FormikWizard } from 'formik-wizard-form';
import * as Yup from "yup";
import Select from 'react-select'
import AsyncSelect from 'react-select/async';
import { components } from 'react-select';
import searchForServices from "@/functions/requests/members/searchForServices";

export default function AddPopUp()
{
    // declare the needed variables
    // redux
    const dispatch = useDispatch<AppDispatch>();
    // intl-18
    const t = useTranslations('members');
    // mui
    const theme = useTheme();
    const fullScreen = useMediaQuery(theme.breakpoints.down('md'));
    // get state from redux
    const addPopUp = useAppSelector((state) => state.membersReducer.value.addPopUp)
    const themeType = useAppSelector((state) => state.themeTypeReducer.value.themeType)
    // setup the popup animation
    const Transition = forwardRef(function Transition(
        props: TransitionProps & {
          children: ReactElement<any, any>;
        },
        ref: Ref<unknown>,
      ) {
        return <Slide direction="up" ref={ref} {...props} />;
    });
    // set the form init values
    const [initialFormValues , setInitialFormValues] = useState<{
        firstName: string | null,
        lastName: string | null,
        email: string | null,
        phone: string | null,
        address: string | null,
        services: [string] | [],
        planDelay: string | null,
        gendre: string | null, // m or w
        startBodyForm: string | null,
        startWeight: string | null,
    }>({
        firstName : '', 
        lastName : '', 
        phone: '', 
        email: '', 
        address: '', 
        services: [],
        planDelay: '',
        gendre: 'm',
        startBodyForm: '',
        startWeight: '',
    })
    // first page
    const FirstPaper = ({
        values,
        errors,
        touched,
        handleChange,
        handleBlur,
        handleSubmit,
        isSubmitting,
        setFieldValue  
    } : any) => {
        return (
            <DialogContent>
                {
                    // dialog text content contain a small description to the current form part
                }
                <DialogContentText sx={{color: theme.palette.text.primary }} id="alert-dialog-slide-description">
                    <h1 className="text-[18px] font-tajawal">{t('memberAddText1')}</h1>
                </DialogContentText>
                <div className="
                    [&_*]:fill-text/80 [&_*]:dark:fill-text-dark/80
                    [&_*]:text-text/80 [&_*]:dark:text-text-dark/80 
                    [&_*]:placeholder-text/80 [&_*]:dark:placeholder-text-dark/80 
                    w-full h-auto mt-[36px] flex flex-col gap-3
                ">
                    <div className="w-full flex lg:flex-row flex-col lg:gap-12 gap-7">
                        <div className="lg:w-1/2 w-full flex flex-col gap-5">
                            <h3 className="font-bold">{t('identificationInformation')}</h3>
                            <div>
                                <input
                                    id="firstName"
                                    className="
                                        disabled:bg-primary-dark/10
                                        input lg:w-[350px] w-full border-2 border-primary-dark p-[11px]
                                        rounded-md bg-primary dark:bg-primary-dark focus:outline-none
                                    "
                                    onChange={handleChange}
                                    onBlur={handleBlur}
                                    value={values.firstName}
                                    placeholder={t('firstName')}
                                />
                                <p className="!text-error text-sm">{errors.firstName && touched.firstName && t(errors.firstName)}</p>
                            </div>
                            <div>
                                <input
                                    id="lastName"
                                    className="
                                        disabled:bg-primary-dark/10
                                        input lg:w-[350px] w-full border-2 border-primary-dark p-[11px]
                                        rounded-md bg-primary dark:bg-primary-dark focus:outline-none
                                    "
                                    onChange={handleChange}
                                    onBlur={handleBlur}
                                    value={values.lastName}
                                    placeholder={t('lastName')}
                                />
                                <p className="!text-error text-sm">{errors.lastName && touched.lastName && t(errors.lastName)}</p>
                            </div>
                            <h3 className="font-bold">{t('gendre')}</h3>
                            <div className="w-full flex justify-start items-center gap-5">
                                <input
                                    id={`mGendre`}
                                    type="checkbox" 
                                    className="form-checkbox p-3 border-none bg-primary-dark/10 dark:bg-primary/10 checked:bg-success-light dark:checked:bg-success-light checked:focus:bg-success-light checked:hover:bg-success-light rounded-md"
                                    onBlur={handleBlur}
                                    checked={values.gendre == 'm' ? true : false}
                                    onChange={() => {
                                        setFieldValue("gendre" , "m")
                                    }}
                                />
                                <label htmlFor={`mGendre`} className="w-full flex flex-col gap-3">
                                    <span>
                                        <h1 className="font-bold text-[16px]">{t("mGendre")}</h1>
                                    </span>
                                </label>
                            </div>
                            <div className="w-full flex justify-start items-center gap-5">
                                <input
                                    id={`wGendre`}
                                    type="checkbox" 
                                    className="form-checkbox p-3 border-none bg-primary-dark/10 dark:bg-primary/10 checked:bg-success-light dark:checked:bg-success-light checked:focus:bg-success-light checked:hover:bg-success-light rounded-md"
                                    onBlur={handleBlur}
                                    checked={values.gendre == 'w' ? true : false}
                                    onChange={() => {
                                        setFieldValue("gendre" , "w")
                                    }}
                                />
                                <label htmlFor={`wGendre`} className="w-full flex flex-col gap-3">
                                    <span>
                                        <h1 className="font-bold text-[16px]">{t("wGendre")}</h1>
                                    </span>
                                </label>
                            </div>
                        </div>
                        <div className="lg:w-1/2 w-full flex flex-col gap-5">
                            <h3 className="font-bold">{t('contactInformations')}</h3>
                            <div className="flex flex-col">
                                <input
                                    id="phone"
                                    className="
                                        disabled:bg-primary-dark/10
                                        input lg:w-[350px] w-full border-2 border-primary-dark p-[11px]
                                        rounded-md bg-primary dark:bg-primary-dark focus:outline-none
                                    "
                                    onChange={handleChange}
                                    onBlur={handleBlur}
                                    value={values?.phone}
                                    placeholder={t('phone')}
                                />
                                <p className="!text-error text-sm">{errors.phone && touched.phone && t(errors.phone)}</p>
                            </div>
                            <div>
                                <input
                                    id="email"
                                    className="
                                        disabled:bg-primary-dark/10
                                        input lg:w-[350px] w-full border-2 border-primary-dark p-[11px]
                                        rounded-md bg-primary dark:bg-primary-dark focus:outline-none
                                    "
                                    onChange={handleChange}
                                    onBlur={handleBlur}
                                    value={values?.email}
                                    placeholder={t('email')}
                                />
                                <p className="!text-error text-sm">{errors.email && touched.email && t(errors.email)}</p>
                            </div>
                            <div>
                                <textarea
                                    id="address"
                                    className="
                                        disabled:bg-primary-dark/10 max-h-[250px]
                                        input lg:w-[350px] w-full border-2 border-primary-dark p-[11px]
                                        rounded-md bg-primary dark:bg-primary-dark focus:outline-none
                                    "
                                    onChange={handleChange}
                                    onBlur={handleBlur}
                                    value={values?.address}
                                    placeholder={t('address')}
                                />
                                <p className="!text-error text-sm">{errors.address && touched.address && t(errors.address)}</p>
                            </div>
                        </div>
                    </div>
                </div>
            </DialogContent>
        )
    }
    // second paper
    const SecondPaper = ({
        values,
        errors,
        touched,
        handleChange,
        handleBlur,
        handleSubmit,
        isSubmitting,
        setFieldValue  
    } : any) => {
        async function loadServices(s : string) {
            let docs = await searchForServices(s)

            let options = docs.map((v , i) => {
                return {value: v._id , label: v.name}
            })

            return options
        }
        // body types options
        const bodyTypesOptions = [
            { value: 'weak', label: t('weak') },
            { value: 'graceful', label: t('graceful') },
            { value: 'middle', label: t('middle') },
            { value: 'midhuge', label: t('midhuge') },
            { value: 'huge', label: t('huge') }
        ]
        // contain the react select styles
        const customStyles = {
            container: styles => ({
                ...styles,
                width: "100%",
                backgroundColor: themeType == "light" ? theme.palette.primary.main : theme.palette.primary.dark,
                margin: "7px 0 0 0",
                fontFamily: 'Regular',
                borderRadius: 5,
                border: themeType == "light" ? "solid 2px black" : ""
            }),
            control: (styles : any, state : any) => ({
                ...styles,
                minHeight: "50px",
                height: "auto",
                border: "none",
                boxShadow: "none",
                borderRadius: 5,
                backgroundColor: themeType == "light" ? theme.palette.primary.main : theme.palette.primary.dark,
                fontFamily: 'Regular',
                color: "#000",
                opacity: 0.8,
            }),
            option: (styles : any, { isDisable , isSelected } : {
                isDisable: boolean,
                isSelected: boolean
            }) => ({
                ...styles,
                zIndex: 999,
                backgroundColor: isSelected ? theme.palette.primary.main : (themeType == "light" ? theme.palette.primary.main : theme.palette.primary.dark),
                color: isSelected ? `#fff` : `#000` ,
                padding: "15px",
                cursor: "pointer",
                '&:hover': {
                    backgroundColor: theme.palette.secondary.light,
                    color: `#fff`,
                },
                '&:active': {
                    backgroundColor: `#eee`,
                    color: `#000`,
                }
            }),
            menu: (styles : any, state : any) => ({
                ...styles,
                backgroundColor: themeType == "light" ? theme.palette.primary.main : theme.palette.primary.dark,
                borderRadius: 5,
            }),
            menuList: (styles : any, state : any) => ({
                ...styles,
                backgroundColor: themeType == "light" ? theme.palette.primary.main : theme.palette.primary.dark,
                height: '150px',
                border: `2px solid #000`,
                borderRadius: 5,
                "::-webkit-scrollbar": {
                    width: "0px",
                    height: "0px",
                },
            }),
        };
        // no options react select component
        const NoOptionsMessage = props => {
            return (
              <components.NoOptionsMessage {...props}>
                <span className="custom-css-class">{t('searchForServices')}</span> 
              </components.NoOptionsMessage>
            );
        };

        return (
            <DialogContent sx={{
                overflowY: 'visible',
            }}>
                {
                    // dialog text content contain a small description to the current form part
                }
                <DialogContentText sx={{color: theme.palette.text.primary }} id="alert-dialog-slide-description">
                    <h1 className="text-[18px] font-tajawal">{t('memberAddText1')}</h1>
                </DialogContentText>
                <div className="
                    [&_*]:fill-text/80 [&_*]:dark:fill-text-dark/80
                    [&_*]:text-text/80 [&_*]:dark:text-text-dark/80 
                    [&_*]:placeholder-text/80 [&_*]:dark:placeholder-text-dark/80 
                    w-full h-auto mt-[36px] flex flex-col gap-3
                ">
                    <div className="w-full flex lg:flex-row flex-col lg:gap-12 gap-7">
                        <div className="lg:w-1/2 w-full flex flex-col gap-5">
                            <h3 className="font-bold">{t('subscriptionInformations')}</h3>
                            <div className="flex flex-col">
                                <input
                                    type="number"
                                    id="planDelay"
                                    className="
                                        disabled:bg-primary-dark/10
                                        input lg:w-[350px] w-full border-2 border-primary-dark p-[11px]
                                        rounded-md bg-primary dark:bg-primary-dark focus:outline-none
                                    "
                                    onChange={handleChange}
                                    onBlur={handleBlur}
                                    value={values?.planDelay}
                                    placeholder={t('planDelay')}
                                />
                                <p className="!text-error text-sm">{errors.planDelay && touched.planDelay && t(errors.planDelay)}</p>
                            </div>
                            <div className="flex flex-col lg:max-w-[350px] min-h-[150px] h-auto">
                                <AsyncSelect
                                    cacheOptions
                                    loadOptions={loadServices}
                                    components={{ NoOptionsMessage }}
                                    loadingMessage={() => t('search')}
                                    isMulti
                                    styles={customStyles} 
                                    placeholder={t("services")}
                                    onChange={((e) => {
                                        let ids = e.map((v,i) => {
                                            return v.value
                                        })
                                        setFieldValue("services" , ids)
                                    })}
                                />                                
                                <p className="!text-error text-sm">{errors.services && touched.services && t(errors.services)}</p>
                            </div>
                        </div>
                        <div className="lg:w-1/2 w-full flex flex-col gap-5">
                            <h3 className="font-bold">{t('healthInformations')}</h3>
                            <div className="flex flex-col">
                                <input
                                    type="number"
                                    id="startWeight"
                                    className="
                                        disabled:bg-primary-dark/10
                                        input lg:w-[350px] w-full border-2 border-primary-dark p-[11px]
                                        rounded-md bg-primary dark:bg-primary-dark focus:outline-none
                                    "
                                    onChange={handleChange}
                                    onBlur={handleBlur}
                                    value={values?.startWeight}
                                    placeholder={t('startWeight')}
                                />
                                <p className="!text-error text-sm">{errors?.startWeight && touched?.startWeight && t(errors?.startWeight)}</p>
                            </div>
                            <div className="flex flex-col gap-5 lg:max-w-[350px] min-h-[150px] h-auto">
                                <Select
                                    options={bodyTypesOptions}
                                    styles={customStyles}
                                    placeholder={t("bodyType")}
                                    onChange={((e) => {
                                        setFieldValue("startBodyForm" , e?.value)
                                    })}
                                />
                                <p className="!text-error text-sm">{errors?.startBodyForm && touched?.startBodyForm && t(errors?.startBodyForm)}</p>
                            </div>
                        </div>
                    </div>
                </div>
            </DialogContent>
        )
    }
    // setup the function that close the popup
    const handleClose = () => {
        dispatch(setAddPopUp(false));
    };
    // we dont mount the pop up if we dont need it
    if(!addPopUp) return <></>
    // we mount the popup if we needed it
    return (
        <Dialog
            fullScreen={fullScreen}
            open={addPopUp}
            TransitionComponent={Transition}
            keepMounted
            onClose={handleClose}
            fullWidth={true}
            maxWidth={'md'}
            PaperProps={{
                style: {
                    backgroundColor: theme.palette.background.paper,
                },
            }}
        >
            {
                // This is the title of the pop up
            }
            <DialogTitle sx={{ color: theme.palette.text.primary , display:'flex' , justifyContent: 'space-between' , flexDirection: 'row' , alignItems: 'center' }}>
                <h1 className="text-[25px] font-tajawal">{t('addNewMember')}</h1>
                <span onClick={() => handleClose()} className="fill-primary-dark dark:fill-primary cursor-pointer">
                    <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path d="M10.5851 8.99904L17.6675 1.92716C17.8792 1.71545 17.9981 1.42831 17.9981 1.12891C17.9981 0.829501 17.8792 0.54236 17.6675 0.330649C17.4558 0.118938 17.1687 0 16.8693 0C16.5699 0 16.2828 0.118938 16.0711 0.330649L9 7.41377L1.92888 0.330649C1.71719 0.118938 1.43008 2.65824e-07 1.1307 2.68055e-07C0.831331 2.70286e-07 0.54422 0.118938 0.332532 0.330649C0.120844 0.54236 0.0019188 0.829501 0.0019188 1.12891C0.0019188 1.42831 0.120844 1.71545 0.332532 1.92716L7.4149 8.99904L0.332532 16.0709C0.227164 16.1754 0.143531 16.2998 0.0864579 16.4368C0.0293845 16.5738 0 16.7208 0 16.8692C0 17.0176 0.0293845 17.1645 0.0864579 17.3016C0.143531 17.4386 0.227164 17.5629 0.332532 17.6674C0.43704 17.7728 0.561376 17.8565 0.698368 17.9135C0.83536 17.9706 0.982298 18 1.1307 18C1.27911 18 1.42605 17.9706 1.56304 17.9135C1.70003 17.8565 1.82437 17.7728 1.92888 17.6674L9 10.5843L16.0711 17.6674C16.1756 17.7728 16.3 17.8565 16.437 17.9135C16.574 17.9706 16.7209 18 16.8693 18C17.0177 18 17.1646 17.9706 17.3016 17.9135C17.4386 17.8565 17.563 17.7728 17.6675 17.6674C17.7728 17.5629 17.8565 17.4386 17.9135 17.3016C17.9706 17.1645 18 17.0176 18 16.8692C18 16.7208 17.9706 16.5738 17.9135 16.4368C17.8565 16.2998 17.7728 16.1754 17.6675 16.0709L10.5851 8.99904Z" fill="currentColor"/>
                    </svg>
                </span>
            </DialogTitle>
            {
                // This is the formik wizard component that contain multi papers each with specific inputs
            }
            <FormikWizard
                initialValues={initialFormValues}// values type is same as initialFormValues type
                onSubmit={async (values : any) => {
                    await dispatch(add(values))
                    handleClose();
                }}
                validateOnNext
                activeStepIndex={0}
                steps={[
                    {
                        component: FirstPaper,
                        // this is the paper validation schema ( can`t go to next paper or submit ( for last paper ) if the validation schema return a false result )
                        validationSchema: Yup.object().shape({
                            firstName: Yup.string().required('thisFieldIsRequired'),
                            lastName: Yup.string().required('thisFieldIsRequired'),
                            phone: Yup.string().required('thisFieldIsRequired'),
                            email: Yup.string().email('invalidEmailAddress').required('thisFieldIsRequired'),
                            address: Yup.string().required('thisFieldIsRequired'),
                        }),
                    },
                    {
                        component: SecondPaper,
                        // this is the paper validation schema ( can`t go to next paper or submit if last paper if the validation schema return a false result )
                        validationSchema: Yup.object().shape({
                            planDelay: Yup.number().typeError('mustBeANumber').required('thisFieldIsRequired'),
                            services: Yup.array().min(1 , "selectAtLeastOneService"),
                            startBodyForm: Yup.string().required('thisFieldIsRequired'),
                            startWeight: Yup.number().typeError('mustBeANumber').required('thisFieldIsRequired'),
                        }),
                    },
                ]}
                >
                {({
                    renderComponent,
                    handlePrev,
                    handleNext,
                    isNextDisabled,
                    isPrevDisabled,
                    isLastStep,
                    isSubmitting,
                    currentStepIndex
                }) => (
                    <>
                        <div>
                            {renderComponent()}
                        </div>
                        <DialogActions sx={{ padding: '16px 24px' }}>
                            {
                                isSubmitting?
                                <div className="w-full flex gap-3 justify-end items-start">
                                    <CircularProgress color="secondary" size={24} />
                                </div>
                                :
                                <div className="w-full flex gap-3 justify-end items-start">
                                    {currentStepIndex != 0 ? <button className="btn font-semibold" type="button" onClick={handlePrev} disabled={isPrevDisabled}>
                                        {t('back')}
                                    </button> : <></>}
                                    <button disabled={isNextDisabled} className="disabled:opacity-10 btn font-semibold" type="button" onClick={handleNext}>
                                        {isLastStep ? t('done') : t('next')}
                                    </button>
                                </div>
                            }
                        </DialogActions>
                    </>
                )}
            </FormikWizard>
        </Dialog>
    )
}